建站网站公司调查,图书馆网站建设目标,怎么样创建做零食山楂的网站,做音乐头像网站文章目录一、C11简介二、列表初始化三、简化声明四、nullptr与范围for五、STL中一些变化一、C11简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)#xff0c;使得C03这个名字已经取代了C98称为C11之前的最新C标准名称。不过由于TC1主要是对C98标准中的漏洞进行修复…
文章目录一、C11简介二、列表初始化三、简化声明四、nullptr与范围for五、STL中一些变化一、C11简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)使得C03这个名字已经取代了C98称为C11之前的最新C标准名称。不过由于TC1主要是对C98标准中的漏洞进行修复语言的核心部分则没有改动因此人们习惯性的把两个标准合并称为C98/03标准。从C0x到C11C标准10年磨一剑第二个真正意义上的标准珊珊来迟。相比于C98/03C11则带来了数量可观的变化其中包含了约140个新特性以及对C03标准中约600个缺陷的修正这使得C11更像是从C98/03中孕育出的一种新语言。相比较而言C**11能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全不仅功能更强大而且能提升程序员的开发效率** 二、列表初始化
C98中标准允许使用花括号{}对数组元素进行统一的列表初始值设定。举个例子
struct Point
{int _x;int _y;
};
int main()
{Point p1 { 1,2 };int array1[] { 1,2,3,4,5 };int array2[5] { 0 };return 0;
}C11扩大了用大括号括起的列表(初始化列表)的使用范围使其可用于所有的内置类型和用户自定义的类型使用初始化列表时可添加等号()也可不添加
struct Point
{int _x;int _y;
};
int main()
{Point p1 { 1,2 };int array1[] { 1,2,3,4,5 };//去掉赋值符号Point p2{ 2,2 };int array2[]{ 1,2,3,4,5 };//更加离谱int x1 1;int x2 { 1 };int x3{ 1 };return 0;
}new 表达式初始化时一定不能添加等号
int* p3 new int[10];int* p4 new int[10]{ 1,2,3,4 };
Point* p5 new Point[2]{ {1,1},{2,2} };日期类构造函数初始化
class Date
{
public:Date(int year, int month, int day):_year(year), _month(month), _day(day){cout Date(int year,int month,int day) endl;}
private:int _year;int _month;int _day;
};
int main()
{Date d1(1, 1, 1);//构造函数Date d2{ 1,1,1 };return 0;
}对于上面这些都是比较轻松的更多的在于容器的初始化
int main()
{vectorint v { 1,2,3,4,5,6,7,8};vectorint v1 { 1,2,3,4 };listint lt { 1,2 };listint lt1 { 1,2,3,4,5,6,7 };return 0;
}vector和list为什么可以这样子初始化这就要说到一个新的容器了initializer_list
initializer_list 是一个容器是 C11 新增的
只提供了 begin 和 end 函数用于迭代器遍历以及获取容器中的元素个数的 size 函数 {}的本质就是initializer_list如果我们使用auto来定义一个变量去接收一个大括号括起来的列表然后用 typeid(变量名).name() 查看变量的类型此时会发现该变量的类型就是 initializer_list 这个东西到底有什么用C98 不支持直接用列表对容器进行初始化这种初始化方式是在C11引入initializer_list后才支持的而这些容器之所以支持使用列表进行初始化是因为C11提供了一个构造函数以initializer_list为参数
看一下C11vector的构造 当用列表对容器进行初始化时会被认为是initializer_list类型此时不管有多少个值都能够被初始化vector。而我们之前自己实现的vector是无法支持的现在我们可以为之前自己模拟实现的vector提供一个构造函数遍历initializer_list 中的元素然后push_back进要初始化的容器当中
vector(initializer_listT il):_start(nullptr), _finish(nullptr), _endofstorage(nullptr)
{typename initializer_listT::iterator it il.begin();while (it ! il.end()){push_back(*it);it;}
}三、简化声明
C11提供了多种简化声明的方式。
1.auto
auto使用的前提是必须要对auto声明的类型进行初始化否则编译器无法推导出auto的实际类型。
如果类型过长比如迭代器的名称我们就可以使用auto用于实现自动类型推断
int main()
{int x 0;auto y x;cout typeid(x).name() endl;cout typeid(y).name() endl;return 0;
}typeid只能查看类型不能用其结果类定义类型
2.decltype
decltype是根据表达式的实际类型推演出定义变量时所用的类型
templateclass T1, class T2
void F(T1 t1, T2 t2)
{decltype(t1 * t2) ret t1 * t2;cout typeid(ret).name() endl;cout ret endl;
}int main()
{int x 0;decltype(x) y;cout typeid(y).name() endl;F(1, 2.2);
}typeid(变量名).name()的方式只能获取一个变量的类型但无法获取这个类型去定义变量。而decltype除了能够推演表达式的类型还能推演函数返回值的类型。 四、nullptr与范围for
nullptr
nullptr:由于C中NULL被定义成字面量0这样就可能会带来一些问题因为0是既能表示指针常量又能表示整型常量所以出于清晰和安全的角度考虑C11中新增了nullptr用于表示空指针
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif /* NULL */范围for
C11中还有范围for范围for循环后的括号由冒号分为两部分第一部分是范围内用于迭代的变量第二部分则表示被迭代的范围
int main()
{vectorint v { 1,2,3,4,5,6 };for (auto e : v){cout e ;}cout endl;return 0;
}范围for本质上是由迭代器支持的在代码编译的时候编译器会自动将范围for替换为迭代器的形式 五、STL中一些变化
C11中新增了容器分别是array、forward_list、unordered_map和unordered_set array
array是一个静态数组即固定大小的数组没有资格与vector对比
array有两个模板参数第一个模板参数代表的是存储的类型第二个模板参数是一个非类型模板参数代表数组中存储元素个数
int main()
{arrayint,10 a1;int a2[10];a2[11];//没报错return 0;
}array与普通数组的对比 C语言数组对于越界检查是抽查的越界可能检查不出来但是对于array的越界读写都能检查出来的 因为array用一个类对数组做了封装并且在访问array容器中的元素时会进行越界检查用[]访问元素时采用断言调用at成员函数访问元素时采用抛出异常检查。 当然vector也可以检查出越界的情况而且array没有初始化并且与其他容器不同的是array容器的对象是创建在栈上的因此array容器不适合定义太大的数组不如vector
forward_list容器 forward_list容器本质就是一个单链表很少使用 forward_list只提供了头插头删不支持尾插尾删因为单链表在进行尾插尾删时需要先找尾 forward_list提供插入insert_after在指定的元素后面插入一个元素而不像其他容器是在指定的元素前面插入一个元素单链表要找到指定元素前一个元素就要重新遍历一遍删除也是erase_after也就是删除指定元素后的一个。 所以我们一般还是使用list容器
C11新的接口
C11给容器都增加了一些新的接口 最开始说的提供了一个以initializer_list作为参数的构造函数用于支持列表初始化 比较鸡肋的接口cbegin 、cend系列以及缩容接口shrink_to_fit(异地) 比较有用 移动构造和移动赋值 emplace_xxx插入接口 本篇结束…