指针
一个十六进制整数 指针即内存地址
int *p=&x;
数据类型 * 指针类型
数据类型 变量 指针变量
指针变量存储的是内存地址 %p输出指针变量的值
指针变量可以进行取运算 printf("%d",p)
取值运算符 *(内存地址) 取内存地址中保存的数据
*指针变量 取指针变量保存的地址中保存的数据
&取地址运算符 *&相互抵消 *&x==x
栈内存从大往小存
堆内存从小往大存
一个地址保存一个字节(一个int 4个地址) 地址+1不是地址简单加了一个位置,实际上是加了类型大小的内存地址
地址本身虽然只是一个十六进制的整数,但其实地址自带类型
char c =‘a’; char *pc=&c;
数据类型 *是个整体 表示地址的类型
指针变量的标识符一般p开头
数据类型 * 标识符
指针变量的初始化:int px=NULL; null表示一个特殊的内存地址0,保存的是代码,代码区的地址都不可以进行取值操作,代码区的数据只读
int p 编程时避免野指针 NULL悬空指针,对于悬空指针不能进行取操作
一般对指针进行取操作前,都要对指针进行悬空判断 if(p!=NULL){}
指针变量的大小保持4个字节 64位系统8个字节 sizeof(指针)==4
int pa,pb; == int pa,pb; pa是int*类型,pb是int类型 int *pa,pb; pa和pb都是int类型
函数中不能返回局部变量的地址 因为局部变量在函数调用之后会被回收 静态局部变量不会被回收,可以返回 静态局部变量,全局变量,形参(指针)可以返回
void * 万能指针 可以保存任何类型的内存地址 不能进行取*操作
在函数中无法通过计算获得数组长度
数组名是数组中的首地址,也是数组中第一个元素的地址
在函数中数组名已经退化为一个指针 数组名不是左值 数组名是个只读变量 但是char *p=arr;p可以++
形参列表中 int arr[10]也不是数组,本质上是int arr 函数中可以 arr=&a;
int p=arr; printf(%d ,(p+i)); printf(%d ,p[i]); printf(%d ,i[arr]); []下标运算符 arr[i]==(arr+i) printf(%d ,*(arr+i));
p=arr printf(%d,*p); ++p; p++:先取p,再p++ (*p)++:*p的值++
为什么下标从0开始,因为第一个元素的偏移量为0
int x=10;
int *p=&x; 保存变量x的地址 p=&x;
int **pp=&p; 保存一级指针变量p的地址 pp=&p;
*pp是一级指针变量里储存的值
**pp是一级指针所指向内存里的值