*间接运算符和&取址运算符

变量a本质上代表一个存储单元;CPU通过该存储单元的地址访问该存储单元中的数据。所以a本来代表两个值:存储单元的地址和储单元中的数据。即:

  • a表示a对应的存储单元中的数据
  • &a表示a对应的存储单元的地址
  • *a表示另一个存储单元中的数据

声明

int a a中存储的是一个整数数值,通过a可以访问这个数值

int *a a中存储的是一个存储单元的地址,而该存储单元中存储的数据是一个整数数值;通过*a可以访问这个数值。

int** a a中存储的是一个存储单元的地址;而该存储单元中存储的数据是另外一个存储单元的地址,这个存储单元中存储的是整数数值。

在C语言里地址叫指针。还有,数组本质上其实也是指针,即:*a 等同于 a[]。

示例

int a = 10;
int *b = &a;		//指针b指向a的地址

printf("%d\n", a );		//a的数据值
printf("%d\n", &a);		//a的地址值
printf("%d\n", b );		//指针b的值,即指针b指向的a的地址值
printf("%d\n", *b);		//指针b指向的a的数据值

结果为:
10
6487620
6487620
10

参考:C语言中的*和&符号


二维数组和指针

二维数组的各种申明方式

表示形式 含义
int a[5] [5]; int类型二维数组
int ** a; 指向指针的指针,可用于二维数组
int * a[5]; 指针数组
int (*a) [5]; 指向一个具有5个元素的数组的指针
int * a[5] [5]; 存放指针的二维数组
int (* a[3]) [4]; 一个3元素数组,每个元素为指向具有4个元素的数组的指针

二维数组的其他表现形式

表示形式 含义 地址
a 二维数组名,指向一维数组a[0],即0行首地址 2000
a+1, &a[1] 指向一维数组a[1],即1行首地址 2016
a[0], *(a+0), *a 0行0列元素,a[0] [0]地址 2000
a[1], *(a+1) 1行0列元素,a[1] [0]地址 2016
a[1]+2, *(a+1)+2, &a[1] [2] 1行2列元素,a[1] [2]地址 2024
* (a[1]+2), * (*(a+1)+2), a[1] [2] 1行2列元素,a[1] [2]的值 元素值,13

示例

数组int a[3] [4] 中的a[2] [1] 用其他形式表示

仔细使用上面的解析方式

把二维数组拆解成一维数组

通过上面的图,可以很直观的得出三种a[2] [1] 的其他表达形式

*(*(a+2)+1);

*(a[2]+1);

int *p = &a[0] [0];
p[9];	//p的第10个元素

参考:C语言二维数组指针(指向二维数组的指针)