C小白Jeff头秃的第七天:听说指针是C中最难的哦!

什么是指针:

一种数据类型,使用它可以定义指针变量,指针变量中存储的是整数,代表内存的编号 。
为什么要使用指针:
1、函数之间是相互独立的,但有些时候 要共享变量
传参是值传递
全局变量容易命名冲突
使用数据需要传递长度
命令空间是独立的,但地址空间就一个,指针可以解决这些问题。
2、由于函数之间的传参是值传递(内存拷贝),对于字节数比较多的变量这种效率比较低。如果传递变量的地址只需要传递4/8字节。
3、堆内存无法取名字,不能向data、bss、stack一样用让变量名与内存建立联系,只能使用指针计量堆内存的地址来使用堆内存。
如何使用指针:
定义: 类型变量名_p;
1、指针变量与普通变量的用法有很大区别,建议取名时以p结尾
2、指针变量与普通变量一样默认是随机的,一般初始化为NULL
3、指针的类型决定了它可以访问多少字节数。
4、一个
号只能定义一个指针变量。
Int *p1,*p2,p3 三个都为指针
Int p1,p2,p3 只有p1为指针,p2,p3为int类型
赋值:变量名_p=地址;
指向栈内存:
Int
p=#
指向堆内存:
Int
p=malloc(4);
解引用:*p
通过指针中记录的内存编号访问编译内存,该过程肯产生段错误,原因是里面存储的地址是非法的。
注意:访问的字节数由指针变量的类型决定
使用指针要注意的问题:

空指针:值为NULL的指针变量叫空指针,如果进行解引会产生段错误。无法访问。

NULL也是一种错误标志,如果一个函数返回值是指针类型,当函数执行出错返回值就是NULL。
如何避免空指针带来的段错误:使用来历不明的指针前做一判断。
1、当函数的参数是指针,别人传给你的就有可能是空指针。
2、从函数获取的返回值也可能是空指针。
if(NULL==p)来判断空指针。
NULL在绝大多数系统中是0,在个别系统中是1,

野指针:指向不确定的内存空间。

 解引用野指针的后果:

1、段错误
2、脏数据
3、一切错误
野指针比空指针的危害更严重,因为它无法判断出来,而且可能是隐藏型错误,短期内可能不暴露出来。
所以的野指针都是程序员自己制造出来的。如何避免野指针。
1、定义指针变量时一定初始化
2、函数不返回栈内存地址。
3、指针指向的内存被销毁后,指针变量要及时置空。

指针的运算:

指针变量中存储的是整数理论上整型数据可以使用的运算符都可以用,但大多数运算都是无意义的。
指针+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;同上。

指针数组与数组指针:

指针数组:由指针组成的数组,它的成员是指针变量。
Int* arr【n】;
数组指针:专门指向数组的指针。
Int (*arr)【n】

指针与数组(数组可以当指针使用,指针也可以当数组使用):

数组是一个特殊的指针,它是常量,不能修改它的值,他与它代表的内存是映射关系,二指针与内存是映射关系。
数组名 == &数组名
指针变量有自己的存储空间,如果他存储的是数组首地址,指针可以当数组使用,数组名也可以当指针使用。
数组名【i】== (数组名+1)
数组作为函数的参数时蜕变成了指针。所以长度丢失
Int arr【】 《=》 int
arr;(数组名可以解引用,指针也可以使用中括号)
Int* arr
二级指针:
就是指向指针的指针,存储的是指针变量的地址。
定义:类型** 变量名_pp;
赋值:变量名_pp=&指针;
解引用:
*变量名_pp 《=》 指针

函数指针:

函数名就是一个地址,它代表函数在代码段中内存的首地址
调用函数其实就是跳转到函数所在代码段执行二进制指令。
函数指针可以当函数使用。
函数指针就是指向函数的指针,他里面存储是函数在代码段中所处的位置(函数名);
返回值 (*函数名)(参数类型1 参数名1,…);
函数指针

使用了回调模式的库函数:

// 快速排序
void qsort(void *base, size_t nmemb, size_t size,
              int(*compar)(const void *, const void *));

// 二分查找
void *bsearch(const void *key, const void *base,
                 size_t nmemb, size_t size,
                 int (*compar)(const void *, const void *));

你可能感兴趣的:(c学习日记,初学者,小白)