现在的位置: 首页 > 综合 > 正文

C语言感悟(一)

2013年10月14日 ⁄ 综合 ⁄ 共 1338字 ⁄ 字号 评论关闭

学习完谭浩强的标准C(在任何平台上都可运行的通用C),老谭所写内容有助于菜鸟快速入门,知识主要集中于语法上,从最开始的“Hello World”,引入了头文件+main函数 的程序框架,紧接着让我们认识了变量,算术表达式,告诉了我们变量类型、以及表达式有的操作符、控制流、函数以及面向过程语言的顺序编程模型(任意一个时刻都只有一条指令在执行)、模块化的程序设计方法(简而言之就是将任务分割成几个子函数的组合),后篇介绍了C的灵魂--指针和数组,让我们认识到C下的内存模型,从编译器的角度,源程序只有符号和数据(这里的数据包括了程序内存模型中的,代码段和数据段)一切皆指针(地址),这个有必要举例讲明下:

 int i = 10;

 i编译后实质就是一个符号(对应一个VA即虚拟地址,它的值由编译器分配)

 接着当我访问i时,这个过程分为2步走:

 1.根据符号VA找到对应的内存(把内存想象一个字节一个格子,并对应一个号码)

 2.根据符号类型这里是int顺序读取sizeof(int)字节的内容

int *p = &i;

 按上述的步骤,我们访问p得到的是816进制数(相信大多还在32平台下编程),这肯定不是我们想要的结果,我们需要的是数字值不是地址,于是我们又多了一个操作符“*” ,专业点的解释是解引用。

Ps:解引用就是根据指针的值找到内存,根据指针所指数据类型,顺序的读取内存

一级指针解引用的操作一次,二级两次

到这里我们可以总结下:

访问符号,我们就由VAvirtual address)找到内存,根据类型顺序读取的字节数

总是有特例:比如 int a[10];  符号 与 &a 的值是相同

                 int(*p)[10]; 符号与 *p 的值是相同

大家可能读完老谭的书,肯定对此迷惑不解,此时需借助外力《C专家编程》来做解释。

老谭解释:数组名就是就是常量指针,上式可改写为 int * const a;

如果按照老谭解释,我们走上述的12两步,根据符号aVA(就是&a),顺序读取4字节(这个值其实就是a[0])a的值是a[0]&a的值是VA,二者肯定不等,上面的结论就解释不通

正解:数组名不是指针,我们不妨把数组写成java声明的形式  int[10] a;

接着走上述的两个步骤,根据符号aVA寻址到内存,而此时符号a的类型是数组,这个时候不是去按类型顺序的读内存,而是将VA直接返回,并将数据类型改为指向数组首元素的指针 最后a的值是VA,但数据类型变成了 int * 上述观点得到完美解释

接着看:int[10] * p;

由符号pVA找到内存,类型是指针(不管它是指向何种数据类型的),顺序的读4字节

不妨假设它的值是 0x00001111

* P 对指针解引用,先到指针所指内存处 0x00001111,指向的数据类型,此处是数组,故将0x00001111直接返回,并将数据类型改为 int *

综上 p*p的值是相同的

老谭解释其实对大家是个天大的误导,数组名只有在作为表达式的右值时或者函数的形参才可以解释为指针。

完善总结:

访问符号,根据VA找到内存,如果这时符号的类型是数组,直接将VA返回,并将数据类型更改为数组首元素的指针

抱歉!评论已关闭.