指针初步学习
指针初步学习
1.指针是什么?
电脑内存这么大我们怎么管理?
于是我们创造了指针。
- 指针是内存最小单位的一个地址
 
假设以下一格为一个字节(Byte)
类比为房间,如何才能找到每个房间,于是就进行编号。
| 编号 | 内存单元 | 
|---|---|
| 1 | |
| 2 | |
| 3 | |
| … | … | 
这个编号为内存地址,即为指针。
假设我们要对int a取地址,int大小为4个字节,C语言就会取出第一个字节的地址。
如:
| 编号(本质为二进制但是用16进制展示) | 内存单元 | 
|---|---|
| 0x00dbfd98 | a | 
| 0x00dbfd99 | a | 
| 0x00dbfd9a | a | 
| 0x00dbfd9b | a | 
此处&a = 0x00dbfd98。
但是注意:我们在口头中所说指针一般为C语言的指针变量。
1  |  | 
在不同的机器上,指针长度不同,32位即32bit,能管理4GB的内存(二进制:11111111 11111111 11111111 11111111),所以在32位机器上一个指针变量大小为4字节。
2.指针和指针类型
1  |  | 
这些不同类型的指针变量在32位下都是4个字节,
那么为什么要区分这些不同类型的指针呢?
2.1指针类型的意义
举例1:
1  |  | 
此时a被修改为了0x11223300。
所以指针类型决定了指针在被解引用时访问几个字节,如果是char*在解引用是访问1个字节,导致了例子中的情况。
举例2:
1  |  | 
即根据指针变量类型的不同进行地址的操作。
那么int*与float*可以通用吗?
显然不可以,在解引用时对于内存的操作仍是不同的。
3.野指针
3.1什么是野指针?
定义:指针指向的位置是不可知的。
举例:
1  |  | 
此处p没有初始化,意味着没有明确的指向(即不初始化放的是随机值)这里的p就是野指针。
此外还有:
- 指针越界访问(如访问超出数组长度的地址)
 - 指针指向的空间释放(如函数返回一个指针后被销毁)
 
3.2如何避免野指针的出现。
- 对指针明确初始化(或初始化为
NULL,但此时无法解引用)。1
2
3
4
5
6//以下为一种安全的初始化方式:
int* p = NULL;
if (p3 != NULL)
{
*p3 = 100;
} - 避免越界
 - 避免局部变量的指针
 - 使用前检查指针的有效性
 
4.指针运算
4.1指针+-整数
举例:
1  |  | 
注意:此处*vp++拆分为*vp;和vp++;
4.2指针-指针
1  |  | 
指针减去指针得到的是指针之间元素的个数。但不是所有的指针都能相减,只有指向同一块空间的指针才能相减,才有意义。
4.2.1用法
举例:
1  |  | 
但是有没有指针+指针呢?
有,但是无意义。类比于生活中的日期加日期,无意义。
4.3指针的关系运算
- 其实就是比较大小
 
举例:
1  |  | 
以上代码可以通过编译,但是标准不规定其可行,因为N_VALUES-1访问了数组前的内存是不推荐的(但是可以访问数组后,即数组越界只允许往后越界)。
5.指针与数组
- 数组是一组相同类型元素的集合
 - 指针变量是一个变量,存放的是地址
 
1  |  | 
指针初步学习
      http://jiangno.com/2024/08/25/note/