C++标准并没有定义signed类型如何用位来表示,编译器通常用其中一位作为符号位来表示。 对于unsigned 整型(unsigned char,unsigned short int, unsigned int, unsigned long int),编译器会将越界值对2^n取模(n为该类型的位数)使其满足大小要求。因此,unsigned整型在计算时不会发生溢出。例如:(假设char类型为8位,2^8 = 256) unsigned char ch = 300; 等价于 unsigned char ch = 44 (300 mod 256) unsigned char ch = -1; 等价于 unsigned char ch = 255 (-1 mod 256)
而对于越界的signed类型赋值的情形,标准没有明确说明,也就是未定义行为。很多编译器采用与unsigned类型一样的处理方式。如果一个字面值不能够被它所有可能类型所表示,那么将产生未定义行为。
字符串字面值(string literal) 形如"..."或者L"..."的字符串。 不是以L开头的字符串字面值,叫作平凡字符串字面值(ordinary string literal),也叫作窄字符串字面值(narrow string literal)。对于平凡字符串字面值,其类型是const char[num],静态存储区,并用所给字符串初始化。 以L开头的字符串字面值,例如:L"foo",是宽字符串字面值。它的类型是const wchar_t[num],静态存储区,并用所给字符串初始化。 (注意上面的num值为所给字符串中字符个数 + 1) 所有字符串字面值的存储是否是不重叠的,这个问题是由实现定义的(implementation-defined)。试图去修改字符串字面值的行为所产生的结果是未定义的。 在编译时,相邻的窄字符串字面值被连接成一个窄字符串字面值,相邻的宽字符串字面值也被连接成一个宽字符串字面值。如果一个窄字符串字面值和一个宽字符串字面值相邻,其结果是未定义了。extern int var = 6; //definition (只有当extern 声明位于函数外部时,才可以含有初始化表达式)
const限定符 在全局作用域内声明的const变量为内部连接属性,即是文件域变量,所以可以把const变量定义放在头文件中(如果这样做,那么在每个包含该头文件中的文件中都会有一个该变量的定义,这样可能造成存储空间的大量浪费。事实上,当const变量是用常量表达式初始化时,大部分编译器在编译时都会用相应的常量表达式替换这些const变量的任何使用。也就不会有空间用于这类const变量的存储)。 可以指定const变量为extern,从而使其变成外部连接属性,可以在整个程序中访问const对象(需要在定义和使用处都用extern声明)。如果定义了一个extern const变量,那么在其它文件中就不能再在全局域定义该变量(一个例外是,可以定义一个内部连接属性的const变量)。例如:// file1.cppextern const int var = 6; // file2.cppextern const int var; //legal: refer to the var in file1// file3.cppconst int var = 9; //legal: internal linkage, only used in this file// file4.cppextern const int var = 2; //illegal: redefinion of var (already defined in file1)// file5.cppint var; //illegal: redefinion of var (already defined in file1)
非const引用只能绑定到与该引用同类型的对象;const引用则可以绑定到不同但相关的类型(该类型能够转换到引用的类型)的对象、甚至绑定到右值。例如:int var = 6;//int& r = 9; // error!const int& r1 = 9; // okconst int& r2 = var + r1; // ok
为什么const引用则可以绑定到不同但相关的类型的对象、甚至绑定到右值呢? 因为如果是绑定到不同类型的对象或右值,会先生成一个与引用类型相同的临时对象(必要时进行类型转换),然后引用变量再与该临时对象绑定。由于临时对象是右值,所以只能进行const引用。 另外,还可以从另一个角度来解释,先看下面的例子:double var = 2.718;const int& r = var;
上面的代码等价于:double var = 2.718;int tmp = var;const int& r = tmp;
如果r不是const引用,那么可以修改r的值。这样做,事实上是修改了临时变量tmp的值,而与程序员试图修改var的值的意愿完全偏离。这种错误是很难察觉的。而const引用不能修改,就完全避免了这种错误的发生。