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

第四章  令人震惊的事实:数组和指针并不相同

 

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       轻松一下——回文的乐趣

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值