朝花夕拾 · C语言 | 指针篇
内存程序运行过程中可以访问到的内存存储空间计算机为了方便对内存的管理以字节为单位对内存进行了编号。地址计算机管理内存时给内存的编号指针指针即为地址地址即为指针指针指向了一个具体的空间指针变量变量保存地址的变量需要占用内存空间。一.指针基础1.指针变量的定义基类型 *变量名基类型该指针指向的空间存储的数据的数据类型:int、char、float 、double 、void、构造数据类型* : 类型说明符说明后面的变量是一个指针变量名遵循标识符的命名规则p开头pmax, ptmp.指针变量中保存的地址是该数据类型的首地址int *pint; char *pch; int *pi, *pj;sizeof (指针) 在64位计算机系统下指针在内存中占用8字节。在32位计算机系统下指针在内存中占用4字节。2.指针变量的初始化和赋值野指针初始化或赋值的一个指针或者指向一个已经释放的内存空间的指针。避免野指针1给指针初始化为空指针NULL2给指针初始化为已有变量的地址。int *p; // 野指针里面存了一个随机地址比如 0x0001 *p 10; // 试图往那个随机地址里写数据编译结果编译绝对不会报错。编译器只检查语法*p语法完全正确编译器认为p是int*解引用是合法的。运行结果不一定崩溃但绝对属于“未定义行为”。野指针可能指向以下三种区域结果完全不同1. Segmentation fault (core dumped)段错误访问的地址属于操作系统受保护的区域比如 0x0000 附近,好排查立竿见影的崩溃2.未分配但可读写的内存,写入成功不报错,但悄悄覆盖了其他变量的数据,极难排查出现随机 Bug3.只读区域如代码段崩溃Bus Error3.指针运算符* ----》指针运算符用来访问指针变量所指向的内存空间的数据*指针变量-----》指针降级为变量类型---》基类型的变量int *p; p; ----int* *p; ----int char * pch; pch - ---char注意1.* 指针运算符只能放在指针变量的前边。2.*指针变量访问指针变量指向的数据该表达式降级为变量类型---》基类型的变量3.*指针变量访问的字节数取决于定义该指针时的基类型。char*p; *p---char -访问1字节 int * p; * p---int ---访问4字节 double *p; *p--double ----访问8字节 取地址运算符获取某个变量的首地址。变量名1.只能给一个变量取地址不能给常量或者表达式取地址。2.给某个变量取地址时获取的是这个变量首字节的地址。4.指针的算术运算 * / % 对于指针运算无意义。- : 指针1- 指针2表示两个指针之间间隔的元素个数地址值之间的字节差/sizeof (基类型):指针1表示从当前地址向后偏移sizeof (基类型)字节--: 指针-1表示从当前地址向前偏移sizeof (基类型)字节char*p1; p1;----向后偏移1字节 int* p2; p1;--向后偏移4字节 printf(%p\n,p1);----%p打印地址 printf(%ld\n,p1-p2);----%ld打印两地址之差二.指针作为函数参数1.被调函数中想要修改主调函数中定义的变量传递该变量的地址2.被调函数中想要使用主调函数中定义的变量可以传递值也可以传递地址3.被调函数想要返回多个结果时可以传递主调函数定义的变量的地址地址指向的空间可以保存被调函数得到的结果。三.指针和一维整型数组数组的数组名为数组首元素地址注意1.数组名为地址常量(右值不能被赋值aa[0]a[0]----*aa[1]----*(a1)a[2]----*(a2)a[n]----*(an)int a[]{0}; int num0; anum; //× a; //× *a1 //√ 等价于a[0]1;一维整形数组作为函数参数传递void print_ array( int a[ ] , int len){ }void print_ array( int *pa, int len){ }a与pa用法相同