#一级指针、二级指针、指针和数组、指针数组总结
##数组:C 语言中所有的数组都可以看成是一维数组,数组传参的时候会发生降维问题,任何数组传参都会降维成指针。
##指针:指针存放变量的地址,指向的值是变量的内容。
指针(一级指针、二级指针、多级指针):
一级指针用普通变量的地址去接,二级指针用一级指针的地址去接,N级指针用N-1级指针的地址去接。
我们在一个程序中已经使用了一级指针了,如果想修改这个一级指针或者这个一级指针指向的内容,就会使用到二级指针了,但是,为了代码的可读性,最好用二级以下的指针解决。
指针变量需要指向一个内存空间,内存空间相当于门牌号,而对一个指针解引用(*),相当于间接访问这个指针变量中存储的地址里面对应的内容。
//指针指向元素
int main()
{
char a = 'w';
char* p = &a; // P 是一级指针,它指向的是 a 的地址。P 里面存放的就是 a 地址的内容。
char** pp = &p;//pp是二级
printf("%c ",*p);
printf("%c ",**pp);
return 0;
}
输出的结果为:w w
//指针指向数组:
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int* p = arr; // 数组在函数中除了 strlen 与 & 这两种情况以外,都代表首元素的地址。
printf("%d\n", *p);
printf("%d\n", *(p + 1)); // 这里面 p +1 其实是 增加了 P 所指向数据类型大小字节的空间,p 开始是 1 的 地址, p +1: 因为 p 是int 型 指针,int 占 4个字节,所以要给 p 里面的地址加上 4,这样 p 的内容就变成给了 2 的地址;
这里输出结果是:
1
2
int arr[5] = { 0,1,2,3,4};
int* p[] = { arr, arr + 1, arr + 2 };
int** Q = p;
printf("%d ", **Q);
printf("%d ", **(Q + 1));
printf("%d ", **(Q + 2));
输出结果:
1 2 3
##指针数组:定义 int (*p)[n]
()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n。执行p+1时,p要跨过n个整型数据的长度。
将二维数组赋给一指针:
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]
所以数组指针也称指向一维数组的指针,亦称行指针。
##指针数组定义 int p[n];
**[]优先级高,先与p结合成为一个数组,再由int说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1时,则p指向下一个数组元素,p=a; 这里p表示指针数组第一个元*素的值,a的首地址的值。
如要将二维数组赋给一指针数组:
int *p[3];
int a[3][4];
p++; //该语句表示p数组指向下一个数组元素。注:此数组每一个元素都是一个指针
for(i=0;i<3;i++)
p[i]=a[i]
这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]赋值时需要分别赋值。
数组指针只是一个指针变量,它占有内存中一个指针的存储空间。
指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。