首页 > 代码库 > C++查缺补漏之变量和基本类型
C++查缺补漏之变量和基本类型
基本内置类型
1.块处理存储
一般来说计算机以位序列存储数据,每一位存储0或1,一段内存可能存储着0001010010101010...但是这样的存储是没有任何意义的,让存储器具有结构的方法是块处理存储,那么什么是快处理存储呢,就是用2^n表示一个存储块的位数(一般以8位作为一个块),这样操作起来更加方便。
如下图:
123456 | 01110001 |
123457 | 10101001 |
123458 | 10100100 |
比如123456这个块如果是整形类型的(当然int需要占用四个字节)那么表示的就是112,如果表示的是ISO-Latin-1的一个字符,那么就表示小写字母q
下面来看一个例子:
#include <iostream> #include <iomanip> #include <stdio.h> using namespace std; int main(int argc, char const *argv[]) { unsigned int number = 16843009;//二进制为<span style="font-family: 'Comic Sans MS';">00000001</span><span style="font-family: 'Comic Sans MS';">00000001</span><span style="font-family: 'Comic Sans MS';">00000001</span><span style="font-family: 'Comic Sans MS';">00000001</span><span style="font-family: 'Comic Sans MS';"> </span> unsigned int * pNumber = &number; cout<<reinterpret_cast<int>(pNumber)<<endl;//打印指针地址 cout<<*pNumber<<endl;//unsigned类型时的值 unsigned char * ptrChar = reinterpret_cast<unsigned char *>(pNumber);//unsigned int * 转为 unsigned char * cout<<static_cast<int>(*ptrChar)<<endl;//unsigned char类型以int类型输出 ptrChar++; cout<<static_cast<int>(*ptrChar)<<endl; ptrChar++; cout<<static_cast<int>(*ptrChar)<<endl; ptrChar++; cout<<static_cast<int>(*ptrChar)<<endl; while(1); return 0; }最后输出结果为:
观察之前我们的那个整形number,不正是由四块值为00000001组成的么,只是解释为unsigned int 类型时为16843009,解释为unsigned char 类型时为1.
2.除了bool类型的整形才可以是unsigned 或者是signed ,如果在只写unsigned 不加上具体类型,那么就是unsigned int类型的 。
3.特殊的char类型
与其他整形不同,char类型有三种不同的类型:char , unsigned char , signed char。但是只有两种表示形式unsigned char 或者signed char。这句话是什么意思呢?我们知道(int,short,long)类型默认都是signed类型的,但是char类型时没有默认类型的,具体是signed还是unsigned类型,还要由编译器而定。要想确定编译器默认是signed还是unsigned,可以
char ch =-1; printf("%d\n",ch);如果打印的是-1,那么表明是signed类型的
若是255,那么表明是unsigned类型的
我在gcc上面测试以后发现是signed类型的,所以在编写char类型的时候最好还是加上signed或者unsigned吧,不然又会多了一些莫名奇妙的错误。
4.浮点型
都知道float表示的浮点型使用一个字来表示,且精度是单精度,只有6位有效数字
double类型占用两个字节,精度为双精度,至少保证了10位的精度
这里的精度到底是什么意思呢?我们来看一下float和double内部到底是如何存储的:
类型float大小为4字节,即32位,内存中的存储方式如下:
符号位(1 bit) | 指数(8 bit) | 尾数(23 bit) |
类型double大小为8字节,即64位,内存布局如下:
符号位(1bit) | 指数(11 bit) | 尾数(52 bit) |
对于float类型来书8位的指数取值范围为:-2^7~2^7+1(-127~128)
double类型11位指数取值范围为-2^10~2^10+1(-1024~1025)
指数的含义是什么呢?
- 负指数代表着浮点数能表示的绝对值最小的数
- 正指数表示了浮点数能表示绝对值最大的数
float的范围为-2^128 ~ +2^128,也即-3.40E+38 ~ +3.40E+38;double的范围为-2^1024 ~ +2^1024,也即-1.79E+308 ~ +1.79E+308
接着我们来看一下尾数:
- float类型的尾数为2^23(8388608),长度为7为,但是又不满七位
- double类型尾数为2^52(4503599627370496),长度为16,但是又不满16
所以所谓的精度就是这里的尾数所能表示的数的长度
下面我们来看一个例子:
#include <iostream> #include <iomanip> #include <stdio.h> using namespace std; int main(int argc, char const *argv[]) { float f1 = 1.123456789123456789; double d1 = 1.123456789123456789; cout<<setprecision(20)<<"float:"<<f1<<endl; cout<<setprecision(20)<<"double:"<<d1<<endl; while(1); return 0; }可得到输出结果为:
我们可以明显的看到float从第7位(为什么不是第六位呢?因为8388608)有效数字开始就开始不准确了
double类型也就只显示了前16位,后面的都被截断了。所以以后再具体应用中需要辨别他们之间的区别,float的精度损失是不可忽视的,使用double类型基本上是不会出错的,双精度的计算代价相对于单精度乐意忽略,在某些机器上double类型比float类型要快得多(可能是硬件上做了优化了吧)。但是long double一般来说是没有必要的。。。
最后说一点,上面我们看到了浮点类型的结构,里面有一位固定符号位,所以浮点类型是没有unsigned的!!!
C++查缺补漏之变量和基本类型
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。