数组指针
在一个一维数组中,定义一个int buf {}; 定义一个指针 int *p = buf;
指针P存储int类型的buf的数据, p存储了buf的值,所以p与buf的值相等
- 声明时意义不同
- sizeof时,p与buf值不相同
- &取地址时,p与buf值不同
// 1. sizeof时 p 与 buf值不相同
printf("%ld \n", sizeof(buf));
printf("%ld \n", sizeof(p));
// 2. &取地址时 p 与 buf值不相同
printf("%p \n", &buf);
printf("%p \n", &p);
除了以上的情况, P完全等价于 buf
数组指针, 存储的是整个数组的地址
本身buf的类型为int[10] 指向其类型的指针 int (*)[10]
int (*p1)[10] = &buf;
printf("%d \n", (*p1)[2]);
printf("%d \n", p1[0][2]);
- []的优先级高于*
- int *p2[] 是一个数组,存储int型的地址
- int (*p1)[10] = &buf; 是一个指针,指向数组的地址
int (*p1)[10] = &buf;
二维数组和指针之间的转换
- 定义了一个二维数组int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int (*p)[4] = arr;
int (*p1)[3][4] = &arr;
printf("%d \n", p[1][2]);
printf("%d \n", *(*(*p1 + 1) + 2));
printf("%d \n", (*p1)[1][2]);
printf("%d \n", p1[0][1][2]);
// q是一个数组长度为4,里面的元素类型int *
int a = 12;
int *q[4] = {&a};
// int *q1[3][4] q1是个数组长度为3,
// 子元素类型int *[4] 这个类型是数组类型,数组子元素类型 int *
int *q1[3][4] = {{&a}, {&a, &a, &a, &a}, {&a}};
// int (*q2[3])[4] 数组子元素类型 int (*)[4] 指针指向长度为4 int型数组
int (*q2[3])[4];
*/
// int arr[3];
// int *p = arr;
// char arr[3];
// char *p = arr;
char *arr[3] = {"hello", "world", "aaa"};
char **p = arr;
printf("%s \n", arr[0]);
printf("%c \n", arr[0][1]);
printf("%s \n", arr[1]);
printf("%s \n", p[0]);
printf("%c \n", p[0][1]);
printf("%s \n", p[1]);
- 在定义语句中,判断这个变量是数组还是指针通过运算符的优先级判断:
- () > [ ] > *
- 如果变量首先粘住的是[ ]
- 那么这个变量一定是一个数组
- 如果变量首先粘着的是*
- 那么这个变量一定是一个指针
- 判断一个指针变量的类型,变量名遇到*号的时候,记住,一定要停下来,剩余的东西都是用来修饰这个指针所指向的内容是怎么样的
- 比如:char *(*p)[3] = &buf; // p 指向 char * [3] 指针数组 //p ---指针数组指针
- 比如:char (**p)[3]; // p 指向 char (*) [3] 数组指针 //p ---数组指针指针
- 比如:char **p[3]; // p 数组 char ** 二级指针// p ---二级指针数组
野指针
- 指针只声明没有初始化
- 其值是一个随机数
- int *p; *p = 5;
- 此时p是野指针
- 其值是一个随机数
- 指针所指向的内存被系统回收但仍然进行访问
- 指针越界
- 野指针的危害
- 访问非法内存,会导致段错误
- 可能破坏系统的关键数据,导致系统崩溃等严重错误
- 如何防止野指针的产生
- 指针定义时及时初始化
- 在初始化之前,p都是野指针
- 绝不引用已被会回收的内存
- 确认所申请的内存边界
- 指针定义时及时初始化
空指针
很多情况下,我们不可避免地会遇到野指针,比如刚定义的指针无法立即为其分配一块恰当的内存,又或者指针所指向的内存被释放了等等。一般的做法就是将这些危险的野指针指向一块确定的内存,比如零地址内存(通用类型地址)。
空指针保存了零地址的指针,指向零地址,在LInux中,从0x0000 0000 一直到0x0804 8000 之间,内存被成为不可访问内存,如果程序访问了这段内存,计算机程序会报错(段错误Segmentation fault)
``

这段内存不可访问
通用类型地址(void *)
可以接受任何类型的地址,也可也传递任何类型的地址
不能直接解引用,必须先进行类型转换
只有void *p 没有void a
二级指针
存储其他指针地址的指针就是二级指针
int a = 77;
int *p = &a;
int **q = &p;
- 在上述代码中
- **q == *p == 77 == a 解引用p就是a的值
- q == &p q存储的值是p的地址
- *q == p == &a 解引用q就是通过p的地址取p的值,拿到a的地址(p的值就是a的地址)
Comments NOTHING