写点什么

萌新不看会后悔的 C++ 基本类型总结(二)

用户头像
花狗Fdog
关注
发布于: 2021 年 03 月 06 日




0. 浮点数关于有效范围一些问题


上一篇

上一篇大概地说了浮点数的精度问题和有效范围大小,还是有些东西没有说出来,我觉得还是应该说一说,我们常说的单精度有 6 ~ 7 位的有效范围,而双精度有 15 ~ 16 位的有效范围,这里所指的有效范围并不是该数值的大小,==这是很多初学者的一个误区==,并不是说这个单精度的 float 只能存储 6 ~ 7 位怎么大的数,如果是 1234578 这样的数则无法存储,这是错误的,想要理解这里的有效范围,还需要知道浮点数的存储方法,浮点数使用科学记数法来表示存储的,最大可以达到 3.4E38,这是一个很大的数,达到了 38 位之多,显然不是上面所说的 6 ~ 7 位,这个有效范围可以认为是 38 位中的前 6 ~ 7 位,因为是使用科学记数法表示,而 6 ~ 7 位又是根据尾数来得出来的,尾数又规定在 1 到 2 之间,也就是说最高位必须是 1,而后面的数可以是 000000(23 个 0),或者最大值为 2,也就是 1.1111111(23 个 1)==需要注意这里的尾数使用二进制表示的==,而 2 ^23 在 6 ~ 7 位之间,尾数可以保存 6 ~ 7 位,然后后面 38 个 0,这才是精度的根源。如果看不懂就去百度 IEEE754,还是看不懂也没关系,初学者不需要了解怎么多,我只是普及一下。




1. C++如何确定常量的类型


C++如何确定常量的类型,老规矩,我们举个例子:

大家都知道在 C++中有两种定义常量的方法,一种是使用 #define 的方式,还有一种就是下文要说的 const。


#define MAX  123456789const int Max 12345679
复制代码

区别在于 #define 不必定义该常量属于什么类型,是 int,还是 long int,而 const 定义的常量必须指明类型,至于哪种定义常量的方法好?我们推荐使用第二种,至于为什么,后面会说,我们现在主要来讨论 C++如何确定常量的类型,假设我们就使用 #define 定义了 MAX = 123456789 怎么一个常量,那么 C++会如何确定常量类型呢?


#define MAX 12456789std::cout <<sizeof(MAX) << std::endl;
复制代码


来看运行结果:

结果是 4,说明 C++将 MAX 保存为 int 类型。

如果我们把这个数变一下:


#define MAX 36456465llstd::cout <<sizeof(MAX) << std::endl;
复制代码

运行结果:

我们将 MAX 后面加了两个 LL,还记得 LL 表示什么吗?对,表示的是 long long 类型。


>下面的结论是需要记住的:在C++中将使用这几种类型中能够存储该数的最小类型来表示,前提是该数后面没有后缀,如果有后缀,则按后缀指定的类型来存储,至于浮点数呢,C++规定过只要不加f后缀的浮点数默认都为double,所以想要将浮点数存储为float,就需要特别的加上后缀f,这是和整形的不同。


以上说的都是对于十进制的存储方式,而对于八进制或者是十六进制,它们的存储方式为 int,unsigned int,long,unsigned long,long long 或者是 unsigned long long。至于为什么会使用无符号的类型来存储,这是因为十六进制常用来表示内存地址,内存地址是没有符号的,因此 unsigned int 比 long 更适合来表示十六位的地址。




2. const 除了修饰常量还能干什么


下面来说说 const,const 除了上面的用法,也就是定义常量,用 const 修饰变量时,一定要在初始化的时候进行赋值,否则之后是无法赋值的。

还有一些其他的用法,当然,如果你刚接触到上面的内容,这个可以跳过。


常量指针:


int number = 666;const int * p = &a;// int const * p 这种方法和上面等效,这个指针被修饰为常量指针,就是不可以通过这个指针修改变量的值。number = 66; //但是可以通过number修改,也就是间接修改了指针指向的变量。// 并且需要注意的一点是虽然不可以通过这个指针修改变量的值,但是可以修改指针所指向的变量,也就是说下面是合法的。int number_2 = 1;p = &number_2;
复制代码

就好比我有一台电脑,装的是 xp 系统,有一天邻居小姐姐想跟我借电脑用一下,但是她觉得 xp 系统老掉牙了,想重装为 win10 系统,这时我就告诉她,不可以,重装只有我可以,这是我的电脑,她虽然不能给我的电脑重装系统,但是它可以选择跟其他人借用有 win10 系统的电脑。这就是常量指针,对应的还有一种指针常量,往下看。


指针常量:


int number = 666;int * const p = &number;// 千万不要写出 const * int p,这是错误的写法。// 指针常量指向的地址不能改变,但是地址中保存的数值是可以改变的。*p = 6; // 可以int number2 = 6;p = &number2; // 不可以
复制代码

除了以上两种,还有一种结合了上面两种,叫做指向常量的长指针。


int number = 666;const int * const p = &number;// p既不能改变指向地址,也不能改变值,这个属于它们三个中的大哥。
复制代码


还有就是如果给函数的返回值修饰了 const,则接收返回值的变量类型也必须同样被 const 修饰。


----


3. 通用字符名

长话短说,如果要表示中文,显然一个字节是不够的,至少需要两个字节,而且还不能和 ASCII 编码冲突,所以,中国制定了 GB2312 编码,用来把中文编进去,类似的,日文和韩文等其他语言也有这个问题。为了统一所有文字的编码,Unicode 应运而生。Unicode 把所有语言都统一到一套编码里,这样就不会再有乱码问题了。。Unicode 通常用两个字节表示一个字符,原有的英文编码从单字节变成双字节,只需要把高字节全部填为 0 就可以。想要深入了解请单击


通用字符名类似于转义字符,使用\u 和\U 打头,\u 然后跟一个八进制,\U 后面跟的是十六进制,可以这样用:


int k\u0025d;// 这样定义变量名cout << "\u0025";             // 打印该字符
复制代码

这样就可以在控制台打印出我们想要字符,比如各种图案。但是前提是要支持通用字符名,如果不支持,就会提示

一般黑框框是显示不了特殊字符的,给大家找到一个中文转 unicode 的网站:中文字符与Unicode字符相互转换

当使用\u6211 打印出来的便是我:


----


4. char 的符号问题

char 的有无符号和 int 不太一样,它比较独特,char 在默认情况下不像 int 那样,默认既不是 unsigned char 也不是 signed char,是否有符号由 C++决定,在我的编译器上可能是有符号类型的,你的终端可能是无符号类型,如果你不确定 char,则应该尽可能的显式去声明是 nusigned 还是 signed,如果你只是存储 ASCII 字符,则无关 char 是什么类型,它都可以保存。


----


5. bool

ANSI/ISO C++标准添加了一种名叫 bool 的新类型,它只占一个字节,只保存 true 和 false 这个已经宏定义好的字面值,只有假和真两种表现方式,有些人一听到真假就想到 01,一想到 01 就认为该类型的变量只能保存 0 或 1,其实这种理解是不对的,该变量只保存 true 和 false 这两个值,并不是保存 0 和 1,除了 0 被替换为 false 之外,所有的数字,1,5,8 等等都会被替换为 true,包括负数,同样反过来,将 bool 类型的变量赋值给 int 类型的变量,只会出现 0 和 1 这两个值。


bool b1 = true // 正确bool b2 = 4; //正确,但4会被替换为1int a = b2; // a的值为1,而不是4,也不是true
复制代码




6. 运算符的优先级和结合性

简单来说先考虑优先级,再考虑结合性。

当两个运算符的优先级是一样的话,要使用结合性进行判断:

例如:

int a = 10*5/6;//由于/ 和*的优先级是一样的,这时候就应该用结合性判断是从左往右算,还是从右往左算。
复制代码








发布于: 2021 年 03 月 06 日阅读数: 11
用户头像

花狗Fdog

关注

还未添加个人签名 2021.02.06 加入

还未添加个人简介

评论

发布
暂无评论
萌新不看会后悔的C++基本类型总结(二)