一维数组和一级指针变量
- 数组名是一个地址,可以使用一个一级指针变量接收其地址;
int arr[5];
int p = arr;
- 两者不同的是数组名是一个常量,不能被赋值,也就是数组名不能单独出现在赋值号的左边;
int arr[5], b[10], c;
arr = b;
arr = &c
- 数组和指针的越界访问编译器都不会报错;
int arr[5];
int *p = arr;
printf("*(p - 1) = %d\n", *(p - 1));
printf("a[-1] = %d\n", arr[-1]);
- 在使用指针时,一定不要使用野指针,使用野指针时将会产生不可预知的错误;在不使用的时候可以将其指向NULL,而NULL时不允许用户使用的,当我们访问NULL时,将会产生段错误,段错误比不可预知的错误好的多,至少你知道有错了;
int *p;
printf("*p = %d",*p);
int *p = NULL;
printf("*p = %d", *p);
- 指针可以使用指针名[index]访问,数组也可通过*(数组名 + index)访问。
int arr[5] = {0, 1, 2, 3, 4};
int *p = arr;
printf("arr[1] = %d\n", arr[1]);
printf("*(arr + 1) = %d\n", *(arr + 1));
printf("*(p + 1) = %d\n", *(p + 1));
printf("p[1] = %d\n", p[1]);
二维数组和二级指针
- 二维数组的数组名二维数组名不是二级指针,而是一个数组指针;使用普通的一级指针保存二维数组的首地址,即便能保存也没法按行操作;
int arr[10][10];
int *p = arr;
- 二级指针指向一级指针的指针,二级指针指向一个指针数组是合法的,其值就是指针数组第一个元素的地址,用二级指针指向指针数组是合法的,但是直接使用二级指针指向二维数组就会报错。
int arr[10][10];
int **p = arr;
int **q = &arr[0];
int **k = &arr;
一级指针和二级指针
- 二级指针是一级指针的升维,可以通过二级指针修改一级指针的值;
- 可以通过一级指针修改普通变量的值;
int a = 10;
int b = 20;
int *p = &a;
int **q = &p;
*p = 30;
*q = &b;
**q = 40;
- 在函数传参时,将一维指针当作实参直接传递给函数,实际上传递的是指针所指向的地址,可以修改指针指向的空间的内容;在改变形参的指向不会影响实参的指向;
void func(int *p){
*p = 20;
p = NULL;
}
int a = 10;
int *p = &a;
func(p);
printf("a = %d\n", a);
printf("*p = %d\n", *p);
- 想要在函数中修改一级指针的指向,那么就需要通过二级指针来操作;
void func(int **q){
**q = 20;
*q = NULL;
}
int a = 10;
int *p = &a;
func(&p);
printf("a = %d\n", a);
printf("*p = %d\n", *p);
指针数组和数组指针
- 指针数组的本质是数组,只不过数组中每个元素都是一个指针,定义一个指针数组
int *p[10];
- 数组指针的本质是一个指针,其指向具有相同列元素的数组
int (*p)[10];
指针数组、数组指针、二级指针、二维数组
- 对于一个二维数组,其数组名相当于一个行指针,可以使用一个数组指针指向它,并通过数组指针来操作二维数组;
int arr[3][4] = {1,2,3,4,\
5,6,7,8,\
9,10,11,12};
int (*p)[4] = NULL;
p = arr;
- 指针数组中的每个元素可以指向二维数组中的对应行,这样就可以通过操作指针数组来操作二维数组,一般多用于函数传参传二维组时使用;
void print_array(int (*p)[4], int line, int col){
for(int i = 0; i < line; i++){
for(j = 0; j < col; j++){
printf("%d ", p[i][j]);
}
printf("\n");
}
}
int arr[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
print_array(arr, 3, 4);
- 使用二维数组存储不定长度的字符串时会照成空间的浪费,特别是字符串长度差异较大时;使用指针数组处理这种问题特别合适,数组中的每个元素可以指向一个字符串,这样就提升了空间的利用率;
char name1[3][64] = {"zhangsan",
"fulajimier.fulajimiluoweiqi.pujing",
"wangwu"};
char *name2[3] = {NULL, NULL, NULL};
name2[0] = "zhangsan";
name2[1] = "fulajimier.fulajimiluoweiqi.pujing";
name2[2] = "wangwu";
- 当指针的类型相同时,+1移动的大小也相同时,我们可以认为二级指针和二维数组时等价的。