#1. 引言html
数据类型是程序的基础,决定了编译器以及运行时的各项操做解释。在编译时不一样的变量应该分配多大的空间?在运行时对指针进行+1操做,指针应该跳几个字节?在类型明确的状况下,上述操做都有据可循,不会有歧义。C / C++ / JAVA / C#等语言都明肯定义了数据类型。我我的也是比较偏向于喜欢使用该类编程语言。编程
本章主要讲述C++的自定义的内置类型,同时对类型描述const用法作一些总结。数组
#2. 原始内置类型 原始内置类型,书中原文为Primitive Built-in Types,具体又分为两种 arithmetic types & void arithmetic types : 算术类型 bool, char,int, short, long,float,double等类型 void: 理解为空类型,对于没有返回的函数,经常将返回值写为void.服务器
对于char, short, int,long,long long类型,都是带符号的整数类型数据,只是能够表示的数据范围不一样,对应的数据长度也不一样。下面是我在64为服务器上运行的测试程序,能够看到各种型数据的长度以及能够表示的数据范围也不同。我编写了一个很简单的测试程序,测试不一样数据类型的数据长度以及对于整数,能够表示的数据范围。app
void typeSizeTest() { std::cout << "char size is: " << sizeof(char) << std::endl; std::cout << "int size is: " << sizeof(int) << std::endl; std::cout << "short size is: " << sizeof(short) << std::endl; std::cout << "long int size is: " << sizeof(long int) << std::endl; std::cout << "long size is: " << sizeof(long) << std::endl; std::cout << "long long size is: " << sizeof(long long) << std::endl; std::cout << "float size is: " << sizeof(float) << std::endl; std::cout << "double size is: " << sizeof(double) << std::endl; char maxChar = 0x7F, minChar = 0x80; printf("max char: %d, min Char: %d\n", maxChar, minChar); short maxShort = 0x7FFF, minShort = 0x8000; std::cout << "max Short: " << maxShort << " min Short: " << minShort << std::endl; int maxInt = 0x7FFFFFFF, minInt = 0x80000000; std::cout << "max Int: " << maxInt << " min Int: " << minInt << std::endl; long long maxLongLong = 0x7FFFFFFFFFFFFFFF, minLongLong = 0x8000000000000000; std::cout << "max LongLong: " << maxLongLong << " min LongLong: " << minLongLong << std::endl; }
char size is: 1 int size is: 4 short size is: 2 long int size is: 4 long size is: 4 long long size is: 8 float size is: 4 double size is: 8 max char: 127, min Char: -128 max Short: 32767 min Short: -32768 max Int: 2147483647 min Int: -2147483648 max LongLong: 9223372036854775807 min LongLong: -9223372036854775808
最大值符号位为0,其余全1
最小值符号位为1,其余全0编程语言
对于有符号的整数类型表达的范围,此处csapp书中给出了很是好的解释。 在40页中有一个公式描述了补码下的数据表示公式。函数
能够看出,若是是正数,那么w-1位为0,其余位全1便可。 若是是负数想要最小,w-1位为1, 其余位为0,就能够对于的数值最小。 经过这个公式看简介明了。测试
float和double类型对应的数据位数以及精度不同。在个人测试机器中,float占据4字节,double占据8字节。阮一峰在他的博客中对浮点数在计算机中的存储方式作了一个很是详细的说明,简单易懂,连接以下。 http://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.htmlui
在C++中须要注意类型转换的问题,其中可能会致使一些数据精度的损失以及可表示范围的变化。根据业务判断相关变量的可能范围,选择合适的类型。指针
const是一个限定符,常常用来描述不但愿被改变的变量。主要有以下几种用法:
这里用来修饰一个普通变量,好比数组长度,任务数量等等,该变量一旦初始化后就不能改变。以下代码就是一个示例。
const int bufSize = 256; int buf[bufSize]; for (int k = 0; k < bufSize; k++) { buf[k] = k; }
默认状况下,const对象的做用域在文件内,若是须要跨文件使用,经过 extern关键字进行描述,达到跨文件使用的效果。
这种用法比较符合常规思惟,引用的类型和要引用的对象类型要匹配
const int a = 5; const int &b = a;
int c = 5; const int &d = c;
用一个常量引用去引用一个普通变量是能够的,可是咱们没法经过这个引用去修改这个变量。
double a = 3.14; double * const b = &a; *b = 5;
该代码说明指针b一直指向a,不能够从新指向其余对象。但能够经过指针修改a的内容
const double a = 3.14; const double *b = &a; const double c = 5; b = &c;
这里指针指向谁能够修改,可是你不能够修改指针指向对象的内容。
const double a = 3.14; const double* const b = &a;
这种状况下既不可让b指向其余对象,也不能够经过b修改a的内容。双重约束。
const int c = 5; int& d = c * 2; 错误信息: initial value of reference to none const must be an lvalue
这里涉及到lvalue(左值), rvalue(右值)的问题,先搞明白这个概念再分析上面这个错误。每个C++表达式,要么是左值,要么是右值,左值能够理解为有名字的对象,好比说咱们本身定义的变量;右值能够理解为是临时对象; 那么上面例子中c*2其实结果只是一个临时变量,是右值。可是编译器认为很是量引用要对应一个左值。匹配不上,因此报错。
能够进一步解释,上述代码能够这么写:
const int c = 5; int temp = c * 2; int& d = temp; ``` temp只是一个临时变量,若是d不是常量引用,说明咱们能够经过d去修改临时变量? 这种行为在C++中是非法的。 ``` // 下面是MSDN关于左值右值的示例。 int main() { int i, j, *p; //属于定义好的变量,有名称,为左值; // 正确, i 为左值. i = 7; //错误: The left operand must be an lvalue (C2106). 7 = i; // C2106 j * 4 = 7; // C2106 // 正确: the dereferenced pointer is an lvalue. *p = i; const int ci = 7; //正确 // 错误: the variable is a non-modifiable lvalue (C3892). ci = 9; // C3892 // 正确: the conditional operator returns an lvalue. ((i < 3) ? i : j) = 7; } ``` [MSDN lvalue, rvalue解释](https://msdn.microsoft.com/en-us/library/f90831hc.aspx)