今天重新开始C++学习之旅,首先让我们来看下面一段代码。
1.C++代码长什么样?
#include<iostream> // 包含标准输入输出流库,以便使用cout和endl等
using namespace std; // 使用标准命名空间std,简化代码中标准库的引用
int main() { // 主函数,程序执行的入口点
cout << "Hello world" << endl; // 输出"Hello world"到标准输出,并添加换行
system("pause"); // 调用系统命令,暂停程序,直到用户按下任意键(注意是Windows系统特有)
return 0; // 主函数返回0,表示程序成功执行
} // 主函数结束
2.#include <iostream> 预处理命令
#include
是C++(以及C语言)中的一个预处理指令,它告诉预处理器在编译之前将指定的文件内容包含到当前源文件中。这个过程称为文件包含或文件合并。
具体来说,#include
的作用如下:
- 文件包含:它指示编译器在编译前将另一个文件的内容插入到当前文件中
#include
指令所在的位置。这通常用于包含库的头文件,这些头文件定义了程序中使用的函数、类、宏等。 - 两种形式:
#include
指令有两种形式:#include <文件名>
:这种形式用于包含标准库的头文件。编译器会在预定义的标准路径中查找这个文件。#include "文件名"
:这种形式用于包含非标准库的头文件,通常是项目自己的头文件。编译器首先在当前目录中查找这个文件,如果找不到,可能会在标准路径中查找。
- 示例:
#include <iostream>
:这是一个常见的用法,用于包含标准输入输出流库的头文件,以便可以使用cout
、cin
等。#include "myheader.h"
:这通常用于包含程序员自己创建的头文件,比如项目的配置文件或自定义的库文件。
- 工作原理:当编译器处理源文件时,它遇到
#include
指令,就会打开指定的文件,并将文件的内容复制到#include
指令的位置,然后再继续编译处理。
使用#include
可以让我们重用已经编写好的代码,而不必每次都重新编写相同的代码。这是模块化和代码组织的一个重要方面。
其他常见的预处理命令。
文件包含 (#include
)
#include <iostream> // 包含标准输入输出流库
#include "myheader.h" // 包含自定义的头文件
想象你正在写一篇文章,而#include
就像是告诉你:“嘿,这里有一些很棒的资料,你需要用到它们。” <iostream>
就像是引用一本官方出版的参考书,而"myheader.h"
则像是引用你自己的笔记本。
宏定义和取消定义 (#define
, #undef
)
#define PI 3.14159 // 定义宏PI,其值为3.14159
#undef PI // 取消宏PI的定义
定义宏#define PI 3.14159
就像是给你的朋友起了一个昵称“PI”,每次你叫“PI”,大家就知道你指的是3.14159。而#undef PI
则是你决定不再使用这个昵称了。
条件编译 (#ifdef
, #ifndef
, #if
, #else
, #elif
, #endif
)
#define DEBUG
#ifdef DEBUG
cout << "Debug mode is on." << endl;
#else
cout << "Debug mode is off." << endl;
#endif
条件编译就像是你在做决定时说:“如果今天是周末,我就去公园;如果不是,我就去工作。”这里,如果DEBUG被定义了,程序就会输出“Debug mode is on.”,否则输出“Debug mode is off.”。
错误指令 (#error
)
#if defined(PLATFORM) && (PLATFORM != "Windows" && PLATFORM != "Linux")
#error "Platform is not supported."
#endif
#error
就像是你在地图上标出一个危险区域,并告诉所有人:“如果你来到这里,就必须停下来,不能再继续前进。”如果PLATFORM定义了,但不是“Windows”或“Linux”,编译器就会显示一个错误消息。
编译指令 (#pragma
)
#pragma once // 确保文件只被编译一次
#pragma once
就像是告诉你的助手:“这个任务只需要做一次,不要重复。”这确保了包含的文件在编译过程中不会被重复包含。
3.cout << “Hello world” << endl;
这和C语言中的printf(“Hello world\n”);或puts(“Hello world”);有不同。
3.1endl是什么?
endl(end of line)是C++中的一个操纵符,它被用于输出流cout,其作用是在输出流的末尾添加一个换行符,并立即刷新输出缓冲区
,确保输出的数据能够及时显示到屏幕上。
- endl=换行+强制刷新输出缓冲区
3.2刷新输出缓冲区又是什么,为什么要这样做?
缓冲区(Buffer)在内存和外部设备之间提供了一个临时存储区域。缓冲区的主要目的是减少频繁的读写操作,从而提高系统的性能。
当缓冲区满了或者遇到特定的指令(如C++中的endl)时,缓冲区会被刷新,即将缓冲区中的数据发送到屏幕或文件。
这样,用户就可以看到最新的输出结果,而程序则可以继续执行,而不需要等待每次输出都立即刷新到屏幕。(如果每次输出都立即刷新到屏幕,可能会导致屏幕频繁闪烁
,影响用户体验。使用缓冲区可以减少这种情况的发生。)
4. #include<iostream>和using namespace std;
长话短说,就是在标准命名空间用标准库。
没有写using namespace std;,那么就需要这样使用cout和endl:
std::cout << "Hello, World!" << std::endl;
4.1命名空间(namespace)是什么?
在C++中,命名空间是一种将代码组织成逻辑组的方法。每个命名空间都是一个作用域,它包含了一系列的标识符(如变量、函数、类等)。使用命名空间,我们可以避免在大型项目中标识符名称的冲突。
4.2 标准命名空间(std
)是什么?
std
是C++标准库使用的命名空间名称,代表“standard”。它包含了C++标准库中所有的类型、函数、对象和宏。例如,我们常用的string
、vector
、cout
和cin
等都是在std
命名空间内定义的。
4.3标准输入输出流库(iostream
)是什么?
iostream
是C++标准库中的一个头文件,它定义了用于处理输入输出流的对象和函数。我们经常使用的cout
(标准输出流)、cin
(标准输入流)、cerr
(标准错误输出流)和endl
(输出换行并刷新缓冲区)等都是iostream
头文件中定义的。
4.4std与
iostream`的关系形象例子
所有在iostream
中定义的工具都是std
命名空间的一部分,因此它们通常被称为std::cout
、std::cin
等。
想象一下,std
就像是一个大型的超市,而iostream
是这个超市中的一个特定货架,专门存放各种烹饪工具。
4.6那还有其他“超市”吗?其他“超市”的输入输出工具
除了std
命名空间和标准库之外,还有其他“超市”提供了输入输出工具:
- 第三方库:例如Boost库,它提供了许多扩展功能,包括输入输出相关的工具,这些工具位于
boost::iostreams
命名空间中。比如,
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/stream.hpp>
using namespace boost::iostreams;
file_sink fs("output.txt");
stream<file_sink> os(fs);
os << "Hello, World!" << endl;
- 操作系统特定的API:不同的操作系统提供了特定的API用于文件操作和网络通信,这些API也提供了输入输出功能,但它们不属于C++标准库。
- 用户自定义的命名空间:程序员可以创建自己的命名空间,并在其中定义输入输出类或函数。
登高自卑,脚踏实地,接着学习总结吧。这一节先到这了。