【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


时间: 2024-09-11 10:27:24

【C++注意事项】1 数据类型及类型转换的相关文章

【C++注意事项】3 引用

通俗来讲,引用(reference)就是给对象另外一个名字. 1)引用必须被初始化 int &ref; // 错误 int val=10; int &ref2=val; // ref2指向val(val的另一个名字) 在初始化变量时,初始值会被拷贝到新建的对象中.在定义引用时,程序把引用和它的初始值绑定(bind)在一起,而不是将初始值拷贝到引用.一旦初始化完成,引用将和它的初始值对象一直绑定在一起.因为无法令引用重新绑定到另一个对象,因此引用必须初始化. 补充:所谓对象,就是一块存储数据

Python数据类型、字符串、运算符入门教程

在这里把python中特有的,以及和C不同的地方记下来. 数据类型 强制类型转换 字符串 转义字符 自然字符串 Unicode字符串 字符串是不可变的 标识符变量的命名 缩进 运算符 运算优先级 1.数据类型 在python中,有4种数据类型--整数(int).长整数(long).浮点数(float)和复数(complex). 2是一个整数的例子. 长整数不过是大一些的整数.长整型通常在数字后面加L表示,如1000000L. 3.23和52.3E-4是浮点数的例子.E标记表示10的幂.在这里,5

SQL Server数据类型转换方法_MsSql

在SQL Server日常的函数.存储过程和SQL语句中,经常会用到不同数据类型的转换.在SQL Server有两种数据转换类型:一种是显性数据转换:另一种是隐性数据转换.下面分别对这两种数据类型转换进行简要的说明: 1 显式转换 显示转换是将某种数据类型的表达式显式转换为另一种数据类型.常用的是CAST 和 CONVERT 函数.  CAST: CAST ( expression AS data_type )  CONVERT: CONVERT (data_type[(length)], ex

&lt;font color=&quot;red&quot;&gt;[置顶]&lt;/font&gt;

Profile Introduction to Blog 您能看到这篇博客导读是我的荣幸,本博客会持续更新,感谢您的支持,欢迎您的关注与留言.博客有多个专栏,分别是关于 Windows App开发 . UWP(通用Windows平台)开发 . SICP习题解 和 Scheme语言学习 . 算法解析 与 LeetCode等题解 . Android应用开发 ,而最近会添加的文章将主要是算法和Android,不过其它内容也会继续完善. About the Author 独立 Windows App 和

【软妹带你学技术】Duang!C++那些不得不说的事儿

艾瑞宝迪看过来!(偷偷唱起来了什么鬼......)话说今天,阳光明媚风景如画,正是畅所欲言夸夸其谈的好日子哇,所以,咱们聊聊C++可否?品一杯茶,执一支笔,45°仰望沉思(很好,装叉技能开启).所谓C++,那可是编程语言中的大大大大咖,无人不知无人不晓,放之四海Duang力无敌.然而,还是有一些不得不说的事儿需要告知各位兄台,请耐下心来听我细细道来. [C++注意事项一]数据类型及类型转换 本篇中咱们讨论如何选择类型和类型转换的问题. 如何选择类型呢? 1.当数值不可能为负时,选择无符号类型:

Java语法基础(一)----关键字、标识符、常量、变量

一.关键字: 关键字:被Java语言赋予特定含义的单词.组成关键字的字母全部小写.注:goto和const作为保留字存在,目前并不使用.main并不是关键字.     二.标识符: 标识符:就是给类,接口,方法,变量等起名字时使用的字符序列. 组成规则:英文大小写字母.数字字符.$和_ 注意事项:不能以数字开头.不能是Java中的关键字.区分大小写 我们通常会给下面的这些东西起一个标识符: 包.类或者接口.方法和变量.常量   三.注释: 单行注释的格式: //注释文字 多行注释的格式: /* 

Java关键字、标识符、常量、变量语法详解_java

一.关键字 关键字:被Java语言赋予特定含义的单词.组成关键字的字母全部小写.注:goto和const作为保留字存在,目前并不使用.main并不是关键字. 二.标识符 标识符:就是给类,接口,方法,变量等起名字时使用的字符序列. 组成规则:英文大小写字母.数字字符.$和_ 注意事项:不能以数字开头.不能是Java中的关键字.区分大小写 我们通常会给下面的这些东西起一个标识符: 包.类或者接口.方法和变量.常量 三.注释 单行注释的格式: //注释文字 多行注释的格式: /* 注释文字 */ 文

PostgreSQL SQL语法(一):词法结构

本文档为PostgreSQL 9.6.0文档,本转载已得到原译者彭煜玮授权. SQL输入由一个命令序列组成.一个命令由一个记号的序列构成,并由一个分号(";")终结.输入流的末端也会标志一个命令的结束.具体哪些记号是合法的与具体命令的语法有关. 一个记号可以是一个关键词.一个标识符.一个带引号的标识符.一个literal(或常量)或者一个特殊字符符号.记号通常以空白(空格.制表符.新行)来分隔,但在无歧义时并不强制要求如此(唯一的例子是一个特殊字符紧挨着其他记号). 例如,下面是一个(

Java经典面试题 一

问题:如果main方法被声明为private会怎样? 答案:能正常编译,但运行的时候会提示"main方法不是public的". 问题:Java里的传引用和传值的区别是什么? 答案:传引用是指传递的是地址而不是值本身,传值则是传递值的一份拷贝. 问题:如果要重写一个对象的equals方法,还要考虑什么? 答案:hashCode. 问题:Java的"一次编写,处处运行"是如何实现的? 答案:Java程序会被编译成字节码组成的class文件,这些字节码可以运行在任何平台,