【走进C++ (2)】HelloWorld 关键字 命名空间 输入输出

📅 发布时间:2026/7/10 9:39:18
【走进C++ (2)】HelloWorld  关键字  命名空间  输入输出 文章目录一、Hello World二、关键字三、命名空间1、引入2、定义3、重名、嵌套4、使用方式5、匿名命名空间四、输入与输出1、库的展开引入2、输入与输出一、Hello World学习一门新的语言肯定是从最经典的hello world开始打开编译器vs2022创建新项目后右键源文件点击添加新建项取名test.cpp。新建完成后就可以开始写代码啦#include iostream using namespace std; int main() { cout hello world! endl; return 0; }虽然不知道namespace、cout、endl等是什么但后边会进一步讲解此刻运行程序就可以打印出hello world!了。运行截图如下而再次尝试运行C语言的hello world也是可以成功打印出来。#includestdio.h int main() { printf(hello world\n); return 0; }运行截图如下这就说明了C是兼容C的可以把C看作是C的巨大补丁其中C最大的特点就是面向对象。二、关键字C总计63个关键字C语言32个关键字下面只是看一下C有多少关键字不会对关键字进行具体的讲解等到后面学到以后再细讲。需要注意的一点是命名时应避开这些关键字防止编译器无法识别这个标记符从而导致编译失败。下面将列出63个关键字混个眼熟后续使用到再查手册不需要全部记忆三、命名空间1、引入在C/C中变量、函数和类都是大量存在的这些变量、函数和类的名称都会存在于全局作用域中可能会导致命名冲突等问题C引入了namespace目的就是对标识符的名称进行本地化以避免命名冲突或名字污染。为了更加清晰的说明这个问题下面将用一个简单的程序进行说明。在stdlib库中有一个rand()的随机数函数假如在一个程序中不小心给变量取名了rand进行编译此时编译器的搜寻规则是这样的局部 - 全局 - 找不到(报错)这时编译器在全局的库里面找到了rand()但程序使用时是将rand定义成一个变量此时发生冲突就会报错#include stdio.h #include stdlib.h int rand 0; int main() { // rand变量和stdlib库的rand()函数命名冲突 printf(%d\n, rand); return 0; }运行结果如下为了解决这一问题在 C 里面就引入了namespace命名空间这一慨念。2、定义定义命名空间需要使用到namespace关键字后面跟命名空间的名字然后接一对{}即可{}中即为命名空间的成员。拿上面的代码举例具体的定义规则如下#include iostream namespace xz { // rand就被xz命名空间隔离开 int rand 0; } namespace xz1 { // 命名空间也可以存放 函数/结构体/类等 int Add(int left, int right) { return left right; } struct Node { struct Node* next; int val; }; } int x 1; int main() { // 用::去访问xz里面的变量 // 带名称就是作用该名称下的域 std::cout xz::rand std::endl; std::cout xz1::Add(1, 2) std::endl; int x 0; // ::左侧不带任何名称就是作用于全局域 std::cout ::x std::endl; // 打印 1 return 0; }上面的程序中有几点需要注意1这里出现的::叫做作用域解析运算符用于帮助编译器明确标识和区分在不同作用域中声明的标识符。a这里的std就是C全部库的命名空间域在大型项目中不推荐全部展开。b::左侧不带任何名称就表示作用于全局域。2命名空间可以定义在全局中也可以定义在局部中即该命名空间的变量的生命周期和所处在的位置相关。以上面程序为例xz处在全局那么rand展开后就是全局变量唯一不同的就是多了一层xz命名空间进行隔离。3命名空间和结构体相似但性质不一样。结构体是定义一个类型命名空间等同于是一个超大类型的集合此外命名空间大括号外不用加分号。4命名空间不仅可以存放变量也可以存放函数结构体甚至是类。5有了命名空间后编译器的搜索原则就变成如下顺序// 不指定域当前局部域 - 全局域 - 找不到报错// 指定域后如果指定了直接去指定域搜索3、重名、嵌套同一个工程中允许存放多个相同名称的命名空间编译器最后会合成同一个命名空间中。此外命名空间也可以嵌套命名空间。具体的演示如下namespace A { namespace AA { namespace AAA { int a 0; } } } int main() { // 嵌套调用 printf(%d\n, A::AA::AAA::a); return 0; }但无论形式如何生命周期的规则都是和其所属的位置相关的唯一的不同就是多了一层命名空间的划分。4、使用方式命名空间主要有三种使用方式1使用using namespace 命名空间名称引入namespace xz { int a 0; } using namespace xz; int main() { printf(%d\n, a); return 0; }但这种方式有不好的地方因为命名空间本身是为了隔离现在一下子展开了隔离的作用就没有了。2使用using将命名空间中某个成员引入为了兼顾隔离和使用便利可以制定展开某一个成员。具体的方式如下namespace xz { int a 0; int b 1; } // 展开xz中的b using xz::b; // 展开库中的cout和endl using std::cout; using std::endl; int main() { cout b endl; // 这里就可以直接使用b了 return 0; }3命名空间作用域解析运算符除了上述两种还有一种展开方式就是配合作用域解析运算符去使用。具体方式如下#include iostream namespace xz { int a 0; int b 1; } int main() { std::cout xz::a std::endl; return 0; }5、匿名命名空间和匿名结构体相似的是命名空间这里也可以匿名。如果一个命名空间没有名称我们就称它为匿名空间域。namespace { int a 0; int b 1; }这种情况下编译器会在内部给这个没有名字的匿名命名空间生成一个惟一的名字。并且还会为该匿名命名空间生成一条using的指令。因此上面的代码会等同于namespace _UNIQUE_NAME { int a 0; int b 1; } using namespace _UNIQUE_NAME;四、输入与输出1、库的展开引入早期的C实现没有引入命名空间的概念所有的标准库函数和对象如cout、cin都被定义在全局命名空间中而在C标准化之前部分编译器厂商提供了iostream.h。在现代 C 标准引入了std命名空间以避免名称冲突。因此为了和C语言区分开并正确使用命名空间C标准规定C特有的头文件不再使用.h后缀即使用iostream的方式配合std进行使用。2、输入与输出cout标准输出控制台和cin标准输入键盘时必须包含iostream头文件并且需要std搭配使用。cout的c是控制台缩写out就是输出到控制台中cout后面的是流插入运算符其本质是重载了左移的运算符。cin也是如此表示把键盘输入输入进控制台中。endl则相当于\n换行符。cin和cout都可以自动识别出类型使用起来更加方便。#include iostream #include iomanip #include stdio.h using namespace std; int main() { // 流插入而且可以自动识别类型 // c就是控制台缩写out就是输出到控制台中 // endl \n int i 0; const char* str hello world; char ch \n; double d 1.111111; //cout hello world, i i endl; cout str i ch endl; // 流提取而且可以自动识别类型 cin i ch; cout str i ch endl; // 精度控制比较麻烦要用setprecision // 所以可以搭配c语言的printf混合使用方便 cout d endl; cout setprecision(4) d endl; // 设置精度为 4 printf(%.4lf\n, d); return 0; }但在某些场景下cin、cout、endl也存在缺点1大量输入输出时应该少用或者不用endl因为每次endl都会刷新缓冲区增加io次数而且数据特别大的时候也尽量不使用endl应该用\n代替因为转义字符\n只会换行不会触发刷新缓冲区的动作。2并非有了C就抛弃C特别是输入输出的控制上其实是可以混合使用的。以上面代码为例在打印精度方面其实C的打印更加便利因此也推荐使用C的printf混合使用。