c++98和c++11的区别,c++98标准共715页,c++11标准共1336页
红色代表本标准与C89标准的区别
1、词汇约定
黄色指与C89标准(注:不是C++标准)的区别
1.1、字符集
基本源字符集
基本源字符集比C89多了一个新行控制字符,C89中其属于执行字符集
通用字符名(universal-character-name)
提供了命名其他字符的方法。形式为 \u 四位十六进制数 、\U 八位十六进制数,前者对应 ISO/IEC 10646 代码为 0000四位十六进制数的字符,后者对应 ISO/IEC 10646 代码为 八位十六进制数的字符。用于链接器不支持拓展字符的系统上形成有效标识符。
ISO/IEC 10646
其定义的字符集称通用字符集(Universal Character Set, UCS),包含了已知语言的所有字符,采用了与 Unicode 相同的字库和字码(字符编码上等同Unicode)1。其范围不能在 0xD800–0xDFFF 内。而且如果通用字符名的十六进制值位于c-char序列、s-char序列或r-char序列之外,其范围不能在 0x00–0x1F 或 0x7F–0x9F 或基本源字符集范围 内
#include<bits/stdc++.h>
using namespace std;
int main(){
//int \u0041 = 100; //c-char序列、s-char序列或r-char序列之外,报错
int \u4f60 = 100; //正确
cout << \u4f60 << endl;
cout << '\u0041' << endl; //输出A
//cout << '\uD800'; //报错
return 0;
}
基本执行字符集、基本执行宽字符集
包括基本源字符集和表示警告、退格和回车的控制字符,加上一个空字符/空宽字符,每个基本执行字符集,成员的值应为非负且彼此不同。基本源、执行字符集中,上述十进制数字列表中 0 之后的每个字符的值应比前一个字符的值大 1。
执行字符集、执行宽字符集
执行字符集和执行宽字符集分别是基本执行字符集和基本执行宽字符集的实现定义的超集。执行字符集和附加成员集的成员值是地域特定的。
三联符序列
三联符序列与C89相同(c++17 中删除)
1.2、预处理单元
- 头文件名
- 标识符
- 预处理数字
- 字符字面值
- 自定义字符字面值
- 字符串字面值
- 自定义字符串字面值
- 预处理运算符或标点符号
- 不能为上述字符之一的每个非空白字符
- 限制与C89标准差不多
1.3、替换单元(Alternative tokens)
包括三联符序列,下面表格中又称双联符序列(digraphs)。为了让代码能通过非ASCII字符集编写,比如ISO 646,但是,ISO 646缺少这些字符,所以通过替换达到所求语义。
#include<bits/stdc++.h>
using namespace std;
int main()<%
cout << 666;
return 0;
%>
1.4、单元(tokens)
- 标识符
- 关键字
- 字面值
- 运算符
- 标点符号 == 其他分隔符
空格、水平和垂直制表符、换行符、换页和注释 ,统称为“空白”,除非他们用于分隔单元,否则将被忽略
1.5、注释(comments)
- /* 开始一个注释,*/终止
- //开始以个注释,新行字符终止
- //、/、/在//注释中没有特殊含义
- //、/*在 /*注释中没有特殊含义
1.6、头文件名(header names)
同C89
1.7、预处理数字(preprocessing numbers)
同C89
2、标识符
标识符是由非数字字符(包括下划线、大小写字母、通用字符名、其他实现定义的字符)及数字构成的序列,其第一个字符应是非数字字符,不同的标识符取决于有效字符的不同
约束
- 在标识符中的通用字符名需在E1范围内
- 在标识符中第一个元素的通用字符名需不在E2范围内
- override、final在某些上下文有特殊含义。当在语法中显式使用这些标识符,而不是使用标识符语法含义时,都会被解析为常规标识符。
- 一些被c++实现和标准库使用的标识符不应另作他用
- c++中任何标识符,大小写字母是不同的
3、关键字
以下73个单元被视为关键字,除非位于属性单元中
同时替换字符序列也是保留的
4、运算符与标点符号
包括预处理运算符标点符号和普通运算符标点符号,每个预处理运算符标点符号在翻译阶段7转换为单个单元
5、字面量(literals)
在C中称为常量(constants)
- 整数字面量
- 字符字面量
- 浮点字面量
- 字符串字面量
- 布尔字面量
- 指针字面量
- 自定义字面量
整数字面量
相比C89整数常量多了两个后缀:ll、LL。超出后缀表示范围会自动升格,若还不能表示则可能会使用拓展整数类型表示,若存在任何类型都不能表示的整数字面量则警告
#include<bits/stdc++.h>
using namespace std;
int main(){
cout << typeid(long long int).name() << endl;
cout << typeid(10000000000000l).name(); //此整数字面量是long long int
return 0;
}
字符字面量
相比C89字符常量多了两个前缀:u、U,字符选择多了通用字符名。
- 不以u、u或L开头的字符字面量是普通字符字面量,也称为窄字符字面量。
- 包含单个c字符的普通字符字面量具有char类型,其值等于执行字符集中c字符的编码。
- 包含多个c字符的普通字符字面量是多字符字面量,具有int类型和实现定义的值。
#include<bits/stdc++.h>
using namespace std;
int main(){
cout << typeid(char).name() << endl;
cout << typeid('abc').name() << endl;
cout << 'abc';//警告
}
浮点字面量
同C89
字符串字面量
#include<bits/stdc++.h>
using namespace std;
int main(){
cout << sizeof "\\666" << endl; //5每个字符1个字节
cout << sizeof u8"\\666"<<endl; //5每个字符1个字节
cout << sizeof u"\\666"<<endl; //10每个字符2个字节
cout << sizeof U"\\666"<<endl; //20每个字符4个字节
cout << sizeof L"\\666"<<endl; //10每个字符2个字节
cout << sizeof R"(\\666)"<<endl; //6 没有发生转义
return 0;
}
- 翻译阶段6相邻字符串字面值被连接起来
- 相同编码前缀,则合并后前缀为该前缀
- 若一个字符串字面值没有前缀,则合并后前缀为另一个字符串字面值前缀
- 如果UTF-8字符串字面量与宽字符串字面量相邻,则程序的格式不正确
- 现定义的行为有条件地支持任何其他连接
- 此连接是一种解释,而不是转换,因为解释发生在翻译阶段6
- 翻译阶段7 “\0”附加到每个字符串字面量,以便扫描字符串的程序可以找到其结尾
#include<bits/stdc++.h>
using namespace std;
int main(){
cout << "\\666" "55\n55" << endl;
cout << "\x66" "A"; //连接后保持原有语义,输出f和A
return 0;
}
布尔字面量
即两个关键字,这样的字面值是初值(prvalue)具有bool类型
- false
- true
指针字面量
关键字nullptr,是具有类型std::nullptr_t的初值(prvalue),可以转换为空指针值或空成员指针值
自定义字面量
由对应字面量加标识符组成。允许整数、浮点、字符和字符串字面量通过定义用户定义的后缀生成用户定义类型的对象。
- 用户定义的字面量被视为对字面量运算符或字面量运算符模板的调用
- 若同时匹配自定义字面量和其他字面量类型,则视为后者
https://zh.wikipedia.org/wiki/%E9%80%9A%E7%94%A8%E5%AD%97%E7%AC%A6%E9%9B%86 ↩︎