C++使用过程中容易忽略的小细节

来源:互联网 发布:紫砂壶开壶 知乎 编辑:程序博客网 时间:2024/06/03 17:01

说明:此篇文献是读者在阅读《c++primer plus》中抓取的容易忽略的小知识点,如有不当之处,敬请指正。
1、运算符sizeof
可对类型名和变量名使用sizeof运算符。对类型名如(如int)使用sizeof运算符时,应将名称放到括号中;但是对于变量名(int a;中的a)使用该运算符时,括号时可选的(可有,亦可无)。
2.如果知道变量的初始值应该是什么,则应该对它进行初始化,将变量声明和赋值分开,可能会带来瞬间选额未决的问题。
3.使用cout<<(dec,hex,oct)可以更改更改显示整数的方式,并且默认的格式为十进制,在修改格式之前,原来的格式将一直有效。
4.与int不同的是,char在默认的情况下既不是没有符号,也不是有符号。是否有符号由c++实现决定,这样编译器的开发人员可以最大限度的将这种类型与硬件属性匹配起来。如果char有某种特定的行为对您来说十分重要,则可以显示的将类型设置为signed char unsigned char.
6.wchar_t 宽字符类型
wchar_t数据类型一般为16位或32位,但不同的C或C++库有不同的规定,如GNU Libc规定wchar_t为32位,总之,wchar_t所能表示的字符数远超char型。
宽字符类型可以表示扩展的字符集。iostream头文件提供 wcin和wcout,可用于处理wchar_t流。另外可以通过加上前缀L来指示宽字符常量和宽字符串。
wchar_t bob=L’p’;
wcout<< L”tall”<< endl;
在支持两字节wchar_t的系统中,上述代码将把每个字符存储在一个两字节的内存单元中。
7.C++ 新增数据类型 char16_t char32_t
前者是无符号的,长16位,后者也是无符号的,长32位,用前缀u表示char16_t的字符常量和字符串常量,用前缀U表示char32_t的字符常量和字符串常量。
char16_t ch1=u’q’;
char32_t ch2=U’m’;
8.bool
字面值true和false都可以通过提升转换为int型,true被转换为1,false被转换为0.
另外,任何数字值和指针值都可以被隐式转换为bool值,任何非零值被转换为true,而零值被转换为false。
9.通常cout会删除结尾的0。例如:将333333.250000显示为333333.25.
调用cout.setf()将覆盖这种行为,至少会在新的实现中这样。float至少6位有效位,而double有效位是15位。在默认情况下,浮点常量都属于double类型,若是希望使用float类型,请使用f或者F后缀。
10.除法运算符的行为取决于操作数的类型,如果两个操作数都是整数,则C++将执行整数除法,这就意味着结果的小数部分被丢弃。如果其中有一个或两个操作数是浮点值,则小数部分被保留,结果为浮点数。
11.C++将使用大括号{}的初始化称之为列表初始化,以为这种初始化常用于给复杂的数据类型提供值列表。但是它对类型转换的要求更严格。列表初始化不允许缩窄,即变量的类型可能无法表示赋给他的值。
12.如果一个操作数是有符号的,另一个操作数是无符号的,且无符号操作数的级别比有符号操作数的级别高,则将有符号的操作数转换为无符号的操作数所属的类型。

13.cin是如何确定已完成字符串的输入的
由于不能通过键盘输入空字符,因此cin需要用别的方法来确定字符串的结尾位置。cin使用空白(空格、制表符和换行符)来确定字符串的结尾位置,这意味着cin在获取字符数组的输入时只读取一个单词。读取该单词后cin将字符串放到数组中,并自动在结尾处添加空字符。并将剩下的单词留在缓存列表中,以备下次继续读取。

14.cin.getline()函数每次读取一行,他通过换行符来确定结尾,但是不保存换行符。相反,在存储字符串时,它用空字符来替换换行符。
cin.get()函数与cin.getline()函数几乎相同,但是get()函数并不在读取并丢弃换行符,而是将其留在输入队列中。
cin与cin.get()类似,只是cin输入的是单词,同样会将换行符留在输入队列中。
getline(cin,str) 该语句是将一行输入读取到string对象中的代码。特别注意,这里的getline()不是类方法。它将cin作为参数,指出到哪里去查找输入。另外也没有指出字符串长度的参数,因为string类对象将根据字符串的长度自动调和增自己的大小。
15.C++11中新增的另一种类型是原始字符串 。在原始字符串中,字符表示的就是自己。例如序列\n不表示换行符,而表示两个常规字符–斜杠和n,因此在屏幕上显示时,将显示这两个字符。另一个例子是,可在字符串中使用“,而无需使用繁琐的\”。当然既然可在字符串字面量包含”,就不能在使用它来表示字符串的开头和结尾。因此原始字符串将使用“(和)”用作定界符,并使用前缀R来标识原始字符串:
cout<< R”(Jim”King”Tutt uses “\n” instead of endl.)” << ‘\n’;
上述代码将显示如下:
Jim”King”Tutt uses “\n” instead of endl.、
如果想在原始字符串中包含“( ,那么使用R”+* (标识原始字符串的开头时,必须使用)+*”标识原始字符串的结尾。
cout<< R”+* (“(who wouldn’t?)”,she whisperad.)+*” << endl;
将显示的内容如下:
“(who wouldn’t?)”,she whisperad.

16.对于枚举,只定义了赋值运算符,没有定义算数运算

17.枚举的取值范围
取值范围定义如下:首先,要找出上限,需要知道枚举量的最大值,找到大于这个最大值的,最小的2的幂,将它减去1,得到的便是取值范围的上限。要计算下限,需要知道枚举量的最小值。如果它不小于0,则取值范围的下限为0;否则再去与寻找上限方式相同的方式,只不过加上负号。

18.数组没有副本机制。

19.对于给定的函数名,可以有非模板函数、模板函数和显示具体化模板函数以及他们的重载版本。
具体化优先于常规模板,而非模板函数优先于具体化和常规模板。

20.派生类和基类之间的特殊关系。
1.派生类对象可以使用基类对象的方法,条件是方法不是私有的。
2.基类指针可以在不进行显示转换的情况下指向派生类对象,基类引用可以在不进行显示转换的情况下引用派生类对象。然而,基类指针或者引用只能调用基类的方法,而不能调用派生类的方法。(指针或者引用的类型决定了作用范围和解析方式)
通常C++要求引用和指针的类型与赋给得类型匹配,但是这一规则对于继承来说是个例外。然而这种例外是单向的,不可以将基类对象和地址赋给派生类引用和指针。

21.如果要在派生类中重新定义基类的方法,通常应该将基类方法声明为虚的。这样,程序将根据对象类型而不是指针或者引用类型来选择方法版本。为基类声明一个虚析构函数也是一种惯例。
关键字virtual只用于类声明的方法原型中,而一般不用于方法的定义中。