处理类型

来源:互联网 发布:南大女生碎尸案 知乎 编辑:程序博客网 时间:2024/04/30 12:28
如何选择类型?
1.当明确知晓数值不可能为负时,选用无符号类型。
2.整数计算选用short - int - long long,因为通常int和long有相同的尺寸。
3.算术表达式中不要使用char和bool。因为char在一些机器上是有符号的,而在另一些机器上是无符号的。
4.执行浮点运算使用double。因为float通常精度不够,而且单精度和双精度在计算代价上相差无几,甚至有些机器上双精度反而更快。long double提供的精度在一般情况下是没有必要的。

切勿混用带符号整数和无符号整数!
当混用时,带符号整数会自动转化成无符号整数。如:
unsigned u = 10;int i = -42;std::cout << i + i << std::endll; //输出-84std::cout << u + i << std::endl; //如果int占32位,输出4294967264

字面值常量
int a = 20; //十进制int b = 020; //八进制int c = 0x20; //十六进制

区别字符与字符串
sizeof('A') = 0,而sizeof("A") = 2,sizeof("Hello") = 6,这是因为在字符串末尾,编译器添加了一个空字符('\0')。

转义字符
\n  换行符
\t  制表符
\a  响铃符
\v  纵向制表符
\b  退格符
\"  双引号
\\  反斜线
\?  问号
\'  单引号
\r  回车符
\f  进纸符

指定字面值类型
前缀:
u:Unicode16字符char16_t
U:Unicode32字符char32_t
L:宽字符wchar_t
u8:UTF-8(仅用于字符串字面常量)
整型字面值后缀
u or U:unsigned
l or L:long
ll or LL:long long
浮点型字面值后缀
f or F:float
l or L:long double
L'A'  //宽字符字面值,类型是wchar_t,‘A’输出A,L‘A‘输出65
u8"hi!"  //utf-8字符串字面值(uft-8用8位编码一个Unicode字符)
42ULL  //unsigned long long
1E-3F  //float
3.14159L   //long double

注意:初始化不是赋值!
初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦除,而以一个新值来替代。

变量只能被定义一次,但可以被多次声明。
如果要在多个文件里使用同一变量,就必须将声明和定义分离(分离式编译)。此时,变量的定义必须出现在且只能出现在一个文件中,而其他用到该变量的文件必须对其进行声明,却绝不能重复定义!

引用类型
引用类型的初始值必须是一个对象,不能是字面值常量
int &ref = 10; //错误
且所有引用类型都要和与之绑定的对象严格匹配
double dval = 3.14;int &refVal = dval; //错误
两个例外情况:
1.初始化常量引用可以使用任意表达式作为其初始值,只要该表达式的结果能转换成引用的类型即可。特别的,允许一个const引用绑定一个非常量对象、字面值、甚至一般表达式
int i = 42;const int &r1 = i; //正确,绑定对象const int &r2 = 42; //正确,绑定字面值常量const int &r3 = r1 * 2; //正确,绑定表达式int &r4 = r1 * 2; //错误,非常量引用不能绑定常量引用
2.基类指针或引用可以绑定到派生类对象上。当使用基类的指针或引用时,我们并不知道该指针或指针指向的真实类型,可能是基类,也可能是其派生类。
Fu &fu = zi;

引用的实质就是常量指针!
区别:1.指针本身是个对象,允许拷贝和赋值,生命周期内可以指向不同对象,引用不是个对象 2.指针无需再定义时赋初值。

空指针:字面值nullptr

void*指针:
void *pv = &obj; //obj可以是任意类型的对象pv = pd; //pv可以存放任意类型的指针
但是不能直接操作void*指针所指的对象,因为我们并不知道这个对象到底是什么类型,也就无法确定能在这个对象上做哪些操作。

不能定义指向引用的指针,因为引用不是个对象,但是可以定义对指针的引用(引用必须办法绑定一个对象)
int i = 42;int *p;int *&r = p; //r是一个对指针p的引用r = &i; //r引用了一个指针,因此给r赋值&i就是令p指向i*r = 0; //r指向i,将i改为0

别名
typedef double wages; //wages是double的同义词typedef wages base, *p; //base是double的同义词,p是double*的同义词using SI = Sales_item; //SI是Sales_item的同义词

难点:
typedef char *pstring; //pstring是char*的别名const pstring cstr = 0; //cstr是指向char的常量指针(注意区别常量指针和指向常量的指针)
这里的基本数据类型是pstring,即指针,如果机械地套用替换,将之变为:
const char *cstr = 0;//是对const pstring cstr的错误理解
这样改写之后基本数据类型变为char,*成为了声明符的一部分。
正确的理解方式:pstring是个指针,所以const pstring就是个常量指针,就这么简单!

decltype类型提示符:编译器分析表达式并得到它的类型,却不实际计算表达式的值
decltype与const:
decltype(f()) sum = x; //sum的类型就是函数f的返回类型,编译器并不实际调用fconst int ci = 0, &cj = ci;decltype(ci) x = 0; //x的类型是const intdecltype(cj) y = x; //y的类型是const int&decltype(cj) z; //错误,z是一个引用,必须初始化
decltype与引用:
int i = 42, *p = &i, &r = i;decltype(r) x = i; // x是引用类型decltype(r+0) b; //正确,加法的结果是int,所以b是int,未初始化decltype(*p) c; //错误,c是int&,未初始化
注意:如果表达式是解引用操作,则decltype将得到引用类型
另外,decltype的表达式如果是加上了括号的变量,结果是引用
decltype((i)) d; //错误,d是int&,必须初始化decltype(i) e; //正确,e是一个未初始化的int






0 0