【C++注意事项】1 数据类型及类型转换

如何选择类型

1)当数值不可能为负时,选择无符号类型。

2)当数值超过了int的表示范围时,选用long long。

3)在算术表达式中不要使用char或bool,只有在存放字符串或布尔值时才使用它们。因为类型char在一些机器中是有符号的,而在另一些机器中又是无符号的。如果你需要使用一个不大的整数,那么明确指定它的类型是signed char或者unsigned char。

4)执行浮点数运算选用double,这是因为float通常精度不够而且双精度浮点数和单精度浮点数的计算代价相差无几。事实上,对于某些机器而言,双精度运算甚至比单精度还快。long double提供的精度在一般情况下是没有必要的,况且它带来的运算时间消耗也是不容小觑的。

类型转换

1)当我们把一个非布尔类型的算术值赋给布尔类型时,初始值为0则结果为false,否则结果为true。

2)当我们把一个布尔值赋给非布尔类型时,初始值为false则结果为0,初始值为true则结果为1.

3)当我们把一个浮点数赋给整数类型时,进行了近视处理。结果值将保留浮点数中小数点之前的部分。

4)当我们赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。例如,8比特大小的unsigned char可以表示0至255区间的值,如果我们赋了一个区间以外的值,则实际的结果是该值对256取模后所得的余数。因此,把-1赋给8比特大小的unsigned char所得的结果是255。

5)当我们赋给带符号类型一个超出它表示范围的值时,结果是未定义的(undefined)。此时,程序可能继续工作、可能崩溃,也可能生成垃圾数据。

无符号数的转换

下面再来展示一个有意思的代码片。

unsigned u = 10;
int i = -42;
cout<<i + i<<endl;  // 输出:-84
cout<<u + i<<endl;  // 输出:4294967264

第一个输出应该就不用说了,对于第二个,首先将-42转换成无符号数,把负数转换成无符号数类似于直接给无符号数赋一个负值,结果就等于这个负数加上无符号数的摸。是不是有些拗口呢?看看下面的代码呢?

int i = -42;
unsigned w=i;
cout<<w<<endl;  // 输出为:4294967254

在来看看下面这段代码:

unsigned u1=42,u2=10;
cout<<u2-u1<<endl;  // 输出:4294967264
unsigned u=-32;
cout<<u<<endl;  // 输出:4294967264  和上面的两段代码一样,都是将-32转换为无符号数

还有一点需要注意的。比如在写一个将数字从10到0的降序输出时,考虑到无符号数不会小于0这一铁律,你是否会这样写呢?

for(unsigned i =10; i>=0; --i)
    cout<<i<<endl;

这是一个陷阱…… 因为当i等于0的时候,输出0是显然的,然而在继续执行for循环中的自减操作后得到了-1,-1并不满足无符号数的要求,因此就像前面的例子那样就被转换成了一个合法的无符号数(4294967295)。

解决这个问题的关键在于要在输出变量之前先减去1。这样的话,如果循环从10开始,减去1后输出结果就成了9到0了,因此初始化时要设置为11。

而且最终截断点不应该是i==0,而应该是i>0,所以应该这样改:

for(unsigned i =11; i>0;)
{
    --i;
    cout<<i<<endl;
}

当然了,既然截断点是大于0,这正好可以用上while循环了。

unsigned i =11;
while(i>0)  // 此处写成 while(i) 也是可以的
{
    --i;
    cout<<i<<endl;
}

备注:该【C++注意事项】系列参考了《C++ Prime 》一书和网络资源,主要用于给自己复习、总结,也希望对广大读者有帮助。



感谢您的访问,希望对您有所帮助。 欢迎大家关注、收藏以及评论。

我的更多博客文章:NoMasp博客导读


为使本文得到斧正和提问,转载请注明出处:
http://blog.csdn.net/nomasp


posted @ 2015-05-20 18:56  nomasp  阅读(222)  评论(0编辑  收藏  举报