• 读《C专家编程》总结一


    《C专家编程》这本书是自己认真读完的一本IT类的书籍,书中详细介绍了关于C语言的缺陷和优点,对于C语言的初学者有很大的帮助;并且本书的语言活泼生动,读起来没有技术类书籍的那种枯燥和艰涩;书中还提供了一些编程实例,供读者实践;确实是一本好书,看过的人都知道,呵呵。

    现将书中对自己有帮助的内容总结如下:

    1.理解C语言声明的优先级规则(本书第64页)

    A  声明从它的名字开始读取,然后按照优先级顺序依次读取。
    B  优先级从高到低依次是:
      B1  声明中被括号括起来的那部分;
      B2  后缀操作符:括号()表示这是一个函数,而方括号[]表示这是一个数组;
      B3  前缀操作符:星号*表示“指向...的指针”

    C  如果const和(或)volatile关键字的后面紧跟类型说明符(如int,long等),那么它作用于类型说明符,在其他情况下,const和(或)volatile关键字作用于     它左边紧邻的指针星号。

    譬如,用优先级规则分析下面的C语言声明:

    char * const *(*next)();
    适用规则                              解                                                释
    A 首先,看变量名“next”,并注意到它直接被括号括住
    B1   所以先把括号里的东西作为一个整体,得出“next”是一个指向...的指针
    B    然后考虑括号外面的东西,在星号前缀和括号后缀之间作出选择
    B2 B2规则告诉我们优先级较高的是右边的函数括号,所以得出“next是一个函数指针,指向一个返回...的函数”
    B3 然后,处理前缀“*”,得出指针所指的内容
    C 最后,把“char * const”解释为指向字符的常量指针

    把上述结果概括如下:这个声明表示“next是一个指针,它指向一个函数,该函数返回另一个指针,该指针指向一个类型为char的常量指针”。

      

    2.数组和指针是如何访问的(本书第83页)

    我们首先要注意“地址y”和“地址y的内容”之间的区别。这是一个相当微妙支出,因为在大多数编程语言中我们用同一个符号来表示这两样东西,由编译器根据上下文环境判断它的具体含义。以一个简单的赋值为例:

    x = y;

    在这个上下文环境里,符号相当含义是x所代表的地址 在这个上下文环境里,符号y的含义是y所代表的地址的内容
    x被称为左值 y被成为右值
    左值在编译时可知,左值表示存储结果的地方 右值知道运行时才知。如无特别说明,右值表示“y的内容”



          实际上编译器为每个变量分配一个地址(左值)  。这个地址在编译时可知,而且该变量在运行时一直保存于这个地址。相反,存储于变量中的值(它的右值)只有在运行时才可知。如果需要用到变量中存储的值,编译器就发出指令从指定地址读入变量并将它存于寄存器中。这里的关键之处在于每个符号的地址在编译时可知。所以,如果编译器需要一个地址(可能还需要加上偏移量)来执行某种操作,它就可以直接进行操作,并不需要增加指令首先取得具体的地址。相反,对于指针,必须首先在运行时取得它的当前值,然后才能对它进行解除引用操作(作为以后进行查找的步骤之一)。
    譬如下述代码对数组下表的引用:

    char a[9] = "abcd";
    ... ...
    char c = a[i];

    编译器符号表具有一个地址9980(实际上就是数组的首地址)
    运行时步骤1:取i的值,将它与9980相加;
    运行时步骤2:取地址(9980+i)的内容;

    再譬如下述代码对于指针的引用:

    char *p;
    ... ...
    c = *p;

    编译器符号表有一个符号p,它的地址是4624
    运行时步骤1:取地址4624的内容,就是“5081”
    运行时步骤2:取地址5081的内容。

    3.动态链接库与静态链接库的不同(本书第100页)

          在动态连接中,所有的符号进入输出文件的虚拟地址空间中,所有的符号对于链接在一起的所有文件都是可见的。相反,对于静态链接,在处理archive(静态库)时,它只是在静态库中查找载入器当时所知道的未定义符号。
          简而言之,在编译器命令行中各个静态链接库出现的顺序是非常重要的,因为符号是通过从左向右的顺序进行解析的。譬如相同的符号在两个不同的函数库中有不同的定义,静态库出现的顺序不同,其结果就有可能不同。另外,如果在自己的代码之前引入静态库,又会带来另一个问题。因为此时尚未出现未定义的符号,所以它不会从函数库中提取任何符号。接着,当目标文件被链接器处理时,它所有的对函数库的引用都是未实现的!这个问题最常出现于链接math库的时候。譬如,像下面这样进行静态链接:
      cc -lm main.c
    则会得到一条错误信息;为了能从math库中提取所需的符号,首先需要让文件包含未解析的引用,如下面所示:
      cc main.c -lm
    【备注】:始终将 -l 函数库选项放在编译命令的最右边是一个很好的习惯。


     未完待续......

  • 相关阅读:
    短视频不为人知的素材来源 以及平台推荐的黑盒机制
    说什么月入几万 我是不是应该一头撞死?
    Python 3 进阶 —— 使用 PyMySQL 操作 MySQL
    CentOS安装Subversion 1.9.*版本客户端
    [算法]PHP随机合并数组并保持原排序
    CentOS安装Memcached
    Git Windows客户端保存用户名和密码
    ApiGen 4.0配置项
    ApiGen安装
    SQL服务器模式
  • 原文地址:https://www.cnblogs.com/cnpirate/p/2703050.html
Copyright © 2020-2023  润新知