想自己做网站,wordpress中文函数手册,宜飞思工业设计网站,手机网站效果图做多大的目录 C11简介
统一的列表初始化
1.初始化范围扩展
2.禁止窄化转换#xff08;Narrowing Conversion#xff09;
3.解决“最令人烦恼的解析”#xff08;Most Vexing Parse#xff09;
4.动态数组初始化
5. 直接初始化返回值
总结
声明
1.auto 类型推导
2. declty…目录 C11简介
统一的列表初始化
1.初始化范围扩展
2.禁止窄化转换Narrowing Conversion
3.解决“最令人烦恼的解析”Most Vexing Parse
4.动态数组初始化
5. 直接初始化返回值
总结
声明
1.auto 类型推导
2. decltype 类型推导
3. 尾置返回类型Trailing Return Type
4. nullptr 关键字
5.using 别名声明
6.默认和删除函数 default 与 delete
范围for循环
STL容器
1. std::array固定大小数组
2. std::forward_list单向链表
3. 无序关联容器基于哈希表
4. std::tuple元组容器 C11简介
C11原称 C0x是 C 编程语言的第三个国际标准ISO/IEC 14882:2011于 2011 年 8 月正式发布。它是自 1998 年 C98 标准后的首次重大更新引入了大量新特性旨在提高代码效率、简化开发流程并支持现代编程范式。C11 被广泛认为是 C 的“现代化重生”推动了语言向更高抽象层级、更安全的资源管理和更强大的并发支持发展。
C11 的起源 应对现代编程挑战 C032003 年小修订版后开发者逐渐发现语言在并发编程、泛型编程和资源管理上的局限性。硬件多核化、移动语义需求如高效对象转移等趋势要求语言进化。 标准化进程 C0x 项目最初计划在 2000 年代完成故代号 C0x但因复杂性多次延期最终于 2011 年发布更名为 C11。 委员会合作ISO C 标准委员会WG21主导设计融合了全球开发者、学术界和企业的提案Bjarne StroustrupC 创始人和 Herb Sutter 等专家推动关键特性。 设计目标 保持与 C98/C03 的兼容性。 提升类型安全性和性能如右值引用、移动语义。 简化代码如 auto 关键字、范围 for 循环。 支持多线程标准线程库 thread。
统一的列表初始化
C11 引入了 统一列表初始化Uniform Initialization允许使用统一的 {} 语法初始化各种类型的对象包括基本类型、数组、结构体、类对象、容器等。这一特性解决了传统初始化方式的不一致性问题增强了代码的可读性和安全性。
1.初始化范围扩展 C98 的限制 仅支持聚合类型如数组、无自定义构造函数的结构体/类的列表初始化
int arr[] {1, 2, 3}; // 允许数组struct Point
{ int xint y;
};
Point p {3, 4}; // 允许聚合类
不支持非聚合类型如有构造函数的类或 STL 容器直接使用 {} 初始化
std::vectorint v {1, 2, 3}; // C98 报错不支持直接列表初始化 C11 的改进 支持所有类型包括非聚合类、容器、用户自定义类型的列表初始化 // 直接初始化非聚合类需定义接受 std::initializer_list 的构造函数std::vectorint v {1, 2, 3}; // 合法std::string s{Hello}; // 合法struct Point{int _x;int _y;};// 使用大括号对内置类型进行初始化int x1 { 1 }; // 可添加等号int x2{ 2 }; // 可不添加等号// 使用大括号对数组元素进行初始化int array1[]{1, 2, 3, 4, 5}; // 可不添加等号// 使用大括号对结构体元素进行初始化Point p{ 1, 2 }; //可不添加等号2.禁止窄化转换Narrowing Conversion
C98 的问题 允许隐式窄化转换可能导致数据丢失或未定义行为
int x 5.5; // 合法隐式截断为 5但可能导致逻辑错误
C11 的改进 使用 {} 初始化时禁止隐式窄化转换
int x{5.5}; // 编译错误double → int 是窄化转换
int y(5.5); // 合法传统方式允许但结果可能不符合预期
3.解决“最令人烦恼的解析”Most Vexing Parse
C98 的歧义问题 声明对象时可能被误解析为函数声明
class Widget { /*...*/ };
Widget w(); // 歧义声明一个返回 Widget 的函数而非默认构造对象
C11 的改进 使用 {} 消除歧义
Widget w1{}; // 明确调用默认构造函数
Widget w2(); // 仍被解析为函数声明
4.动态数组初始化
C98 的限制 动态分配的数组无法直接初始化
int* arr new int[3]; // 需后续逐个赋值
arr[0] 1; arr[1] 2; arr[2] 3;
C11 的改进 允许动态数组直接使用列表初始化
int* arr new int[3]{1, 2, 3}; // 合法
5. 直接初始化返回值
C98 的局限 函数返回复杂对象时需显式构造
std::vectorint getData() {std::vectorint tmp;tmp.push_back(1);tmp.push_back(2);return tmp;
}
C11 的改进 可直接返回初始化列表
std::vectorint getData() {return {1, 2, 3}; // 直接构造并返回
}
总结
C11 的统一列表初始化通过以下方式彻底改变了 C 的编码风格 语法一致性所有类型初始化方式统一减少记忆负担。 安全性增强禁止窄化转换避免潜在错误。 代码简洁性简化容器和复杂对象的初始化流程。 现代编程支持为后续标准如 C14/17的改进奠定基础。
声明
C11 在变量、函数、类等声明方面引入了多项重要改进旨在提升代码简洁性、类型安全性和表达能力。
1.auto 类型推导 功能允许编译器自动推导变量类型减少冗余的类型书写。
auto x 42; // x → int
auto s Hello; // s → const char*
std::vectorint vec {1, 2, 3};
auto it vec.begin(); // it → std::vectorint::iterator// C98 必须显式写出类型
std::vectorint::iterator it vec.begin();
2. decltype 类型推导 功能获取表达式的类型用于声明复杂类型或模板编程。
int x 10;
decltype(x) y 20; // y 的类型为 inttemplatetypename T, typename U
auto add(T a, U b) - decltype(a b) { // 推导返回值类型return a b;
} 3. 尾置返回类型Trailing Return Type 功能将函数返回类型放在参数列表之后提高可读性尤其适用于模板函数。
auto func(int a, double b) - int; // 声明// 结合 decltype 推导返回值类型。
// Lambda 表达式隐式使用尾置返回类型。
templatetypename T, typename U
auto multiply(T t, U u) - decltype(t * u) {return t * u;
}
4. nullptr 关键字 功能替代 NULL 或 0 表示空指针避免与整数类型的歧义。
void func(int);
void func(char*);
func(nullptr); // 调用 void func(char*)
func(0); // 调用 void func(int)// C98
int* p NULL; // C98 中 NULL 通常是 0 的宏定义类型不安全
5.using 别名声明 功能替代 typedef 定义类型别名支持模板化。
using IntPtr int*; // 等价于 typedef int* IntPtr;
templatetypename Tusing Vec std::vectorT; // 模板化别名C98 无法实现
Vecint v; // 等价于 std::vectorint
6.默认和删除函数 default 与 delete default显式要求编译器生成默认函数如构造函数、拷贝赋值运算符。
class MyClass {
public:MyClass() default; // 显式生成默认构造函数
}; delete禁止编译器生成特定函数或禁用某些重载。
class NonCopyable {
public:NonCopyable(const NonCopyable) delete; // 禁止拷贝
};
void func(int) {}
void func(double) delete; // 禁用 double 版本的重载
范围for循环
范围 for 循环是 C11 引入的一项简化遍历操作的特性它允许开发者以更简洁、直观的方式遍历容器、数组或其他可迭代对象的元素。
基本语法
for (声明 : 范围表达式)
{// 循环体
} 声明定义一个变量用于依次获取范围内的每个元素通常使用 auto 推导类型。 范围表达式可以是数组、STL 容器如 vector、list、初始化列表或任何支持 begin() 和 end() 成员/自由函数的对象。 隐式依赖 begin() 和 end() 范围表达式必须能通过 begin(范围表达式) 和 end(范围表达式) 获取迭代器包括自由函数或成员函数。
代码示例
// 结合 auto 关键字避免显式写出复杂类型
std::vectorint vec {1, 2, 3};
for (auto num : vec) // 使用引用避免拷贝
{ num * 2; // 可修改元素
}// 使用 const auto 避免拷贝同时防止修改元素
for (const auto str : stringList)
{std::cout str std::endl;
}
STL容器
C11中新增了五个容器分别是array、forward_list、unordered_map和unordered_set、tuple
1. std::array固定大小数组 用途替代传统的 C 风格数组提供安全的边界检查、STL 兼容接口和值语义 对比 C98C 风格数组无成员函数且易因越界导致未定义行为。
#include array
std::arrayint, 3 arr {1, 2, 3};
arr.at(1) 42; // 安全访问越界抛出异常
for (auto num : arr) { std::cout num; } // 范围 for 循环 2. std::forward_list单向链表 用途内存敏感场景下的单向链表仅支持前向遍历。 特点 比 std::list双向链表更省内存每个节点少一个指针。 仅支持 push_front()、insert_after() 等操作无 size() 方法。 适用场景需要低内存开销且无需反向遍历的场景如缓存池、轻量级链表。
#include forward_list
std::forward_listint flist {1, 2, 3};
flist.push_front(0); // 头部插入
auto it flist.begin();
flist.insert_after(it, 99); // 在第一个元素后插入
3. 无序关联容器基于哈希表
C11 引入了基于哈希表的无序容器提供平均 O(1) 复杂度的查找、插入和删除操作。 std::unordered_set 和 std::unordered_multiset std::unordered_map 和 std::unordered_multimap
可以查看前面文章STL详解
4. std::tuple元组容器 用途存储任意类型组合的固定大小集合类似结构体但无需显式定义类型。 特点 支持通过 std::get索引 或结构化绑定C17访问元素。 常用于函数多返回值或泛型编程。
#include tuple
auto data std::make_tuple(42, Hello, 3.14);
int num std::get0(data); // 获取第一个元素
std::string str std::get1(data);
对比表格C11 新增容器 vs C98 容器
容器类型C11 新增C98 类似容器主要差异固定数组std::arrayC 风格数组安全、支持 STL 接口单向链表std::forward_liststd::list仅前向遍历内存更省哈希集合std::unordered_setstd::set无序 vs 有序哈希表 vs 红黑树哈希映射std::unordered_mapstd::map同上元组std::tuple增强无直接等价多类型混合存储