《代码阅读方法与实现》阅读笔记三

第3章   高级C数据类型

人们在设计完全傻瓜式的系统时,常犯的错误就是低估了十足傻瓜的能力。

                                                           ――Douglas Adarns

         3.1指针

在C程序中,指针一般用来:

构造链式数据结构;引用动态分配的数据结构;实现引用调用(call by reference)访问和迭代数据元素;传递数组参数;引用函数;作为其他值的别名;代表字符串;直接访问系统内存。

#define new(type) (type*) calloc(sizeof(sizeof(type),1)

[…]

node=new(struct codeword_entry);

用一个宏来完成数据结构的动态分配。

Static char * ccval (const struct cchar *,int);

C函数只能返回指向数组元素的指针,不能返回整个数组。因此,当函数在数组中生成结果,并返回相应的指针时,一定要确保该数组不是在函数的栈上分配的局部变量,避免出现这类问题的一种方法是将这类数组声明为static。这种做法也并非完全安全,使用全局或static局部变量的函数大多数情况下都不可重入(reentrant)。这意味着,如果这个函数的一个实例正在运行,那么程序中其他执行线程就不能再调用它。更坏的情况是,在我们的示例中,函数的结果必须在该函数再次被调用之前,保存到其他地方(例如,使用strdup调用);否则,它将被新的结果重写。

C语言不允许将函数作为参数传递给其他函数,然而,它允许传递指向函数的指针。

在阅读基于字符串的代码时,要注意区分字符指针和字符数组。

3.2结构

结构在C语言中的应用如下:

将一般作为一个整体来使用的数据元素集合到一起;从函数中返回多个数据元素;构造链式数据结构;映射数据在硬盘设备、网络链接和存储介质上的组织方式;实现抽象数据类型;以面向对象的方式编程。

Struct fxp_cb_nop{

Void * fill[2];

Volatile u_int16_t cb_status;

Volatile u_int16_t cb_command;

Volatile u_int32_t link_addr;

};

Volatile限定符(qualifier)用来标明,底层的内存字段要被程序之外的实体使用,从而,禁止编译器对这些字段执行优化,比如移除冗余引用。

结构内字段的次序依赖于所处的架构和所用的编译器,因此用结构来映射外部数据天生不可移植。    

3.3共用体

C共用体(union)将共享同一个存储区域的项聚合起来。某一时刻,共享该区域的这些项中,只有一项可以访问。在C程序中共用体主要用于下述用途:

有效地利用存储空间;实现多态(polymorphism);使用不同的内部表达方式对数据进行访问。

到目前为止,共用体最常见的应用是实现多态。此处的意思就是同一个对象用于代表不同的类型。这种用途的共用体一般会潜入到包含type字段的C结构中,这个type字段表示共用体存储的数据类型,常用一个名为type的枚举类型来表示。

我们最后分析的共用体应用是将数据存入共用体的一个字段,然后访问另外的字段,以完成数据在不同内部表达方式之间的转换。尽管这种应用天生不能移植,但有些转换是能够安全执行的,其他一些情况虽然比较有用,但要依赖具体机器。

3.4动态内存分配

一般将malloc封装到执行检查malloc返回值的函数中(一般命名为xmalloc),在需要调用malloc的地方用这个函数来替代。

如果需要更多的空间,则调用C库函数realloc,将第一个参数指向的空间,调整为由函数的第二个参数指定的新大小。该函数返回一个指向调整后内存块的指针,它的地址可能和最初块的地址并不相同。原内存块中的内容被复制到新的位置。

 

你可能感兴趣的:(《代码阅读方法与实现》阅读笔记三)