您的位置:首页 > 编程语言

《C专家编程》读书笔记4

2011-07-30 11:23 197 查看
第四章 令人震惊的事实:数组和指针并不相同

4.1 数组并非指针

extern int *x;

extern int y[];

4.2 我的代码为什么无法运行

文件1:

int mango[100];

文件2:

extern int*mango;

并不能正确运行

4.3 什么是声明,什么是定义

定义,只能出现在一个地方,确定对象的类型并分配内存,用于创建新的对象。例如:int my_array[100];

声明,可以出现多次,描述对象的类型,用于指代其他地方定义的对象(例如在其他文件里)。例如:extern int my_array[[];由于并未在声明中为数组分配内存,所以并不需要提供数组长度的信息。对于多维数组,提供除最左边一维之外其他维的长度——这就是给编译器足够的信息产生相应的代码。

4.3.1 数组和指针是如何访问的

X = Y;

X的含义是X所代表的地址。

这个被称为左值。

左值在编译时可知,左值表示存储结果的地方。

Y的含义是Y所代表的地址的内容。

这个被称为右值。

右值知道运行时才知。如无特别说明,右值表示“Y的内容”。

每个符号的地址在编译时可知。所以,如果编译器需要一个地址(可能还需要加上偏移量)来执行某种操作,它就可以直接进行操作,并不需要增加指令首先取得具体的地址。相反,对于指针,必须首先在运行时取得它的当前值,然后才能对它进行解除引用操作(作为以后进行查找的步骤之一)。图A展示了对数组下标的引用



如果声明extern char *p,它将告诉编译器p是一个指针,它指向的对象是一个字符。为了取得这个字符,必须取得p的内容,把它作为字符的地址并从这个地址中取得这个字符。



4.3.2 当你“定义为指针,但以数组方式引用”时会发生什么

当书写了extern char *p,然后用p[3]来引用其中的元素时,编译器将会:

1. 取得符号表中p的地址,提取存储于此处的指针。

2. 把下标所表示的偏移量与指针的值相加,产生一个地址。

3. 访问上面这个地址,取得字符。



4.4 使声明与定义相匹配

4.5 数组和指针的其他区别



定义指针时,编译器并不为指针所指向的对象分配空间,它只是分配指针本身的空间,除非在定义时同时赋给指针一个字符串常量进行初始化。

只有字符串常量才是如此。不能指望为浮点数之类的常量分配空间,如:

float *pip = 3.141; /*错误!无法通过编译*/

在ANSI C中,初始化指针时所创建的字符串常量被认为只读。如果试图通过指针修改这个字符串的值,程序会出现未定义的行为。在某些编译器中,字符串常量被存放在只允许读取的文本段中,以防止它被修改。

由字符串常量初始化的数组是可以修改的。

4.6 轻松一下——回文的乐趣
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: