c专家编程3、4章读书笔记

来源:互联网 发布:数据库设计第三范式 编辑:程序博客网 时间:2024/06/05 15:26

师兄毕业了,留给我一本c专家编程。今日略读几章,发现此书内容尚可,就是翻译的不好,导致有些内容无法一下子就理解,现就其中的几点内容做详细分析。

1.“3.3 优先级规则”与“3.4 通过图表分析c语言声明”,这一点内容我觉得写的非常好,比较适于分析复杂的c语言声明,就不给大家做展开分析了。

2. typedef int (*array_ptr)[100]

int (*array_ptr)[100]是数组指针,这里特别要与int *array_ptr[100]区分开来,根据c语言中符号的优先级规则,[]优先级要高于*,因此array_ptr先与[100]结合,代表array_ptr首先是一个数组,再与*结合,代表array_ptr中共包括100个int*类型的数据,这100个int*指针又可能分别指向不同的int数据,因此从总体上看int *array_ptr[100]是一个二维数组。以上分析过程可以使用“3.3 优先级规则”与“3.4 通过图表分析c语言声明”中介绍的方法进行分析。而int (*array_ptr)[100]首先是一个指针,而后这个指针指向一个一维数组,这个一维数组的长度是n。因此从总体上看int (*array_ptr)[100]也是一个二维数组,但其第一维仅有一个数据。

这里给大家推荐一篇blog,其中的一幅图可以加深大家对上述两个变量的内存布局的认识。

http://www.cnblogs.com/mq0036/p/3382732.html

既然以上两个变量都是二维数组,那么就都可以把以上两个变量指向二维数组。具体的赋值方法可以参考上述blog,在此就不给大家复制了。

给大家对上述问题采用一个更加简单的描述方式,int (*array_ptr)[100]也可以写为int (*)[100] array_ptr的形式。通过这种形式array_ptr的类型就更加一目了然了,array_ptr是一个指向数组的指针,因此array_ptr+1则是移动100个sizeof(int)字节,因此array_ptr+1则指向了数组最后一个元素的下一个元素,但此时array_ptr的类型仍然是int (*)[100]。

3. typedef 与 #define的区别

先给大家分享一些我在网上找到的资料

http://developer.51cto.com/art/201104/256060.htm

http://www.cnblogs.com/kerwinshaw/archive/2009/02/02/1382428.html

最直观的一个区别就是typedef 与 #define的用法是相反的,如下:

typedef    int       INT;
#define    INT       int

虽然在程序中都可以使用INT,但#define在预处理结束后便再次被换为int,而typedef是定义了int类型的别名,是语言编译过程的一部分。通过以上对比就可以发现两种方法的作用时间不同,#define是在编译的预处理阶段发挥作用,但typedef在编译阶段有效。

4. 定义和声明的区别

定义:只能出现在一个地方,确定对象的类型并分配内存。

声明:可以多次出现,描述对象的类型,用于指代其他地方定义的对象。

这里要注意的是,由于声明过程中不需要分配内存,因此不需要提供关于数组长度的信息。在声明多维数组时,需要提供除最左边一维之外其他维的长度。

5. 定义为指针,但以数组方式引用

在探讨这个问题前首先要对数组变量的引用方式进行分析,其引用方式可分为通过数组方式或指针方式进行引用。

1)通过数组方式对变量进行引用的运行时步骤为:

运行时步骤1:取i的值,将它与数组基地址相加。

运行时步骤2:取地址中的内容。

2)通过指针方式对变量进行引用的运行时步骤为:

运行时步骤1:取得符号表中p的地址,提取存储于此处的指针。

运行时步骤2:把下标所表示的偏移量与指针的值相加,产生一个地址。

运行时步骤3:访问上述地址,取得字符。


通过以上分析可以发现运行时系统对于数组引用与指针引用的处理方式不同。因此当定义为数组,引用为指针时,其运行步骤为:首先取数组0的内容,加上偏移量形成地址,最后解引用获得数据,但此时地址是错误的,因此通过以上方式就无法获得正确的数据。上述引用方式往往会造成段错误。
0 0