指针的含义、表示、规范、存储、运用
# 指针的含义
表示某个变量或数据所在的内存地址 注意是内存地址 不是内存地址上的数据
# 指针的表示
一般用指针运算符&和 *表示 其中符号&表示取地址运算符 符号*表示取地址上数据运算符 例如:&value 表示取变量value在内存中分配的地址 *value 表示取变量value在内存中所分配地址上的数据
# 指针的规范
## 先声明再定义
int *p;//这里是声明一个整数型指针变量p 注意int *p虽然是连着一起写 实则是int* p 其中p是变量名 int*是数据类型 且是整数型指针数据类型 p = &a;//这里是定义一个整数型指针变量p 而指针就是表示某个变量或数据的内存地址 进一步可知&a就是取变量a在内存中分配的地址赋给整数型指针变量p printf("p = %d\n",p);//打印出整数型指针变量p等于地址6000001
## 声明和定义一起表示
int *p = &a;//取变量a在内存中分配的地址赋给整数型指针变量p printf("p = %d\n",p);//打印出整数型指针变量p等于地址6000001
## 错误表示
int a = 2;//把十进制数2赋给整数变量a int *p = a;//这里是错误的表达方式 不能把一个具体的数据赋给指针
# 指针的存储
## 理解一个变量的存储过程和原理
int a = 5; printf("a = %d",a);
解释以上:在栈中定义了一个变量a,并且在内存中开辟了一个int类型大小的空间, 即4个字节空间 ,然后让变量a指向这片空间,在变量a所在那片空间,里面存放数值5 ,把数值5转换成二进制数,存到变量a的4个字节空间,如下图所示:
## 理解一个指针的存储过程和原理
int a = 5; int *p;//这里是声明一个整数型指针变量p 注意int *p虽然是连着一起写 实则是int* p 其中p是变量名 int*是数据类型 且是整数型指针数据类型 p = &a;//这里是定义一个整数型指针变量p 而指针就是表示某个变量或数据的内存地址 进一步可知&a就是取变量a在内存中分配的地址赋给整数型指针变量p printf("p = %d\n",p);//打印出整数型指针变量p等于地址6000001
解释以上:在栈中定义了一个变量a,并且在内存中开辟了一个int类型大小的空间, 即4个字节空间 ,然后让变量a指向这片空间,在变量a所在那片空间,里面存放数值5 ,把数值5转换成二进制数,存到变量a的4个字节空间,另外在栈中再定义一个指针变量p,且在内存中开辟了一个int*类型大小的空间,即4个字节空间 ,最后从变量a的内存空间取出变量a所在内存地址,存放到指针变量p开辟的内存地址上,如下图所示:
## 理解二级指针的存储过程和原理
int a = 5; int *p;//这里是声明一个整数型指针变量p 注意int *p虽然是连着一起写 实则是int* p 其中p是变量名 int*是数据类型 且是整数型指针数据类型 p = &a;//这里是定义一个整数型指针变量p 而指针就是表示某个变量或数据的内存地址 进一步可知&a就是取变量a在内存中分配的地址赋给整数型指针变量p int **q;// q = &p;// printf("q = %d\n",q);//打印出整数型指针变量q等于指针变量p的内存地址7000001
解释以上:先对数据类型和变量划分开,int **q的变量名为q,数据类型为int **,int *中存放的是int类型数据的地址,而int **中存放的是int类型数据的地址的地址,上述我们明白了,一个*是指一个int数值的地址,则指针变量p中存放的是int数值的地址,即p = 6000001,为变量a的地址。那么我们可以推到,指针变量q就是存放指针变量p的地址。指针变量p存放变量a的地址,而指针变量p本身也是一个变量,它的值为变量a的地址 ,而内存也给指针变量p开辟了一片空间,让指针变量p存放它的数值,指针变量q存放指针变量p的地址,指针变量q也是一个变量。
# 指针的运用
## 指针与数组
解释以上:由以上输出结果可知,数组名arr是一个指针,存放的是内存地址,是数组名arr中第0个元素的所在内存地址,不是变量,不可以进行数值运算,并且arr = &arr = &arr[0]都是存放同一内存地址。
解释以上:由以上输出结果可知,int *pa实际上是int* pa,表示声明一个整数型指针变量pa,而int*pa = &arr[0]表示取出数组名arr所在内存地址赋给指针变量pa,从而可通过指针变量pa操作数组下标号(即0、1、2......)来间接取到数组arr中的元素或数值。
解释以上:由以上输出结果可知,数组名arr是不能进行数值运算的。
解释以上:由以上输出结果可知,虽然数组名arr不能进行数值运算,但可通过把数组名arr所在内存地址赋给指针变量pa,让指针变量pa进行数值运算来取值。
## 数组指针
### 表示
例如:int (*pa)[]或int (*pa)[3]
### 定义
变量pa是指针,指向数组,数组内的每个元素都是整型数据。
解释以上:由以上输出结果可知,int *pa实际上是int* pa,表示声明一个整数型指针变量pa,而int*pa = &a表示取出变量a所在内存地址赋给指针变量pa,*p = 20表示指针变量pa的内存地址上存放变量a所在内存地址上的数据是20,int (*parr)[] = &arr表示取出数组名arr所在内存地址赋给数组指针变量pa,从而可通过数组指针变量pa操作数组下标号(即0、1、2......)来间接取到数组arr中的元素或数值。
## 指针数组
### 表示
例如:int* arr[]或int* arr[3]
### 定义
变量arr是数组,数组内的每个元素都是指针。
解释以上:由以上输出结果可知,通过指针数组变量arr操作指针数组下标号(即0、1、2......)来间接取到指针数组arr中每个元素所在内存地址上对应的数据。
解释以上:由以上输出结果可知,int* (*parr)[] = &arr表示取出数组名arr所在内存地址赋给指针数组变量parr,从而可通过指针数组变量parr操作数组下标号(即0、1、2......)来间接取到数组arr中的元素或数值。
## 指针函数
### 表示
例如:int* func() { int a = 10 ; int*pa = &a ; return a ; }
### 定义
函数返回值是指针的函数。
解释以上:由以上输出结果可知,在int* func() { int a = 10 ; int* pa = &a ; return a ; }中,int* func()表示函数返回值是整型指针的函数,而int*pa = func()表示返回值是整型指针的函数通过指针变量pa把变量a所在内存地址返回赋给指针变量pa,再经过指针变量pa用指针取值符 *,即 *pa取出变量a所在内存地址上的数值。
## 函数指针
### 表示
例如:int ( *pa)(int)
### 定义
函数名是指针变量
解释以上:由以上输出结果可知,在int (* pa)(int) = NULL 中,(* pa)表示函数名是指针变量,即函数指针,而pa = func表示把func函数所在内存地址赋给指针变量pa,从而可通过指针变量pa利用func函数所在内存地址来间接操作func函数。