指针初步学习
指针初步学习
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/