首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
C++和标准库速成(一)——HelloWorld和名称空间
📅 2026/9/14 9:29:24
✍️ 爱科研究院
👁 阅读 3,247
目录1. 引言1. 简单小程序Hello World1.1 模块导入1.2 预处理指令1.2.1 简介1.2.2 常用的预处理指令1.3 main()函数1.4 输入输出流1.4.1 输出流1.4.2 转义字符1.4.3 输入流2. 名称空间2.1 定义名称空间2.2 using指令2.3 嵌套名称空间2.4 名称空间别名参考1. 引言C20的标准库模块目前还没有正式得到编译器的支持而MSVC中已经存在了对标准库模块的实验性支持。需要安装适用于v143生成工具的C模块并且将普通控制台应用项目属性C/C下的所有选项中的启用实验性的C标准库模块改为是。vs18只需要安装完默认的“使用C的桌面开发就行了然后在新建的控制台应用中点击项目选择最后一个xxx和属性点击C/C的所有选项将生成ISO C23的标准库模块改为是。1. 简单小程序Hello Worldimportstd.core;// vs18需要改为import std;intmain(){std::coutHello, World!std::endl;return0;}1.1 模块导入C20中最重要的新特性之一就是对模块的支持用来替代之前的头文件机制。如果你想要使用某个模块中的功能则需要导入这个模块可以通过一条import声明做到。如import std.core;如果你的编译器还不支持模块只需要简单地将import声明替换为#include预处理指令。1.2 预处理指令1.2.1 简介如果你的编译器还不支持C20的模块需要编写如下的预处理指令#include iostream。简单来说生成一个C程序共有3个步骤。首先代码经过预处理器预处理器会识别代码中的元信息。其次代码被编译或转换为计算机可识别的目标文件。最后独立的目标文件被连接在一起生成一个应用程序。预处理指令以#字符开始前面实例中的#include iostream就是一条预处理指令。在此例中include指令告诉预处理器提取iostream头文件中的所有内容并提供给当前文件。头文件最常见的用途是声明在其他地方定义的函数函数声明会通知编译器如何调用这个函数并声明函数中参数的个数和类型以及函数的返回类型函数定义包含这个函数的实际代码。在C20引入模块之前声明通常放在扩展名为.h的文件中称为头文件其定义通常包含在扩展名为.cpp的文件中称为源文件。有了模块我们不再需要将声明与定义分离但是之前的写法仍然可以使用。注意:1. 在C中标准库头文件的名称通常以.h结尾不使用名称空间。2. 在C中标准库头文件的名称省略了.h后缀所有文件都在std名称空间和std的子名称空间中定义。3. C中的标准库头文件在C中依然存在但使用以下两个版本3.1 不使用.h后缀改成前缀c这是推荐使用的版本这些头文件将内容放在std名称空间中。3.2 使用.h后缀这是旧版本这些版本不适用名称空间。1.2.2 常用的预处理指令预处理指令功能常见用法#include [file]将指定的文件插入代码中指令所在的位置几乎总是用来包含头文件使代码可使用在其他位置定义的功能#define [id] [value]每个指定的标识符都被替换成指定的值在C中常用来定义常数值或宏。C提供了常数和大多数宏类型的更好机制。在C使用宏有风险。#ifdef [id]#endif#ifndef [id]#endififdef(if defined)块和ifndef(if not defined)块中的代码被有条件地包含或舍弃这取决于是否使用#define定义了特定的标识符经常用来防止循环包含。每个头文件都以#ifndef开头以保证某个标识符还未被定义然后用一条#define指令定义该标识符。头文件以#endif结束这样这个头文件不会被多次包含#pragma [xyz]xyz因编译器而异。如果在预处理期间执行到这一指令通常会显示一条警告或错误信息参见该表之后的举例下面是使用预处理指令避免重复包含的一个实例#ifndefMYHEADER_H#defineMYHEADER_H// ... the contents of this header file#endif如果编译器支持#pragma once指令可采用以下方法重写上面的代码。#pragmaonce// ... the contents of this header file1.3 main()函数main()函数是程序的入口。main函数返回一个int值以指示程序的最终执行状态。在main()函数中可以忽略显式的return语句这种情况下会自动返回0.main()函数要么没有参数要么具有两个参数如下所示。int main(int argc, char* argv[])argc给出了传递给程序的实参数目argv包含了这些实参。注意argv[0]可能是程序的名称也可能是空字符串所以不应使用它。应当使用特定于平台的功能检索程序名。最重要的是实际参数从索引1开始。1.4 输入输出流1.4.1 输出流基本的输入输出非常简单可将输出流想象为针对数据的洗衣滑槽放入其中的任何内容都可以被正确地输出。std::cout就是对应于用户控制台或标准输出的滑槽此外还有其他滑槽包括用于输出错误信息的std::cerr。运算符将数据放入滑槽在前面的示例中引号中的文本字符串被送到标准输出。输出流可在一行代码中连续输出多个不同类型的数据如下面的代码所示。std::cout There are 219 ways I love you. std::endl;从C20开始推荐的写法是使用std::format()定义在中用来格式化字符串。如std::cout std::format(There are {} ways I love you., 219) std::endl;。std::endl代表序列的结尾。当输出流遇到std::endl时就会将已送入滑槽的所有内容输出并转移到下一行。1.4.2 转义字符表明一行结尾的另一种方法是使用\n字符\n字符是一个转义字符这是一个换行符。转义字符可以在任何被引用的文本字符串中使用。转义字符含义\n换行将光标移到下一行的开头\r回车将光标移到本行的开头\t制表符\反斜杠字符引号警告请记住endl会在流中插入新的一行并且将当前缓冲区中的所有内容刷出滑槽。不建议过度地使用endl例如在循环中使用这会影响程序的性能。另一方面在流中插入\n也会插入新的一行但不会自动刷新缓冲区。1.4.3 输入流流还可用于接收用户的输入最简单的方式是在输入流中使用运算符。std::cin输入流接受用户的键盘输入。示例如下intvalue;std::cinvalue:需要慎重对待用户输入因为永远都不会知道用户会输入什么类型的数据。如果你拥有C的背景知识但初次接触C你可能想了解过去使用的、可靠的printf()和scanf()现在究竟是什么情况。尽管C中仍然可以使用这些函数但强烈建议你改用format()和流库主要原因是printf()和scanf()未提供类型安全。2. 名称空间2.1 定义名称空间名称空间用来处理不同代码段之间的名称冲突问题。例如你某天编写了一段代码其中有一个名为foo()的函数。某天你决定用第三库其中也有一个foo()函数。编译器无法判断你的代码要使用哪个版本的foo()函数。库函数的名称无法改变而改变自己的函数名称又会感觉到痛苦。在此类情况下使用名称空间从而指定定义名称的环境。为将某段代码加入名称空间可用namespace块将其包含。示例如下namespacemycode{voidfoo(){std::coutfoo() called in the mycode namespacestd::endl;}}将你编写的foo()版本放到名称空间mycode后这个函数就与第三方库提供的foo()函数区分开来。为调用启用了名称空间的foo()版本需要使用::在函数名称之前给出名称空间::称为作用域解析运算符。mycode::foo();2.2 using指令mycode名称空间中的任何代码都可调用该名称空间内的代码而不需要显式说明该名称空间。隐式的名称空间可使代码清晰并易于阅读。可使用using指令避免预先指明名称空间。这个指令通知编译器后面的代码将使用指定名称空间中的名称。示例如下usingnamespacemycode;intmain(){foo();// Implies mycode::foo();}一个源文件中可包含多条using指令这种方法虽然便捷但注意不要过度使用。极端情况下如果你使用了已知的所有名称空间实际上就是完全取消了名称空间。如果使用了两个同名的名称空间将再次出现名称冲突问题。另外应该知道代码在哪个名称空间内运行这样就不会无意中调用错误版本的函数。可以使用using指令引用名称空间内的特定项。例如想要只使用std名称空间中的cout可以使用如下的using声明using std::cout;后面的代码可以使用cout而不需要预先指明这个名称空间但仍然需要显式说明std名称空间中的其他项。警告切勿在全局作用域的头文件中使用using指令或using声明否则添加你的头文件的每个人都必须使用它。将其放在较小的作用域例如名称空间或类作用域中是可以的甚至是在文件头部。将using指令或using声明放在模块接口文件中也是不错的选择只要你不将它导出。2.3 嵌套名称空间嵌套的名称空间即将一个名称空间放在另一个名称空间中。各个名称空间之间由双冒号隔开示例如下namespaceMyLibraries::Networking::FTP{/*...*/}这种紧凑写法是在C17之后才得到支持的在C17之前必须按如下方式使用嵌套的名称空间。namespaceMyLibraries{namespaceNetworking{namespaceFTP{/*...*/}}}2.4 名称空间别名可使用名称空间别名为另一个名称空间指定一个更简短的新名称。示例如下namespaceMyFTPMyLibraries::Networking::FTP;参考[比] 马克·格雷戈勒著 程序喵大人 惠惠 墨梵 译 C20高级编程(第五版)
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/9/14 9:29:24
AI重构光模块三温测试:从30分钟到2分钟的底层突破
2026/9/14 9:29:24
人形机器人喇叭杂音共振排查:从电路到结构的系统调试指南
2026/9/14 9:24:23
AI时代的程序员支点:从代码杠杆到判断力迁移
2026/9/14 10:59:39
Haystack × Ragas 集成指南:用 RagasEvaluator 构建 LLM 驱动的 RAG 质量评估
2026/9/14 10:59:39
企业级智能体效能管理:从能用到好用的实战指南
2026/9/14 10:59:39
如何通过OpenAI API构建自定义ChatGPT助手
2026/9/14 10:59:39
oauth2-proxy 使用 GitHub 提供商接入 Gitea / Forgejo 身份验证的完整配置与源码解析
2026/9/14 10:59:39
NLP模型量化技术:原理、实现与应用优化
2026/9/14 10:54:38
Spring AI vs LangChain4j:Java后端LLM框架选型实战指南
2026/9/14 0:03:40
KCF目标跟踪算法与OTB工程实现:毕业设计实战解析
2026/9/14 0:03:40
Megatron-LM 推理实战指南:基于 Megatron Core 高层 API 的离线推理与 OpenAI 兼容服务
2026/9/14 0:03:40
语音情感识别实战:Keras实现LSTM、CNN、SVM与MLP多模型对比
2026/9/14 7:37:16
拯救者Y7000黑屏故障排查与维修实战指南
2026/9/14 2:50:57
AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验
2026/9/13 0:01:25
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化