lsfreeing 2020-01-18
指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。
type *var-name;
type 是指针的基类型,它必须是一个有效的 C 数据类型,var-name 是指针变量的名称。用来声明指针的星号 * 与乘法中使用的星号是相同的。
赋为 NULL 值的指针被称为空指针,NULL 指针是一个定义在标准库中的值为零的常量。
它是一个指针,它指向一个数组。指向数组的指针,本质是指针。
int (*p)[3] 因为()优先级高,首先说明p是一个指针,指向一个int型的一维数组, 数组有3个元素,每个元素是一个int型整数
简单来说,就是int (*p)[3]是指一个指向数组的指针,它其实还是一个指针,只不过是指向数组而已
它是一个数组,数组的元素都是指针。存放指针的数组,本质是数组。
int *p[3] [ ] 优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,指针数组本身就是个数组,只不过这个数组里存放的不是int 不是char,而是一个指针类型( int*,char* ),也就是就是地址 。
C语言允许函数的返回值是一个指针(地址),我们将这样的函数称为指针函数。
用指针作为函数返回值时需要注意的一点是,函数运行结束后会销毁在它内部定义的所有局部数据,包括局部变量、局部数组和形式参数,函数返回的指针请尽量不要指向这些数据,C语言没有任何机制来保证这些数据会一直有效,它们在后续使用过程中可能会引发运行时错误。func() 运行结束后 n 的内存依然保持原样,值还是 100,如果使用及时也能够得到正确的数据,如果有其它函数被调用就会覆盖这块内存,得到的数据就( 不是原来的值 )失去了意义。
相关文章:C语言指针作为函数返回值
如果在程序中定义了一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,这段存储空间的首地址称为这个函数的地址。而且函数名表示的就是这个地址。既然是地址我们就可以定义一个指针变量来存放,这个指针变量就叫作函数指针变量,简称函数指针。
int Func(int x); /*声明一个函数*/ int (*p) (int x); /*定义一个函数指针*/ p = Func; /*将Func函数的首地址赋给指针变量p*/ c = (*p)(a, b); //通过函数指针调用Func函数
指针变量的“基类型”用来指定该指针变量可以指向的变量的类型,即该指针变量只能存放什么类型变量的地址。所以 int*p 表示 p 指向的是 int 型变量,里面只能存放 int 型变量的地址。虽然 p 是指针变量,但只要是变量就有地址,就可以定义一个指针变量存放它:
int **q = &p;
为什么存放 &p 要两个“*”呢?因为指针变量 p 的基类型为 int 型,所以 &p 的基类型为 int*型 。所以如果要定义一个能指向 int* 型变量的指针变量,有两个要求:首先它要是指针变量,即一个“*”;其次,该指针变量指向的是 int* 型的数据,或者说存放的是 int* 型变量的地址,所以就是 int**。
以上就是为什么需要两个“*”的原因。两个“*”表示二级指针,就是指针的指针。二级指针需要两个“*”才能指向最终的内存单元,即 **q==i。变量 q 中存放变量 *q 的地址,变量 *q 中存放变量 **q 的地址,变量 **q 中存放i的内容,即 10。或者说:q 指向 *q,*q 指向 **q,**q 中存放i的内容,即 10。
同样,虽然 q 存放的是指针变量 p 的地址,但它也有地址。所以也可以定义一个指针变量,里面存放 q 的地址:
int ***r = &q;
r 的基类型就是 int** 型。而 q 的基类型是 int* 型,所以 &q 的基类型是 int** 型。所以 r 有三个“*”才能指向 q 的地址。三个“*”表示三级指针,即指针的指针的指针。三级指针需要三个“*”才能指向最终的内存单元,即 ***r==i。
# include <stdio.h> int main(void) { int i = 10; int *p = &i; int **q = &p; int ***r = &q; printf("i = %d\n", ***r); return 0; } 输出结果是: i = 10