? 指针是一种特殊的数据类型,使用指针可以定义指针变量,指针变量中存储的是整形数据,代表了内存的编号,可以这个编号来访问对应的内存。
? 1、函数之间是相互独立的,但是有时候需要共享变量
? 传参是单向值传递
? 全局变量命名容易冲突
? 使用数组还需要传递长度
? 虽然命名空间相互独立,但是地址空间是同一个,所以指针可以解决共享变量的问题
? 2、由于函数之间传参是值传递(内存拷贝),对于字节数较多的变量,值传递的效率较低,如果传递变量的地址只需要传递4|8个字节
? 3、堆内存无法取名字,它不能像data/bss/stack让变量名与内存之间建立联系,只能使用指针来记录堆内存的地址,以此来使用堆内存
? 定义:
? 类型* 变量名_p;
? 1、指针变量与普通变量的用法区别很大,建议在取名时以p结尾加以区分
? 2、指针变量的类型表示了存储的是什么类型的变量的地址,它决定了通过这个指针变量可以访问的字节数
? 3、一个只能定义一个指针变量
? int p1,p2,p3; // 只有p1是指针变量,p2 p3都是int类型变量
? int p1,p2,p3;// p1 p2 p3都是指针变量
? 4、指针变量与普通变量一样默认值是随机的,一般初始化为NULL
? 赋值:
? 变量名_p = 地址; // 必须是有权限的而且有意义的内存地址
? 指向栈内存:
? int num;
? int p = #
? 指向堆内存:
? int* p = malloc(4);
? 解引用:
? *p;
? *p <==> num
? 通过指针变量中记录的内存编号去访问内存,这叫做解引用。
? 该过程可能产生段错误,原因是指针变量中存储的是非法的内存编号
? 注意:访问的字节数是由指针变量的类型决定的
?
作业:
1、实现一个变量交换的函数,调用它对一个数组进行排序
void swap(int* p1,int* p2)
2、实现一个函数计算两个整数的最大公约数和最小公倍数,return来返回最大公约数,最小公倍数用指针处理
3 6 3
3 6 6
? 空指针:值为NULL的指针变量叫做空指针,对空指针进行解引用一定会产生段错误
? NULL也是一种错误标志,如果一个函数的返回值是指针类型时,当函数执行出错时可以返回NULL作为错误标志
? NULL作为指针变量的初始值 if(NULL == p)
? 如何避免空指针带来的段错误:
? 对于来历不明的指针使用前,一定要进行判断
? 1、调用函数返回值为指针类型时,可能是空指针
? 2、当函数的参数是指针类型时,调用者传递过来的可能是空指针
? 注意:NULL在绝大多数系统中是0,极个别系统中是1,if(!p)
?
野指针:指向不确定的内存的指针
对野指针解引用的后果:
1、段错误
2、脏数据
3、一切正常
野指针比空指针的危害性要更严重,因为它是无法判断出来的,错误可能是隐藏型的,短时间内可能不会暴露
所有的野指针都是人为制造的,如何避免产生野指针:
1、定义指针时一定要初始化 int* p = NULL;
2、函数不返回局部变量的地址
3、指针变量指向的内存被释放后,指针变量要及时置空 =NULL
? 指针变量中存储的是整数,理论上整数支持的所有运算指针变量都支持,但是绝大多数的运算是无意义
? 指针 + n:指针+指针类型字节数n 前进了n个元素
? 指针 - n:指针-指针类型字节数n 后退了n个元素
? 指针 - 指针:(指针-指针)/指针类型字节数 计算出两个指针之间间隔了多少个元素
const与指针:
当我们为了提高传参效率而使用指针时,传参的效率提高了,但是变量也有被修改的风险,这种情况可以使用const来进行保护
const int* p; 保护指针所指向的内存不被修改
int const* p; 同上
int* const p; 保护指针的指向不能修改
const int* const p; 保护指针指向的内存和指向都不能修改
int const* const p; 同上
数组指针与指针数组:
指针数组:
是由指针变量组成的数组,它的成员都是指针变量
类型* arr[长度]
数组指针:
专门用于指向数组的指针
类型 (*arrp)[长度];
数组名与指针:
数组名其实是一种特殊的指针,但它是常量,不能修改它的值,它与内存之间是映射关系,不能改变,而指针与内存之间是指向关系,可以改变
数组名是没有存储空间,而指针变量是有存储空间
指向数组的指针,可以当做数组名使用
数组名也可以当做指针使用
数组名[i] == *(数组名+i)
*(指针名+i) == 指针名[i]
注意:当数组作为参数传递时变成了指针,所以长度丢失了
? 二级指针就是指向指针的指针,里面存储的是指针变量的地址。
? 定义:
? 类型** 变量名_pp;
? 赋值:
? 变量名_pp = &指针变量;
? 解引用:
? *变量名_pp <=> 指针
? **变量名_pp <=> *指针
?
函数指针:
? 函数名就是地址(整数),它代表了函数在代码段中的位置
函数指针就是指向函数的指针,里面存储的是函数在代码段中的位置
134513520
原文:https://www.cnblogs.com/deric06/p/14849473.html