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

C预处理器所实现的3个主要功能是:
(1)字符串替换,通常用于为常量提供一个符号名。
(2)头文件包含:一般性的声明可以被分离到头文件中,并且可以被许多源文件使用。
(3)通用代码模板的扩展:与函数不同,宏在连续几个调用中所接收的参数的类型可以不同(宏的实际参数只是按照原样输出)。在宏的扩展中,空格会对扩展的结果造成很大影响。

ANSI C标准的每个主题都附有一个约束小节,列出了所有的约束条件。现在又出现了一个更为有趣的情况:标准规定编译器只有在违反语法规则和约束条件的情况下才能产生错误信息。这意味着所有不属于约束条件的语义规则你都可以不遵循,而且由于这种行为属于未定义行为,编译器可以采取任何行动,甚至不必通知你。

可移植的代码(portable code):即严格遵循标准的代码。一个严格遵循标准的程序应该是:
(1)只使用已确定的特性;
(2)不突破任何由编译器实现的限制;
(3)不产生任何依赖由编译器定义的或未确定的或未定义的特性的输出。

关键字const并不能把变量变成常量!在一个符号前加上const限定符只是表示这个符号不能被赋值,也就是它的值对于这个符号来说是只读的,但它并不能防止通过程序的内部(甚至是外部)的方法来修改这个值。const最有用之处就是用它来限定函数的形参,这样该函数将不会修改实参指针所指的数据,但其他的函数却可能会修改它。

算术转换:
char,short int或者int,包括它们的有符号或无符号变型,以及枚举类型,可以使用在需要int或unsigned int的表达式中。如果int可以完整表示源类型的所有值,那么该源类型的值就转换为int,否则转换为unsigned int,这称为整型升级。
在寻常的双目算术运算中,如果其中一个操作数的类型是long double,那么另一个也被转换为long double。其次,如果其中一个操作数的类型是double,则另一个也被转换为double。再次,如果其中一个操作数类型是float,则另一个也被转换为float。否则,两个操作数进行整型升级:如果其中一个操作数类型是unsigned long int,那么另一个也被转换为unsigned long int。如果其中一个操作数类型是long int,而另一个是unsigned int,则如果long int能够完整表示unsigned int的所有值,则unsigned int类型操作数被转换为long int,如果long int不能完整表示unsigned int的所有值,则两个操作数都被转换为unsigned long int。再次,如果其中一个操作数类型是long int,则另一个被转换为long int。再次,如果其中一个操作数类型是unsigned int,则另一个被转换为unsigned int。如果所有上述情况都不属于,则两个操作数都为int。

尽量不要在代码中使用无符号类型,以免增加不必要的复杂性。尤其是不要仅仅因为无符号数不存在负值而用它来表示数量。
尽量使用像int那样的有符号类型,这样在涉及升级混合类型的复杂细节时,不必担心边界情况(如-1被翻译为非常大的正数)。
只有在使用位段和二进制掩码时,才可以使用无符号数。应该在表达式中使用强制类型转换,使操作数均为有符号数或无符号数,这样就不必由编译器来选择结果的类型。

在制订ANSI C标准时,引入了pragma指示符。#pragma用于向编译器提示一些信息,诸如希望某个特定函数扩展为内联函数,或者取消边界的检查。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值