C++ Tips: 类型和声明

  
4.1 保持较小的作用域。
    保持较小的作用域有助于避免一些难以发现的错误。
C++ 支持在for 循环和if 语句中直接声明变量,如:
for (int i=0; i<100;i++){}
if (bool b = func() ) {}
其中i 和b 的作用域从被声明的点开始,直到 } 结束。
 
4.2 不要在一个作用域和它外围的作用域里采用同样的名字。
在一个作用域和它外围的作用域里采用同样的名字会造成名字遮蔽,即外围的名字被内部作用域的名字遮蔽,人们很容易没有注意某个名字被遮蔽了,所以会造成一些隐蔽的错误。
 
4.3 在一个声明中声明一个名字。
例如int* p, q; 是指int* p; int q; 而不是int* p; int* q;  int* p, q; 这种结构不利于阅读 因此应该避免。
 
4.4 让常用的和局部的名字比较短,让不常用的和全局的名字比较长。
    选择好的名字是一种艺术。较大的作用域的名字应该相对比较长且更加明确,如textParser 、intMatrix 。在很小的作用域使用很短且熟悉的名字,如i 、x 、tmp 。常用的名字比较短,书写方便,不常用的名字比较长这种做法也很有价值。
4.5 避免看起来类似的名字。
如只是大小写不同的名字,count 和Count 。或者大写的O 和零0 ,小写的L(l) 和一(1) 都很难分辨,应该避免。一些代码分析工具如CodeWizard 会对它们提出警告。
 
4.6 维持某种统一的命名风格。
应该选择一种统一的命名风格。如宏定义和枚举大写,用下划线分隔单词等。这样可以提高代码的可读性。
 
4.7 仔细选择名字,反映其意义而不是反映其实现方式。
   例如phone_book 就比number_list 要好,即使你的电话号码实际存放在list 里。请仔细选择那些重要的名字,否则几个月后自己写的代码也会让你困惑。
 
4.8 如果所用的内部类型表示某种可能变化的值,请用typedef 为它定义一个有意义的名字。
   例如我们想用float 去表示温度,那么用typedef 会清晰的表明含义。typedef float Temperature 。Temperature temp;
 
4.9 用typedef 为类型定义同义词,用枚举或类定义新类型。
   typedef 是为类型定义同义词,而不是定义新的类型。C++ 里只有枚举或类是用户定义类型,可以用来定义新类型。
 
4.10 切记每个声明中都必须描述一个类型(没有“隐式的int “)
     例如const c = 7 ;C 和C++ 的早期版本将int 作为没有明确声明的类型。这种隐式的int 会导致许多微妙错误。
 
4/11 避免有关字符数值的不必要假设。
     一个字符表示的是C++ 程序运行的机器上的字符集中该字符的整数值。如果在一台使用ASCII 字符集的机器上,’0’ 的值就是48 。在非ASCII 字符集的机器上如EBCDIC 字符集,’0’ 的值是240 。char 的大小通常为8 位,但标准并没有规定它的大小,只是保证至少有8 位。
 
4.12 避免有关整数大小的不必要假设。
int 的大小是由实现确定的,典型情况下是32 位。short int 至少有16 位,long int 至少有32 位。
 
4.13 避免有关浮点类型表示范围的不必要假设。
浮点类型有float 、double 、long double ,它们的大小由实现确定。
 
4.14 优先使用普通的int 而不是short int 或者long int
int 大小由实现选择,采用在给定的计算机上最适合存储和操作整数的类型,通常是一个32 位的机器字。
 
4.15 优先使用double 而不是float 或者long double
浮点类型有float 、double 、long double ,意义由实现确定。对浮点运算的深入理解能帮助选择合适的类型,或者一般情况下选择double 就可以。
 
4.16 优先使用普通的char 而不是signed char 或者unsigned char
     char 可能是有符号的,也可能是无符号的。这三种char 类型的变量可以相互赋值,但可能导致无定义的结果。例如,char c; signed char sc; unsigned char uc;
c = 255; // 如果char 有符号且为8 位,则由实现定义
c = sc; // 可以
c = uc; // 如果普通char 有符号且uc 值过大,则由实现定义
sc = uc; //uc 值过大,则由实现定义
uc = sc ;// 可以, 转换到unsigned
sc = c; /// 如果普通char 无符号且c 值过大,则由实现定义
uc = c; // 可以, 转换到unsigned
如果始终采用普通char 这些问题都不会出现。
 
4.17 避免做出有关对象大小的不必要假设。
    C++ 对象的大小是用char 的大小的倍数表示的, 按照定义,char 的大小为1
基本类型大小的性质为:
1=sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)
1 <= sizeof(bool) <= sizeof(long)
sizeof(char) <= sizeof(wchar_t) <= sizeof(long)
sizeof(float) <= sizeof(double) <= sizeof(long double)
sizeof(N) = sizeof(signed N) = sizeof(unsigned N)
 
4.18 避免无符号算术。
    通过将变量声明为unsigned 而保证某些值始终为正的企图常常被隐含的类型转换规则破坏。如有这样的定义,unsigned int ui; int i; 如果恰好ui 的值为0 且 i 的值为-1 ,那么ui+i 等于多少? -1 ?结果将是unsigned int 类型的最大值。因为i 会被提升到unsigned int ,然后再与ui 相加。 如果是两个普通的int 相加就不会有问题。
 
4.19 应该带着疑问去看待从signed 到unsigned ,或者从unsigned 到signed 的转换。
    如果目标类型是unsigned ,结果值就是从原值中取出正好等于目标类型所需要的那么多位, 可能会发生截断。 如unsigned char uc = 1023 ;高位被截断, uc 的值为255 ,即11111111
如果目标类型是signed ,如果源值在结果类型中可以表示,则值不变,否则结果值由实现定义。 如signed char sc = 1023 ;// 实现定义
 
4.20 应该带着疑问去看待从浮点到整数的转换。
    浮点到整数转换,小数部分将被丢掉,也就是截断。如果转换结果无法在目标类型里表示,则结果无定义。 如:int i = 2.7 ;//i 变为2
char b = 2000.7 ;// 对8 位char 无定义,2000 不能在8 位char 里表示
 
4.21 应该带着疑问去看待向较小类型的转换,如将int 转到char
    向较小类型的转换,如将int 转到char 可能发生截断, 也可能导致无定义的行为, 参考4.19
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值