《C专家编程》1-2章阅读收获
2017-09-13 10:22
267 查看
一、
C诡异离奇,缺陷重重,却获得了巨大的成功。
·编译器设计:效率(几乎)就是一切。编译器的效率包括两个方面:运行效率(代码的运行速度)和编译效率(产生可执行代码的速度)。
除了开发和学习环境外,运行效率起决定作用。
·数组下标0的开始。这个编译器的设计者的选择,因为偏移量的概念在他们心中已经根深蒂固。
·C语言的基本数据类型与底层硬件相对应。
·auto关键字是摆设(在C++11后,auto已经变成自动类型判定这一强大功能)
·C程序员要自己管理动态内存的使用,创建各种大小的数组,测试数组边界。并且自己进行范围检查。
C++引入一些新方法,使得宏这种预处理器几乎无用武之地。(这句话并不理解)
编译限制:在代码移植的时候应该不同编译器之间的差距。
·“安静的改变” 算术的转换 ,2个操作数的类型不同将会被转换。
数据类型朝着浮点精度更高、长度更长的方向转换,整形数如果转换为signed不会丢失信息,就转换为signed,否则转换unsigned。
当无符号数unsigned int 和signed int比较的时候,在标准C(ANCI C),有符号数将被自动转换为无符号数。(注意当出现比较的时候,可能出现bug)
【尽量不要使用无符号数】包括年龄,国债等。
·二、这不是bug,而是语言特性
·switch: 1、 如果没有default,而且所有的case都不匹配,那么将跳过这个switch代码段。
2、一条switch最多有257个标签(256个可能的值和一个EOF)
3、把default打成defau1t(把“l”打成“1”),一般的lint程序检测不出
4、const并不是常量
5、一般来说case后面要加break,不然将顺序执行case 语句(fall through错误)
在定义C函数的时候,在缺省情况下函数的名字是全局可见的。
在函数前加extern的缺省存储类型说明符是冗余的。
想要限制对这个函数的访问必须在函数前加一个static。
多义符号(多用符号)
有一条很实用的建议:乘法和除法优于加法和减法,在涉及其他操作符是一律加上括号。
运算符的结合性:结合性只用于表达式中同时出现2个相同的优先级操作符的情况,用于消除歧义。
例如a=b=c; =具有右结合性,所以该句语句等同于,b=c;a=b;
(不如分开或是用括号,不要自找麻烦)
在函数中返回一个数组例如下面的代码
char * localize_time(char * filename)
{
char buffer[20];
//do something
return buffer;
}
buffer是一个自动分配内存的变量,也就是函数的局部变量,当控制流离开声明局部变量的范围时,自动变量将失效。
返回一个指向局部变量的指针,当函数结束,该变量已经被销毁,谁也不知道这个指针指向地址的内容是什么。
解决方案:
A、使用全局声明的数组
简单易用,任何人都有可能修改这个数组。
函数的下一次调用会覆盖当前的数据。、
B、使用静态数组 :static char buffer[20];
将修改范围限定在函数范围
函数的下一次调用会覆盖当前的数据
C、显示的分配内存
char * func()
{
char * s = malloc(120);
//....
return s;
} 防止函数外的修改
每次调用不会覆盖以前的返回值
适合多线程
程序员要承担内存管理的责任,必须记得要释放内存,以免造成内存泄漏
在同一代码块中进行malloc和free操作,可以更为轻松进行内存管理
lint程序
lint程序是一个检测工具,可以检查出bug和一些不可靠的编码风格。后来为了编译器做得更小、更快、更简单,
把lint程序从编译器中抽出来了。
C诡异离奇,缺陷重重,却获得了巨大的成功。
·编译器设计:效率(几乎)就是一切。编译器的效率包括两个方面:运行效率(代码的运行速度)和编译效率(产生可执行代码的速度)。
除了开发和学习环境外,运行效率起决定作用。
·数组下标0的开始。这个编译器的设计者的选择,因为偏移量的概念在他们心中已经根深蒂固。
·C语言的基本数据类型与底层硬件相对应。
·auto关键字是摆设(在C++11后,auto已经变成自动类型判定这一强大功能)
·C程序员要自己管理动态内存的使用,创建各种大小的数组,测试数组边界。并且自己进行范围检查。
C++引入一些新方法,使得宏这种预处理器几乎无用武之地。(这句话并不理解)
编译限制:在代码移植的时候应该不同编译器之间的差距。
·“安静的改变” 算术的转换 ,2个操作数的类型不同将会被转换。
数据类型朝着浮点精度更高、长度更长的方向转换,整形数如果转换为signed不会丢失信息,就转换为signed,否则转换unsigned。
当无符号数unsigned int 和signed int比较的时候,在标准C(ANCI C),有符号数将被自动转换为无符号数。(注意当出现比较的时候,可能出现bug)
【尽量不要使用无符号数】包括年龄,国债等。
·二、这不是bug,而是语言特性
·switch: 1、 如果没有default,而且所有的case都不匹配,那么将跳过这个switch代码段。
2、一条switch最多有257个标签(256个可能的值和一个EOF)
3、把default打成defau1t(把“l”打成“1”),一般的lint程序检测不出
4、const并不是常量
5、一般来说case后面要加break,不然将顺序执行case 语句(fall through错误)
在定义C函数的时候,在缺省情况下函数的名字是全局可见的。
在函数前加extern的缺省存储类型说明符是冗余的。
想要限制对这个函数的访问必须在函数前加一个static。
多义符号(多用符号)
static | 在函数内部,表示该变量的值在各个调用中保持延续性 在函数这一级,表示该函数只对本文件可见 |
extern | 用于函数定义,表示全局可见(属于冗余的) 用于变量,表示它在其他地方定义 |
void | 作为函数的返回类型,表示不返回任何值 在指针声明中,表示通用的指针声明 位于参数列表中,表示没有参数 |
* | 乘法运算符 用于指针,间接引用 位于参数列表中,表示没有参数 |
& | 位的AND操作符 取地址操作符 |
优先级问题 | 表达式 | 可能误以为的结果 | 实际结果 |
.的优先级高于* (->操作符用于解决这个问题) | *p.f | p所指对象的字段f (*p).f | 对p取f偏移,作为指针,然后进行接触引用操作 |
[]高于* | int *ap[] | ap是个指向int数组的指针 int(*ap)[] | ap是个元素为int指针的数组 int *(ap[]) |
函数( )高于* | int *fp() | fp是个函数指针,所指向的 函数返回int | fp是个函数,返回值是个int*类型 |
==和!=高于位运算符 | (val&mask!=0) | (val&mask)!=0 | val&(mask!=0) |
算术运算符高于移位运算符 | msb<<4+lsb | (msb<<4)+lsb | msb<<(4=lsb) |
逗号运算符优先级最低 |
运算符的结合性:结合性只用于表达式中同时出现2个相同的优先级操作符的情况,用于消除歧义。
例如a=b=c; =具有右结合性,所以该句语句等同于,b=c;a=b;
(不如分开或是用括号,不要自找麻烦)
在函数中返回一个数组例如下面的代码
char * localize_time(char * filename)
{
char buffer[20];
//do something
return buffer;
}
buffer是一个自动分配内存的变量,也就是函数的局部变量,当控制流离开声明局部变量的范围时,自动变量将失效。
返回一个指向局部变量的指针,当函数结束,该变量已经被销毁,谁也不知道这个指针指向地址的内容是什么。
解决方案:
A、使用全局声明的数组
简单易用,任何人都有可能修改这个数组。
函数的下一次调用会覆盖当前的数据。、
B、使用静态数组 :static char buffer[20];
将修改范围限定在函数范围
函数的下一次调用会覆盖当前的数据
C、显示的分配内存
char * func()
{
char * s = malloc(120);
//....
return s;
} 防止函数外的修改
每次调用不会覆盖以前的返回值
适合多线程
程序员要承担内存管理的责任,必须记得要释放内存,以免造成内存泄漏
在同一代码块中进行malloc和free操作,可以更为轻松进行内存管理
lint程序
lint程序是一个检测工具,可以检查出bug和一些不可靠的编码风格。后来为了编译器做得更小、更快、更简单,
把lint程序从编译器中抽出来了。
相关文章推荐
- 《C专家编程》3-4章阅读收获
- 《C专家编程》7-8章阅读收获
- Java编程思想阅读收获
- [程序员]杂志2011年第2期,阅读收获
- C++ primer第二次阅读学习笔记(第1、2章)
- Java编程思想阅读收获
- 听儿童阅读的意义与价值讲座收获 2017.08.20
- 黑马程序员 【Head Firs Java (中文版)阅读笔记】 1章、2章、3章
- 《终极算法》阅读笔记与摘要(1)-序和第1-2章
- 一段适合新手的Java代码,阅读一定有收获。
- cocos2d-x Programmers Guide v3.3 译本和阅读笔记(1-2章)
- 阅读软件开发本质和方法的收获
- 阅读Java代码的的一些收获
- 阅读jdk1.8源码小收获
- 阅读cin用法介绍的收获
- 四年阅读20遍,遍遍都有新收获 -- 好书不在厚贵
- 读移山之道确实有收获(阅读作业之王熹篇)
- doubango初步阅读收获-跨平台的代码编写
- 阅读编程规范收获
- 《The C Programming Language》第二次阅读之收获