首页 > 其他 > 详细

c.5.30

时间:2021-06-04 17:48:09      阅读:19      评论:0      收藏:0      [点我收藏+]

什么是指针:

? 指针是一种特殊的数据类型,使用指针可以定义指针变量,指针变量中存储的是整形数据,代表了内存的编号,可以这个编号来访问对应的内存。

为什么要使用指针:

? 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

c.5.30

原文:https://www.cnblogs.com/deric06/p/14849473.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!