PS:本文假设你对指针已有一定的了解,能熟练运用最简单的指针。
概念
首先解释一下两个概念
- 指针的类型
- 指针指向的类型
指针的类型
1
2
3
4
5(1)int *p; 定义一个类型为 int* 的变量p 指针的类型是int*
(2)char *p; 定义一个类型为 char* 的变量p 指针的类型是char*
(3)int **p; 定义一个类型为 int** 的变量p 指针的类型是int**
(4)int (*p)[3]; 定义一个类型为 int (*)[3] 的变量p 指针的类型是int(*)[3]
(5)int *(*p)[3]; 定义一个类型为 int *(*)[3] 的变量p 指针的类型是int*(*)[3]
很明显,把变量名去掉就可以得到指针的类型。
指针指向的类型
1 | (1)int *p; 定义一个类型为 int* 的变量p 指针指向的类型是int |
很明显,将 *p 去掉就可以得到指针指向的类型。
这个语句的意思就是,先读取指针变量中的地址,再读取该地址对应的值。
如何获得指针变量中地址对应的值
1 | 最简单的一个例子 |
很明显,通过 * 指针变量 就可以获得指针变量中地址对应的值1
2
3
4
5
6再来一个一维数组的
int a[3];
int *p = &a[0]; or int *p = a; //a储存的就是a[0]的地址,且不可更改
p[0] = 0; p[1] = 1; //对数组赋值,等价于a[0] = 0; a[1] = 1;
*p = 0; *(p+1) =1; //对数组赋值,等价于a[0] = 0; a[1] = 1;
printf("%d%d%d%d",p[0],p[1],*p,*(p+1)); //依次输出a[0]a[1],a[0],a[1]
这里要重点掌握 int *p = a; *(p+1) =1;
这里 p+1 并不是代表地址数加一,它与指针的类型有关系
C标准并没有具体给出规定哪个基本类型应该是多少个字节数,而且这个也与OS、编译器有关。下面给出在32位环境下的图。
这里可以这样理解,对于不同的指针类型,虽然每次都走一步,但是他们一步所对应的长度是不同的。
所以指针一定要分类型,不同类型的指针,p+1的含义是不一样的。
1 | 再来一个二维数组 |
二维数组在概念上是二维的,有行和列,但在内存中所有的数组元素都是连续排列的。
1 | 最后最后 |
1 | 结构体 |
1 | 指向函数的指针 |