《C专家编程》读书记录

其实,这本书适合没事的时候翻翻,随便打开哪一页,应该都可以看下去的。总体来说,写的比较欢脱,不像《C和指针》和《C陷阱和缺陷》的章节标题那么严肃,有时候还以为自己在看科技杂志。不过,理解书里面的内容反而需要有较高的C语言基础,内容结构比较松散,如果觉得没有逻辑性,可能是语言基础还掌握的不够。

比较喜欢第1章关于C语言的介绍,前世今生什么的。

2015年5月1日  星期五 天气 雨

第1章  C:穿越时空的迷雾

  • C语言的史前阶段:BCPL->B->New B->早期C
  • C语言的早期体验(评:历史原因造成了现在C语言的一些语言特性)
  • 标准I/O库和C预处理器
  • K&R C   

      

  • 今日之ANSI C
  • 它很棒,但符合标准吗:不可移植代码,坏代码,可移植代码
  • 编译限制,ANSI C标准对一个能够成功编译的程序的最小长度做了限制
  • ANSI C标准的结构,与K&R C相比,最重要的新特性就是原型

第2章 这不是Bug,而是语言特性f

  • 编程语言的细节,Fortran语言经典错误,DO 10 I=1.10和DO 10 I=1,10的区别。

    分析编程语言缺陷的一种方法是把所有的缺陷归类为3类:不该做的做了,该做的没做,该做但做的不合适。

  • 多做之过
    • switch语句中的fall through  
    • 相邻字符串常量被自动合并  
    • 太多的缺省可见性,即默认的函数作用域过宽
  • 误做之过,语言中有误导性质或是不适当的特性
    • 重载,许多符号甚至关键字被重载
    • 有些运算符的优先级是错误的(ANSI C标准由于种种历史原因,没有在优先级方面采取措施)
  • 少做之过,语言应该提供但未能提供的特性
    • 空格问题
    • 注释风格
    • 编译器日期被破坏
    • lint程序绝不应该被分离出来,lint程序寻找bug,早用,勤用

第3章 分析C语言的声明

  • 只有编译器才会喜欢的语言,声明
  • 声明如何形成,至少一个类型说明符+有且只有一个声明器+零个或更多声明器+一个分号
  • 优先级规则,括号内的->后缀操作符->前缀操作符,按照这个顺序优先级从高到低
  • 通过图表分析C语言声明
  • typedef可以成为你的朋友,为一种类型引入新名字,而不是为变量分配内存
  • typedef int x[10]和#define x int[10]的区别
    • 可以用其他类型说明对宏类型名进行扩展
#define peach int  
unsigned peach i; /*没问题*/
typedef int banana;
unsigned banana i;/*错误,非法*/
    • 连续几个变量声明中,typedef保证所有变量为同一种类,#define定义则无法保证

  • typedef struct foo {..foo;}的含义,不同的命名空间内使用同一个名字,bad habit

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

  • 数组并非指针
  • 我的代码无法运行
  • /*file 1*/
    int mango [100];
    /*file 2*/
    extern int *mango;
  • 什么是声明,什么是定义
    • 声明,描述其他地方创建的对象
    • 定义,确定对象类型并为其分配内存,只能出现在一个地方
  • 使声明和定义匹配,指针的外部声明与数组不匹配,代码当然没办法运行
  • 指针和数组的区别
指针 数组
保存数据的地址 保存数据

间接访问数据,首先取指针内容,把它作为地址,然后从这个地址取地址。如果指针有一个下标[I],就把指针的内容加上I作为地址,从中提取数据

直接访问数据,a[I]只是简单的以a+I为地址取得数据
通常用于动态数据结构 通常用于存储固定数目且数据类型相同的元素
相关的函数为malloc().free() 隐式分配和删除
通常指向匿名数据 自身即为数据名

第5章 对链接的思考

  • 函数库、链接和载入

  C预处理器——>前端(语义和语法分析)——>后端(代码生成器)——>优化器——>汇编程序——>链接-载入器,编译器通常分割成几个更小的程序

    • 静态链接,函数库的一份拷贝是可执行文件的物理组成部分
    • 动态链接,可执行文件只包含了文件名,让载入器运行时自行寻找所需要的函数库
  • 动态链接的优点,体积小,共享数据库
  • 函数库链接的5个特殊秘密
    • 动态库文件扩展为“so”,静态为“a“
    • 通过-lthread选项,告诉编译器连接到libthread.so
    • 编译器期望在确定的目录找到库
    • 观察头文件,确认所使用的函数库
    • 与提取动态库中的符合相比,静态库中的符号提取的方法限制更严  
  • 警惕interpositioning,通过编写与库函数同名的函数来取代该库函数的行为
  • 产生链接器报告

第6章 运动的诗章:运行时数据结构

运行时数据结构包括栈,活动记录,数据和堆

  • a.out及其传说,assembler output,汇编程序和链接编辑输出格式
  • 段,segments,在unix中段表示一个二进制文件相关的内容块。文件中有三个段:文本段,数据段和BSS段
  • OS在a.out文件里干了些什么,可执行文件中段在内存如何分布(自己画一下内存中的分布图)
  • C语言运行时系统在a.out里干了些什么,C语言怎么组织正在运行的程序的数据结构(堆栈,活动记录,数据,堆等)

    堆栈段的三个主要作用:为局部变量提供存储空间,进行函数调用时存储与此相关的一些维护性信息,用作暂时存储区

  • 当函数被调用时发生了什么:过程活动记录(自己画过程活动记录的规范描述)
  • auto和static,函数内变量定义为static被保存在数据段而不是堆栈,就算退出函数,变量值依然保持。
  • 控制线程
  • setjmp和longjmp,主要用于错误恢复
  • UNIX中的堆栈段,当进程需要更多空间是,堆栈会自动生长
  • MS-DOS中的堆栈段,在可执行文件建立时,堆栈大小必须确定,不能再运行时增长
  • 有用的C语言工具:用于检查源代码的工具,用于检查可执行文件的工具,用于帮助调试的工具,性能优化辅助的工具

2015年5月5日  星期二 9:43

第7章 对内存的思考

  • Intel 80x86系列,向后兼容
  • Intel 80x86内存模型以及它的工作原理
    • 在UNIX中,段是一块以二进制形式出现的相关内容
    • 在内存模式中,段是内存模型设计的结果,一块64KB的内存区域
    • 在OS中,段与操作系统的内存管理有关
  • 虚拟内存,通过“页”形式组织,页是OS在disk和memory之间移动的单位,一般为几K字节
  • Cache存储器 ,全写法cache和写回法cache
  • 数据段和堆,像堆栈段能够根据需要自动增长一样,数据段也包含了一个对象,用于完成这项工作,这就是堆。堆用于动态分配的存储,通过malloc等库函数获得内存。
  • 内存泄露

    C语言通常不使用垃圾收集器,自动确认并回收不再使用的内存块。

    堆经常出现两种类型的错误:

    • 释放或改写仍在使用的内存
    • 未释放不再使用的内存 
  • 总线错误,总线错误大多是因为未对齐的读或写引起的,段错误是由于内存管理单元异常,通常由于解引用一个未初始化/非法值的指针引起

第8章 为什么程序员无法分清万圣节和圣诞节

看了之后有点不知所云,还是理解不够深,好零碎的感觉

第9章 再论数组

  • 什么时候数组和指针相同?

    

  • 为什么会发生混淆
    • 作为函数的形式参数时,数组和指针可互换
    • 表达式中数组名(与声明不同)被compiler当做一个指向该数组第一个元素的指针
    • C语言把数组下表作为指针的偏移量
  • 为什么C语言把数组形参当做指针,传值调用,传址调用?
  • 数组片段的下标

    通过向函数传递一个指向数组任意元素的指针,这样传递给函数的就是从该元素之后的数组片段

  • 数组和指针可交换性的总结
    • 用a[i]这样的形式对数组进行访问总是被编译器“改写”或解释为像*(a+i)这样的指针访问
    • 指针始终是指针,绝不可以改写为数组。你可以用下标形式访问指针,一般都是指针作为函数参数的时候,而且你知道实际传递给函数的是一个数组
    • 在特定的上下文中,也就是作为函数的参数,一个数组的声明可以被看成一个指针。作为函数参数的数组(就是在一个函数调用中)始终会被编译器修改成为一个指向数组第一个元素的指针
    • 因此,当把一个数组定义为函数参数时,可以选择把它定义为数组,也可以定义为指针。不管何种选择,在函数内部事实上获得的都是一个指针
    • 在其他情况中,定义和声明必须匹配。
  • C语言的多维数组
    • 尽管术语上称作多维数组,但C语言实际上只支持“数组的数组”
    • int apricot[2][3][4]在内存中的定位(可以自己画一下) 
    • 内存中数组如何布局:“行主序”,数组最右边下标最先变化 
    • 对多维数组的初始化

第10章 再论指针

  • 多维数组的内存分布,以线性形式排列在内存中,array[i][j]——>*(*(array+i)+j)
  • 指针数组就是Iliffe向量,声明一个一维指针数组,每个指针指向一个字符串来取得类似于二维字符数组的效果.char *pea[4];char pine[4][5];
  • 在锯齿状数组上使用指针,字符串指针数组,右端长度不一
  • 向函数传递一个一维数组,需要长度约束,有两种方法
    • 增加额外参数表示元素数目,argc的作用
    • 赋予数组最后一个元素一个特殊的值,该值不会作为正常元素出现在数组中
  • 使用指针向函数传递一个多维数组
    /*二维或更多维数组无法在C语言中用作一般形式的参数*/
    my_function(int my_array[10][20]);
    my_function(int my_array[][20]);
    my_function(int (*my_array)[20]); my_function(
    char ** my_array); /*字符串指针*/

    对于多维数组作为参数传递的支持缺乏是C语言存在的一个内在限制。这使得用C语言编写某些特定类型的程序非常困难,如数值分析算法。

  • 使用指针从函数返回一个数组
    /*先声明函数*/
    int (*paf()) [20];
    /*定义函数*/
    int (*paf()) [20]{ 
        int (*pear)[20];  
        pear=calloc(20,sizeof(int)); 
        if(!pear)longjmp(error,1); 
        return pear; 
    }
    /*调用函数*/
    int (*result)[20];
    result=paf();
    (*result)[3]=12;
  • 使用指针创建和使用动态数组
    • 使用malloc()函数得到一个指向一大块内存的指针,然后像引用数组一样引用内存
    • realloc()对一个现在的内存块大小进行重新分配,同时不会丢失原来块的内容  

    

第11章 你懂得C,所以C++不在话下

  • 初识OOP,面向对象编程:封装,继承,多态(动态绑定?)
  • 抽象——取事物的本质特性
    • 隐藏不相关细节
    • 向外界提供“黑盒子”接口
    • 把一个复杂的系统分解成几个相互独立的组成部分
    • 重用和共享代码
  • 封装——把相关的类型、数据和函数组合在一起
    • 类把代码和相关数据封装(捆绑)在一起
  • 展示一些类,类<-->对象,类型<-->变量
  • 访问控制,public,private,protected后面可以跟一大串声明,friend和virtual只能用于一条声明
  • 声明,正常的C语言声明,包括函数,类型或数据
  • 如何调用成员函数,点操作符.
  • 继承——复用已定义的操作
  • 多重继承
  • 重载,作用于不同类型的同一操作具有相同的名字
  • C++如何进行操作符重载
  • C++输入/输出,cout<<"the value is:"<<i<<endl;多个I/O操作数链接在一起
  • 多态——运行时绑定
    • 支持相关的对象具有不同的成员函数(但原型相同),并允许对象与适当的成员函数进行运行时绑定。virtual关键字告诉编译器该成员函数是多态的。
    • 多态是指一个函数或操作符只有一个名字,但它可以用于几个不同的派生类类型的能力    
  • 解释
    • 当相应派生类的成员函数取代基类的同类函数是,C++要求你必须提前通知compiler,方法就是在可能被取代的基类成员函数前加上virtual关键字
  • C++如何表现多态
    • vptr指针实现虚函数,vptr指针指向一个叫做vtbl的函数指针向量(称为虚函数表,也称为V表)。每个类都有这样一个向量,类中每个虚函数在该向量中都有一条记录
    • 具体可参看别人的一篇博客,对于虚函数在内存中分配等问题分析的非常透彻 http://blog.jobbole.com/86843/
  • C++的其他要点
    • 异常,在错误处理时改变程序的控制流
    • 模板,支持参数化类型 ,类和对象的关系<---->模板和函数的关系
      template<class T> 
      T min(T a,T b)
      {
          return (a>b)?a:b;
      }
    • 内联inline
    • new和delete操作符,new可以真正地建立一个对象,malloc()函数只分配内存。
    • 传引用调用,call-by-reference。  
原文地址:https://www.cnblogs.com/sherPur/p/4555602.html