C诡异离奇,缺陷重重,却获得了巨大的成功。

---- --Dennis Ritch

好记性不如烂笔头,但是作为一个计算机专业的小菜选手,用笔而不同键盘是不是有点儿对不起互联网了,怎么的也要挤进这个知识互联共享的大家庭里。最近在看基本编程相关的书籍,这本曾经读过的[美]Peter Van Der Linden著 徐波 译的《C专家编程》回头看一看,发现有很多知识点,虽然和其他文章有重复,但是鉴于它的重要性和易错性,决定每天再看一看,并用bolg记录下来,让自己加深印象,深刻理解,这也是一个重复学习和监督的过程。我始终相信技术类的书不能一目十行,需要一步一步的向前走,想想以前也学了很多,看了很多,但是真正能握在手中的又有多少。这可不是练太极--“无形胜有形”!时间虽然紧张,但还得脚踏实地慢慢来,1*1虽然简单,但是每个人都曾付出努力去背过!不成功怎么知道它的简单,不失败怎么知道它的艰难。切记心浮气躁,切记走马观花,切记眼高手低!在这个过程中如果有幸也能帮到您一点,我也是十分的高兴,如果文章有错,敬请指出,不深感激!文章也会不断的进行完善,以后可能还有修改增删。
C语言的史前阶段:

C语言的出现证明了一件事儿,那就是失败时成功之母。因为一直被人们朝圣的C语言竟然源于一个失败的项目。1969,通用电气、麻省理工工学院和贝尔实验室联合创立了一个庞大的项目--Multics。该项目的目的是创建一个操作系统,但是最后失败了。当心灰意冷的贝尔实验室的专家们撤离Multics工程后,他们又去寻找其他的任务。其中一个叫Ken Thompson的研究人员对另一个操作系统很感兴趣。所以Thompson和Denis Ritchie自娱自乐,把Thompson的“太空旅行”软件移植到不太常用的PDP-7(由迪吉多公司所研发的一款迷你电脑)系统上。与此同时,Thompson为PDP-7编写了一个简单的OS,它比Multics简单的多,并取名为UNIX。

语言早期的发展:

BCPL(Basic Combined Programing Language)--基本组合编程语言。

1、编译器设计者的金科玉律:效率就是一切。
       在编译器中,效率几乎就是一切。
      编译器的效率主要包括两个方面: 运行效率(代码运行的速度)和编译速度(产生可执行代码的速度)。其中运行效率起决定性作用。很多的编译器会选择延长编译时间,缩短运行时间。还有一些优化措施(清楚无用代码和忽略运行时的检查)既能缩短编译时间,又能减少运行时间,还能减少内存的使用量。但是效率就是一切也不是绝对的,因为如果结果错误,就算编译器效率再高也是无用的。 由于早期的程序员就是那些编译器设计者,所以由很多语言特性是根据编译器设计者的思路发展而来的。
(1)数组的下标从0开始而不是1。但是人类是习惯从1开始的。
(2)C语言的基本类型直接与底层硬件相对应;
(3)auto关键字显然是摆设。它只对常见符号表入口的编译器设计者有意义。
(4)表达式中的数组名可以看作是指针;
(5)float被自动扩展为double;
(6)不许嵌套函数;
(7)register关键字。经常使用的变量可以放到寄存器。简化了编译器,把麻烦丢给程序眼员。
2、宏的替换时空格所引起的问题:

例如:#define a(y)  b(y)
a(x)被替换为:b(x);
而如果是#define a (x) b(y)
此时:
a(x) 被替换为:(x) b(y)x

这将被替换的面目全非,所以宏就是单纯的文本替换,使用时要注意。
3、一个非比寻常的bug;
       C语言从Algol中继承了一个特性,就是复合赋值符。它允许一个重复出现的赋值符只写一次而不是两次;因为最早的时候,B语言中词法分析器里有一个技巧:实现=op比op=要方便:
     例如现在的:b+=3   为什么不是b=+3呢?
    因为这样会产生歧义?
     一个简单的例子,若是b=-3;那么翻译是:b=b-3呢?还是b=-3?负数。
      所以这时早前编译器出现的一些bug。
4、函数的原型申明;

老式的函数申明方法:char * strcpy(det,src)char *det,*src;{}现在:char *strcpy(char *det,char *src){}

可以省略形参名称,但是不能省略类型;
5、参数的赋值条件:
        要是赋值的形式合法,两个操作数都是指向有限定符或无限定符的相容类型的指针, 左边指针所值向的类型必须具有右边指针所指向的类型的全部限定符。
简单的理解:

例如;char * cp;
const char *ccp;  //指向一个具有const限定的字符指针;
ccp=cp;//合法的,没有警告;
cp=ccp;//结果会产生编译警告;

const最有用之处就是用它来限定函数的形参,这样 该函数将不会修改实参指针所指的数据。
     但是可以通过scanf()和指针来改变值。这里就不细讲了。主要是分清常量指针和指针常量,以及指向常量的指针常量。
6、安静的转变
    (1).在表达式中,char 和 short 类型的值,无论有符号还是无符号,都会自动转换成 int 或者 unsigned int(如果 short 的大小和 int 一样,unsigned short 可表示的最大值就大于 int,在这种情况下,unsigned short 被转换成 unsigned int)。因为它们被转换成表示范围更大的类型,故而我们把这种转换称之为“升级(promotion)”。
    (2).按照从高到低的顺序给各种数据类型分等级,依次为:long double, double, float, unsigned long long, long long, unsigned long, long, unsigned int 和 int。这里有一个小小的例外,如果 long 和 int 大小相同,则 unsigned int 的等级应位于 long 之上。char 和 short 并没有出现于这个等级列表,是因为它们参与运算时就应该已经被升级成了 int 或者 unsigned int。
    (3).作为参数传递给函数时,char 和 short 会被转换成 int,float 会被转换成 double。使用函数原型可以避免这种自动升级。
7、一个微秒的Bug
请看下面一段代码:

int array[]={1,2,3,4,5};
#define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0]))
int main()
{int d=-1,x;if(d<=TOTAL_ELEMENTS){x=array[d+1];}
}

运行此程序,你会发现改程序if条件不为真,这是why?
     这是becauseTOTAL_ELEMENTS所定义的值是unsigned int类型的,因为sizeof()返回的类型是无符号型的。 if语句在unsigned int和signed int之间测试相等性,则d会被升级到unsigned类型,因为nusigned类型表示的范围更大。那-1转换为一个unsigned就是一个无比大的整数,用补码表示。致使表达式一直是假。看似简单的问题,却在“安静的转换中”隐藏着一个Bug。
  要修改这个问题,只需要强制类型转换一下即可:

if(d<=(int)TOTAL_ELEMENTS-2)  //OK

注:尽量不要使用无符号类型的数据,这样会引起不必要的麻烦。只有在位段和二进制掩码的时候才可以使用无符号数。
其实在某些版本中我们要使用下面的代码

#define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0]))  (1)
而不是:
#define TOTAL_ELEMENTS (sizeof(array)/sizeof(int))   (2)

如果是(2)式,我们将array变成char或者float类型,就会出现意想不到的结果。但是前者可以在不修改#define语句的情况下改变数据组的基本类型(比如把int变为char,float等等)。
所以一定要小心这些“安静的转换”!
小知识;
      我们所说的“黑客”(Hacker),它的原先意思是“天才程序员”,后来这个称号被媒体贬损,人言可畏啊,一个好人被硬生生的说成了坏人。使他在局外人的眼中成了“邪恶的天才”的代名词,类似一个bad guy。

自由软件基金:(Free Software Foundation)是一个特殊的组织,它由MIT的顶级黑客Richard Stallman所创立。目标是软件应该是免费的,所有人都可以自由使用。他雄心勃勃想建立一个UNIX的自由软件实现方案,成为GUN(代表GUN is not UUIX。

《C专家编程》:编译器的金科玉律(一)相关推荐

  1. 一篇特别长的总结(C专家编程)

    博客链接: http://codeshold.me/2017/02/expert_c_programming.html 读一本书必输出一篇笔记或者总结!!! <C专家编程>这本书很早看完了 ...

  2. C专家编程—使用unsigned int可能产生的Bug(1)

    在vs2008环境下,如下代码显示不同的结果: #include<stdio.h> #define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0 ...

  3. Python专家编程

    Python专家编程 一.CPython CPython是一个默认的.广泛使用的Python编程语言的实现.CPython是用C语言写的.除了CPython,还有两个高质量的Python实现:一个是J ...

  4. 《C专家编程》一1.6 它很棒,但它符合标准吗

    本节书摘来自异步社区<C专家编程>一书中的第1章,第1.6节,作者 [美]Perter Van Der Linde,更多章节内容可以访问云栖社区"异步社区"公众号查看 ...

  5. c语言多态性编码图形,C和C++经典著作 C专家编程Expert C Programming Deep C Secrets pdf...

    摘要 <C专家编程>可以帮助有一定经验的C程序员成为C编程方面的专家,对于具备相当的C语言基础的程序员,<C专家编程>可以帮助他们站在C的高度了解和学习C++.书本撷取了几十个 ...

  6. C专家编程(Expert C Programming)1

    C专家编程(Expert C Programming) 一基本概念 1.与时间相关的几个函数 char *ctime( const time_t *timer ); Each of these fun ...

  7. 《C专家编程》学习总结2

    <C专家编程>学习总结2   转自 : http://blog.chinaunix.net/u2/87570/showart_2120069.html 编译器做了些什么 图1:编译器通常分 ...

  8. C专家编程 读书笔记

    在ANSI C中,如果要声明空参数表,则必须使用关键字void进行显式声明: CPU,16位地址总线,能够访问2^16也就是64KB的内存:20位地址总线,可以访问2^20也就是1MB的内存:32位地 ...

  9. C专家编程(Expert C Programming)(二)

    C专家编程(Expert C Programming)(二) 1.程序内存布局 2.运行时数据类型 堆栈 函数内部的局部变量,函数调用时的维护性信息,暂时存储区(通过alloca分配的内存就是位于此, ...

  10. C语言专家编程题,一篇特别长的总结(C专家编程)

    读一本书必输出一篇笔记或者总结!!! <C专家编程>这本书很早看完了,但整理笔记却断断续续的花了三天时间,这从侧面更说明了这本书的经典了(尽管不到300页)! 至此C经典著作<C T ...

最新文章

  1. java IDE的四大金刚
  2. 基础认证伪造工具phishery
  3. 计算机专业答辩模板,论文答辩模板-计算机专业.ppt
  4. win10禁用驱动程序强制签名_图文细说 win10系统未检测到第三个监视器的途径 -win10使用教程...
  5. html中的特殊符号
  6. 大数据之-Hadoop之HDFS的API操作_配置参数的优先级说明_以设置hdfs文件副本数量参数为案例---大数据之hadoop工作笔记0057
  7. 怎么看登陆哪个用户名_面试教材看哪个版本?抽到的版本与备考的不一致怎么办?...
  8. Scott Mitchell 的ASP.NET 2.0数据教程之十七:: 研究插入、更新和删除的关联事件
  9. 吴恩达深度学习笔记 course2 week2 优化算法
  10. eclipse svn插件安装总失败 每次打开eclipse总提示 subversive svn connectors
  11. 删除Windows远程桌面连接记录 和 删除Windows凭据
  12. Bayesian framework 贝叶斯框架 (R)
  13. 1030:计算球的体积
  14. Vmware打开服务器的时候提示“该虚拟机似乎正在使用中。”
  15. qq影音4.0 android,QQ影音4.0官方最新正式版
  16. html动画爱心制作代码,CSS心形加载的动画源码的实现
  17. Σd|nφ(d)=n的证明
  18. linux安装最新版的glib库,GLib库安装与简析
  19. BZOJ1665 Usaco2006 Open The Climbing Wall
  20. android canvas画图gc,自定义控件绘图(Canvas,Paint,Region等)篇一

热门文章

  1. 单片机原理及其应用试题(含答案)
  2. 树莓派 安装谷歌拼音输入法(树莓派官方版系统、基于Debian)
  3. execution表达式里写多个条件
  4. 前端学习(一):HTML基本语法
  5. html 如何写退出程序,vb点击关闭窗口 单击退出程序的VB代码怎么写
  6. (04)Structs初学笔记——后台往前台传值
  7. 智慧园区弱电系统集成建设方案
  8. 串口控件MSCOMM的注册方法(使用MSCOMM串口控件程序的运行问题)
  9. 给Hexo主题博客加入百度站点统计
  10. warning: Pulling without specifying how to reconcile divergent branches is discouraged. You can sque