C和指针(九)链表和指向指针的指针

链表
1,链表是包含数据的独立数据结构的集合,链表中每个节点通过指针连接在一起,通常节点是动态分配的。
1)单链表中每个节点包含一个指向下一节点的指针,链表最后一个节点的指针为NULL。
2)链表中的节点可能分布于内存的各个地方,并不一定物理相邻。
3)单链表可以从链表头节点遍历链表至尾节点,无法从相反方向遍历。
4)双链表包含指向前一个节点的指针和指向后一个节点的指针,可以双向遍历链表。
5)双链表头节点两个指针一个指向链表第一个节点,一个指向最后一个节点,如果链表为空,两指针都为NULL。

2,单链表是一种使用指针存储值的数据结构,链表中每个节点包含一个字段,用于指向链表下一个节点,另外有一个独立的指针指向链表的第一个节点,节点在创建时采用动态分配内存的方式,节点不一定物理相邻,遍历链表是根据指针进行的,单链表只能以一个方向遍历。
3,双链表包含两个link字段,一个指向链表下一个节点,另一个指向链表前一个节点,可以双向遍历。

函数指针
1,声明数组时必须指定数组长度,如果数组链接属性是external或者作为函数的参数,声明时可以不注明长度。
2,函数指针使用前需要初始化,初始化表达式中的&操作符可以省略,编绎器隐式将函数名转换为函数指针,&操作符显式要求编绎器执行类型转换。

3,回调函数,把函数指针作为参数传递给其他函数,后者回调这个函数。
1)许多窗口系统使用回调函数连接多个动作。
2)如果在上下文环境无法确定回调函数的准确类型,可将参数类型声明为void*,在回调函数中再强制转换参数为正确类型。

4,转移表是一个函数指针数组,声明并初始化一个函数指针数组时,初始化列表中函数名的顺序即是数组下标的顺序,从数组中选择正确的函数指针,函数调用操作符将执行函数体。

5,函数指针数组下标越界,程序可能在三个地方终止:
1)首先下标越界的内存可能在分配给该程序的内存之外,操作系统检测到这个错误并终止程序,如果程序终止,错误报告在下标越界位置,但有些操作系统不会终止程序;
2)程序未终止,非法下标内存的值被提取,该值可能不是有效地址,此时程序终止,错误报告的地址随机,问题调试难度较大;
3)如果值是程序中有效的地址,机器将执行根据非法下标获得的虚拟地址的指令,如果获取的这个随机地址位于一块存储数据的内存中,程序因非法指令或非法操作数地址终止;4)数值也可能代表有效的指令,程序执行该随机地址的指令,如果该随机地址恰好位于一个函数的内部,执行该函数可能修改一些数据,导致未知的行为,函数的返回地址也是另一个随机值,计算机将在各个随机地址间跳转,指令破坏了调用路径,问题调试难度更大。
5)一开始就应该保证转移表的下标在合法范围内。

命令行参数
1,命令行参数是指向指针的指针另一个用武之地,在一些系统中用户在命令行中编写参数启动程序,参数传递给程序。

2,C的main函数有两个形参,第一个argc表命令行参数数目,第二个argv指向一组参数值,每个元素指向一个参数文本的指针。
1)如果程序需要访问命令行参数,main函数在声明时需要加上这些参数。
2)argv的指针数组,每个元素都是一个字符指针,数组末尾是一个NULL指针,argv声明为指向字符的指针的指针。
3)部分操作系统向main函数传递第三个参数,指向环境变量列表以及值的指针,参照操作系统和编绎器。

3,argv第一个参数通常是程序的名称,程序显然知道自己的名字,这个参数通常是忽略的。
1)但如果程序采用几组不同的选项启动,这个参数不可忽略,例UNIX系统中用于列出一个目录下所有文件的程序,以名字ls启动将产生一个文件的简单列表,以名字l启动,将产生一个多列的简单列表,如果以名字ll启动,将产生一个文件的详细列表,程序对第一个参数进行检查,确定由哪个名字启动,根据名字选择启动选项。
2)命令行参数程序名后面可能有零个或多个选项,后面跟随零个或多个文件名,选项名以-开始,main程序处理参数。

字符串常量
1,字符串常量出现在表达式中,它的值是一个指针常量,编绎器将这些指定字符的一份拷贝存储在内存的某个位置,并存储一个指向第一个字符的指针。
1)当数组名用于表达式中,它的值也是指针常量。

2,可以对指针常量进行下标引用、间接访问以及指针运算,这些操作符作用于字符串常量则相当于对指针常量的操作。
1)字符串常量+下标引用、间接访问、指针运算的表达式是合法的。

总结
1,如果声明得当,一个指针变量可以指向另一个指针变量。
1)指向指针的指针使用前需要初始化。
2)对指针变量执行双重间接访问获得目标对象,当然更多层的间接访问也是允许的。

2,还可以创建指向函数和数组的指针,以及创建指针的数组。
1)使用函数指针实现回调函数,指向回调函数的指针作为参数传递给另一个函数,后者使用这个指针调用回调函数,使用这种技巧可以创建通用型函数,回调函数执行特例工作。
2)转移表使用函数指针数组,函数必须具有相同的原型,通过下标选择指针,再通过指针调用对应函数,确保下标值不越界。

3,如果某个执行环境实现了命令行参数,参数通过两个形参传递给main函数。
1)argc表示参数的数量。
2)argv指向一个指针序列以NULL指针结束,每个指针指向一个字符序列表命令行参数,第一个参数就是程序名字,可通过argv间接访问操作获取命令行参数。

4,表达式中的字符串常量值是一个常量指针,指向字符串的第一个字符,与数组名一样,可以用指针表达式和下标引用使用字符串常量。

猜你喜欢

转载自blog.csdn.net/mei_true/article/details/131395721
今日推荐