C++(3) 基本数据类型相关细节

Cpt3 处理数据

a. 本章包括整型和浮点型、其系统限制文件、数字字面值和类型转换等;
OOP的本质是根据存储对象的特征设计并扩展自己的数据类型;这些类型的基本组件是C++的内置类型;
内置类型包括基本类型和复合类型,基本类型包括不同大小的整数和浮点数,复合类型包括数组、字符串、指针、结构等;

3.1 简单变量

a. 信息的存储包括类型、取值、位置;
C++命名规则:只能包含数字、字符和下划线;
第一个字符不能是数字;大小写敏感;
不能使用C++关键字直接作为名称;
一般以两个下划线或下划线加大写字母作为开头的名称被保留给实现使用(FILE_,LINE 都是预定义的宏,使用_ 和 __ 开始的函数一般都是专用的函数,一般都是于特定系统相关的,如果要想有更好的移植性,应该避免使用),以一个下划线开头的名称被保留给实现,用作全局标识符(_global);
不推荐用户本身自定义这类变量;
没有长度限制(但有些平台可能有限制);
多个单词组合一般采用下划线或者从第二个单词开始大写首字母;
在命名时可以通过适当的前后缀增加变量的可读性;

b. 使用宽度width描述数据类型的单位内存开销;
基本类型的宽度排序为char、short、int、long、long long,分为有符号和无符号两种;
一般的,char=1B,short至少2B,int至少与short一样长,long至少4B,且不短于int;long long至少8B,且不短于long;
一般认为1byte=8b;(容纳字符集的最小实现,如ASCII和EBCDIC,Unicode则可能需要更大的表示,如16-32b);
int的实现宽度是一个值得注意的问题,int可以使16b到64b,取决于硬件,考虑到实现环境的问题,在程序移植时可能出现问题,具体尺寸查看使用sizeof,sizeof(类型名)或sizeof 变量名;
默认signed;
对基本整型的描述可以对应地查看climits头文件(使用对应的符号常量来表示对类型的限制,例如INT_MAX/INT_MIN/CHAR_BIT,一般由编译器决定;

C++额外支持的初始化方式:int a(10)==int a=10;
在使用时如果不对参数变量进行初始化,函数将会读取内存残留作为输入参数导致错误;
对C++11支持额外的初始化方式,int a{1}或int a={1},支持数组、结构、单值变量,括号内缺省表示重置为0;
这种方式有助于更好地防范类型转换错误,一般而言使用大括号初始化是为了统一初始化方式,即使初始化兼容于类的初始化,增强初始化通用性;

c. 无符号类型,关键字unsigned;
类型到unsigned类型的值传递是以0作为参照的,而不是其二进制实现;

d. 整数类型的选取:
在不考虑内存的情况下,优先使用自然长度int;
在存在可移植性问题的情况下,避免int可能随环境变化导致宽度变化,应使用对应的long(接近16位)或long long(接近20位)等类型;
在严格考虑内存的情况下,一般使用short节省内存,避免由于环境移植导致int类型内存占用增加,节省一点就是赢得一点;
注意不同长度变量截取和赋值的差异;

e. 整形字面值,C++对数字的显示支持,十进制/0八进制/0x十六进制,默认以十进制输出;
但是需要注意,字符串和数字间的转换之类的操作只支持十进制,八进制会是变为十进制,十六进制无法输出;
stringstream操作(需要string和ssteam头文件)以及sscanf_s函数都不行;(不同的输出类型只是为了表达方便(内存读写))
cout的格式化输出:cout<<type; cout<<number;type包括dec,hex,oct等控制符;该操作影响后续的所有cout;

f. 对于常量其存储类型默认为int,如果数据存在后缀(u-无符号,l-long,ll-long long等等,大小写都可以)则按照后缀指定格式;
对于没有指定后缀的常量,按照能够存储该数的最小类型表示
(int起,2000int4000long3000000000longlong,int为16位),
对于没有后缀认十六进制和八进制数,考虑到其应用环境一般为地址描述,因此一般采用无符号类型;

g. 一般系统的常用字符不超过128个,即8bit足够表示字符,此外也可以用于作为整型存储数据;
一般采用ASCII标准,使用宽字符类型例如Unicode字符集可以存储更多值;
字符及其编码的转换由输入输出函数完成;
字符字面值(字符常量)一般使用单引号,字符串常量使用双引号;
可以使用输出流ostream的对象cout的一个成员函数cout.put()实现单字符输出;

h. char字面值,一般不直接采用编码方式,而是使用引号显式输入;
对不同编码类型应该同样满足有序性;
对于部分特殊字符需要通过\进行转义以进行输入,或使其具有特殊功能;
转义字符同样对应到ASCII码;
现代系统并不支持所有的转义序列;
对于某些组合键,同样可以使用转义的八进制或十六进制数ASCII码表示(等价于单个字符的输入),例如使用\032或\0x1a表示Ctr+Z,可以嵌入到字符串中;
转义字符的实际实现可能受到系统的影响;
一般char的默认类型不能确定是否包含符号,在存储整型的应用下需要手动设置类型signed/unsigned;

i. 通用字符名,C++支持的基本字符集可以分为源字符集、执行字符集(执行过程中可用,一般指输入输出),此外针对各地方言问题引入了通用字符名universal character name,以提高不同语言键盘的输入兼容性;
基于通用字符名甚至可以拿中文作为变量名;
还是重复一下一般不采用编码输入方式;
(拿vs2017不能正常输出,需要手动扩展);

j. wcha_t,作为char的补充类型,用于表示扩展字符集,与某一底层类型的长度和符号属性相同;
对于要求存储为wcha_t类型的字符(串)需要在引号之前加L进行说明,且对应的需要使用wcin和wcout;
底层类型这个可以看成是使用某种整形类型重用来存储字符typedef short wchar_t;
C++11新增了char16_t和char32_t,可以看成固定长度2B和4B的wchar_t,以避免实现方式差异性,分别使用前缀u和U,与\u形式的Unicode和\U形式的Unicode匹配;其实现也是基于某种已有的底层类型;

j. bool i;i=true/false,一般非零(包括负数)表示true,此外任何数字值或指针值(NULL=0)都可以被隐式转换为bool值;

3.2 const限定符

a. 对常量使用符号名称进行调用可以增强程序的维护性和可读性;对常量的关联除采用宏定义外,C++更常用的方式是const修饰;
一般const修饰的变量大写首字母,宏定义方式一般大写所有字母;const变量一般(只能,const修饰的变量不能作为可接收数值的左值)在声明中直接进行初始化;
相比宏定义,const的优势是(1)可以确定变量类型;(2)受作用域限制;(3)可以用于特殊数据类型;

3.3 浮点数

a. 浮点数表示为num1num2的形式,即num=num1*2^num2;
浮点数通常可以输出为带小数点的形式或科学计数法形式;

b. 浮点类型,包括float、double、long double,类型参数包括有效位数significant figure和指数范围;通常float有效位为32,double为64,long double为80/96/128,指数范围至少是-37-37;具体范围参考cfloat头文件;
从cfloat看指数范围比有效位大多了,也就是优先考虑取值范围,其次考虑精度;
cout所属的ostream类有一个类成员函数,可以精确控制输出格式,包括字段宽度、小数位数、输出格式等;
浮点数常量默认存储为double类型,可以使用f-float后缀和l-long double后缀;
对于float,C++只保证6位有效位;

c. 浮点数转化细节,浮点数采用2幂次描述,其基本组成结构包括符号位S-指数位E-小数为F,实际值为S1.F2^E,E具有正负,采用移码表示(8位E则-127);
float,S=1,E=8,F=23,32bit-4B;
double,S=1,E=11,F=52,64bit-8B;
考虑到浮点数的表示形式,以float为例,F部分描述的小数part最小为2-23=0.0000001192,次小值2-22=0.000000238,也就是分辨率实际上是2-23=1.192*10^-07,分辨率为七位有效数字,考虑到末位存在舍入,一般认为float的有效位数为6位,部分有效位为7位;
同理,double为15-部分16;
一般只将浮点数用于范围描述,而不用于相等判定;

3.4 C++算数运算符

a. 基本的算术运算符包括:±*/(取整)%(取余),其中/在存在小数操作数时返回小数(上转换),%不允许小数操作数;
运算符优先级与算数优先级一致,括号仍然有顶级的优先级;
对于作用于同一操作数的同级运算符需要考虑运算符对操作数的结合性,以确定对该操作数首先进行哪一侧的运算;一般而言相同等级的运算符具有相同的结合性以便判断操作次序,例如对同级运算符R-L的a,b,a1b则是先对1进行b运算;
对于其他同级操作,其顺序取决于系统实现;

b. 除法分支,除法仅在操作数都是整数的情况下进行取整操作,否则整数操作数将会类型上转换为浮点型;

c. 取余运算,一般用于结合除法运算解决将一个量分成不同部分的问题;

d. 类型转换,不同变量类型的操作可能具有不同的硬件编译指令;
类型转换一般发生在不同类型变量间的值传递过程(赋值、参数传递、运算符)中;
初始化和赋值:右值类型隐式转换为左值类型(存在类型限制;
大范围类型到小范围类型的赋值,一般只复制右侧的字节
浮点型到整型的赋值需要同时考虑范围和小数部分截取的问题;

e. 列表初始化,即基于{}的批量初始化,一般用于对复杂数据类型进行初始化;该转化要求不能进行截取,且要求数据已知的不能超过目标类型范围,范围不确定的变量x,由于编译器并不确定(即便在执行该语句时x确实不越界)x范围,因此不支持该赋值语句;

f. 表达式类型转换,
整型提升,由于int类型被认为是计算机最自然的类型,在执行过程中低于int的类型会被转换为int的形式进行运算(true=1),并将运算结果转换为原类型;
对于不同类型,编译器根据校验表实现类型的上转换,一般将两个操作数转换为较宽的操作数形式,以保证宽度一致;浮点型宽于整型;
在不溢出的情况下相同类型优先转换为有符号型,否则转换为无符号型

g. 强制类型转换,typename(value)(函数风格·),或(typename)value;
更严格的转换函数为static_cast(value);

h. auto类型,自适应类型,根据初始值选取优先度较高的类型;一般用于复杂类型的处理,根据其初始化方式自适应的选取变量类型;
一般不用于对简单类型的设置;
强制类型转换是否存在数据泄露;

i. 常见基本类型的有效位数和取值范围为:
char-8bit-S+2^7-128;
short-16bit-S-215-32768;3*104
int-32bit-S-231-2147483647;2*108
long-int;(或者说long相比int长度更加固定);
long long-64bit-S-263-9223372036854775807i64;9*1018;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值