《C专家编程》1-2章阅读收获
一、
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 somethingreturn buffer;
}
buffer是一个自动分配内存的变量,也就是函数的局部变量,当控制流离开声明局部变量的范围时,自动变量将失效。
返回一个指向局部变量的指针,当函数结束,该变量已经被销毁,谁也不知道这个指针指向地址的内容是什么。
解决方案:
A、使用全局声明的数组
简单易用,任何人都有可能修改这个数组。
函数的下一次调用会覆盖当前的数据。、
B、使用静态数组 :static char buffer[20];
将修改范围限定在函数范围
函数的下一次调用会覆盖当前的数据
C、显示的分配内存
char * func()
{char * s = malloc(120);//....return s;
}
防止函数外的修改
每次调用不会覆盖以前的返回值
适合多线程
程序员要承担内存管理的责任,必须记得要释放内存,以免造成内存泄漏
在同一代码块中进行malloc和free操作,可以更为轻松进行内存管理
lint程序
lint程序是一个检测工具,可以检查出bug和一些不可靠的编码风格。后来为了编译器做得更小、更快、更简单,
把lint程序从编译器中抽出来了。
《C专家编程》1-2章阅读收获相关推荐
- C专家编程 第1章 C:穿越时空的迷雾 1.9 阅读ANSI C标准,寻找乐趣和裨益
阅读ANSI C标准,寻找乐趣和裨益 int foo(const char **p) { } 编译这段代码,编译器会发出一条警告信息: int main(int a ...
- 《C专家编程》第二章——这不是Bug,而是语言特性
无论一门语言有多么流行或多么优秀,它总是存在一些问题,C语言也不例外.本章讨论的重点是C语言本身存在的问题,作者煞费苦心的用一个太空任务和软件的故事开头,也用另一个太空任务和软件的故事结尾,引人入胜. ...
- C专家编程 第6章 运动的诗章:运行时数据结构 6.1 a.out及其传说
运动的诗章:运行时数据结构 编程语言理论的经典对立之一就是代码和数据的区别.有些语言(如Lisp)把二者视为一体.其他语言(如C语言)通常维持两者的区别.Internet蠕虫非常难以被人们所 ...
- C专家编程 第11章 你懂得C,所以C++不再话下 11.1 初识OOP
C++之于C,就像Algol-68之于Algol ---David L.Jones 如果你觉得C++还不够复杂,那你知道protected abstract virtual ...
- C专家编程 第10章 再论指针 10.7 使用指针创建和使用动态数组
使用指针创建和使用动态数组 当预先并不知道数据的长度时,可以使用动态数组.绝大多数具有数组的编程语言都能够在运行时设置数组的长度.它们允许程序员计算需要处理的元素的数目,然后创建一个刚好能容纳 ...
- C专家编程 第8章 为什么程序员无法分清万圣节和圣诞节 8.10 轻松一下---国际C语言混乱代码大赛
轻松一下---国际C语言混乱代码大赛 C语言结合了汇编语言的所有威力和汇编语言的所有易用性. 国际C语言混乱代码大赛(IOCCC)是一项年度竞赛,自1984年以来一直延续至今.它源于Lande ...
- C专家编程 第1章 C:穿越时空的迷雾 1.4 KR C
时间:1978 人物:Steve Johnson 事件:编写了pcc这个可移植的C编译器 影响:形成了一代C编译器的基础. C语言的演化之路如图1-2所示. 1973-3(早期的C)--->19 ...
- C专家编程 第8章 为什么程序员无法分清万圣节和圣诞节 8.2 根据位模式构筑图形
根据位模式构筑图形 图标(icon)或者图形(glyph)是一种小型的位模式映射于屏幕后产生的图像.一个位表示图像上的一个像素.如果一个位被设置,那么它所代表的像素就是"亮" ...
- C专家编程 第6章 运动的诗章:运行时数据结构 6.3 操作系统在a.out文件里干了些什么
操作系统在a.out文件里干了些什么 为什么a.out要以段的形式组织.段可以方便地映射到链接器在运行时可以直接载入的对象中!载入器只是取文件中的每个段的映像,并直接将它们放入到内存中.从本 ...
最新文章
- 东莞市经济贸易学校计算机,2017东莞市经济贸易学校中考录取分数线公布
- 程序员幽默:工作群里常见表情的真正含义……
- 远程连接server问题
- 用Vim编程——配置与技巧
- 桌面计算机怎么覆盖文件,恢复被覆盖的文件_恢复被覆盖的桌面文件
- python在化学中的应用_用Python配平化学方程式的方法
- AD9371+ZYNQ结构中JESD204B IP核的AXI_STREAM接口数据结构
- 平面标定(Homography变换)
- 安全工具(免费杀毒软件Avast、免费防火墙费尔、免费木马清理工具arswp,AVG/Ewido,超级兔子)...
- PR/PS/AE/达芬奇免费模板素材网站分享——个人纯分享,没有公众号,没有广告!
- Window.iso镜像文件下载
- C# 利用winrar解压带密码的压缩包
- Android 10.0 去掉SystemUI中的电池图标显示
- 【人物志】美团技术委员会前端通道主席洪磊:爱折腾的斜杠青年
- RS码(Reed-Solomon码)
- 典型相关分析如何分析两组变量的关系
- 华为鲲鹏HCIA考试-练习04
- MeRL:强化学习分配奖励机制的新方法
- python--计算两个中文字符串的编辑距离
- 如何从浏览器中导出crx应用