在前文中,我们曾看到,预处理指令的先执行性受到了原生字符串字面量的挑战。那么,这一指令的不符直觉之处还有哪些呢?这一次,峰子得寸进尺,进一步对 #include 指令进行战略试探。
首先,若将文件以词法记号为单位进行分割,存入多文件中,再向同一文件中做 #include ,会发生什么呢?
//test.cpp #include "include.txt" #include "using.txt" #include "outerfunc.txt" #include "mainfuncbegin.txt" #include "mainfunc.txt" #include "mainfuncend.txt"
//include.txt #include <iostream>
//using.txt using namespace std;
//outerfunc.txt void outerfunc() { cout << "From outerfunc():" <<endl; }
//mainfuncbegin.txt int main(int argc,char * argv[]) {
//mainfunc.txt cout << argv[0] << endl; outerfunc();
//mainfuncend.txt }
编译环境:TDM-GCC-32 4.7.2,Windows 7 旗舰版。
编译选项:
mingw32-g++ test.cpp -o test.exe -std=c++11
mingw32-g++ test.cpp -o test.exe
这个文件的编译是成功的。
运行结果:
prompt> dir /d
......
[.] mainfunc.txt outerfunc.txt using.txt
[..] mainfuncbegin.txt test.cpp
include.txt mainfuncend.txt test.exe
8 个文件 1,002,239 字节
2 个目录 9,725,964,288 可用字节
prompt> test
test
From outerfunc():
看起来,这样的分割是可以为编译器所接受的。
但是,是不是把文件无论怎么分割,都可以轻松通过编译呢?
//test.cpp #include "markstart.txt" #include "others.txt" #include "markend.txt" int main(){ return 0; }
//markstart.txt R"(
//others.txt Hello, world!
//markend.txt )"
编译环境:Windows 7 旗舰版,TDM-GCC-32 4.7.2编译选项和结果:
prompt> dir /d
......
[.] markend.txt others.txt test.cpp
[..] markstart.txt
4 个文件 116 字节
2 个目录 9,725,747,200 可用字节
prompt> mingw32-g++ test.cpp -o test.cpp -std=c++11
In file included from test.cpp:1:0:
markstart.txt:1:1: error: unterminated raw string
R"(
^
编译失败。
结合上个实验的结论不难明白,R"( 之后的内容都视为纯的字符串,不发挥语法功能,直到遇到 )" 为止。但是显然,它并不知道何时遇到或会不会遇到一个截止符,如果后面发现了新的 #include 指令,到底要不要展开,所以,编译器不可能允许上述代码通过编译。
峰子的一系列后续实验都指向这个结论:程序可以被分成多文件结构,当并且只有当每个文件中包含了完整的一个个词法单元(或称词法记号)时。
相关推荐
函数是C++程序设计中的基本组成部分之一,它由一系列执行特定任务的指令组成,并可以被程序多次调用。函数有助于将复杂的程序分解为较小、更易于管理的部分。在C++中,函数通常具有以下结构: ```cpp 返回类型 函数...
在C++编程中,预处理器(Preprocessor)是编译过程中的一个重要环节,它在实际编译源代码之前处理源代码。预处理器的主要任务包括宏替换、条件编译和文件包含等。本文将深入探讨C++ IDE中如何设置和利用预处理器,并...
这里,`#include <iostream>`是预处理器指令,用于引入输入输出流库,使得我们能够进行标准输入输出。`main()`函数是程序的入口点,`std::cout`是输出流对象,用来打印到控制台。 接下来,我们将探讨如何创建一个...
本章"初识C++——C++程序设计入门"是学习C++之旅的起点,旨在为初学者构建坚实的基础。 首先,C++程序的基本结构通常包括预处理指令、函数定义、变量声明和控制流语句。预处理指令以`#`开头,如`#include`用于引入...
最后,编译预处理是C++编译过程的一部分,主要处理`#define`、`#include`等预处理器指令。预处理器在实际编译之前扩展宏定义,替换条件编译指令,并处理头文件的包含,有助于提高代码的可读性和模块化。 综上所述,...
C++是一种强大的面向对象编程语言,它源自C语言并扩展了其功能,包括类、模板、异常处理等高级特性。以下是对C++基础知识点的详细解释: 1. **空头程序**:C++中的空头程序是一个没有实际操作的简单程序,通常用于...
10. **C++11新特性**:2013年的文档可能已经包含了C++11标准的新特性,如右值引用、lambda表达式、自动类型推断(auto关键字)等。 使用这份离线文档,开发者可以随时查阅C++的相关信息,无论是初学者还是经验丰富...
CFLAGS = -std=c++11 -Wall OBJS = main.o helper.o all: my_program.exe main.o: main.cpp $(CC) $(CFLAGS) -c main.cpp helper.o: helper.cpp $(CC) $(CFLAGS) -c helper.cpp my_program.exe: $(OBJS) $(CC...
11. **预处理器**:预处理器指令如#include、#define和宏定义在编译阶段起作用,用于代码组织和定制。 12. **STL(标准模板库)**:STL包含容器(如vector、list、map等)、迭代器、算法和函数对象,极大地提高了...
《C++经典教材——C++入门》是一本专为初学者设计的教程,旨在帮助读者快速掌握C++的基础知识,为深入学习和实践打下坚实基础。 该教材可能涵盖以下几个关键知识点: 1. **C++简介**:介绍C++的历史、特点和应用...
标准库中的类和函数在`std`命名空间中声明,因此需要通过`#include`预处理器指令和`using namespace std`来访问它们。 - **输出控制符`endl`**:用于在输出流中插入一个新行并刷新缓冲区。 - **函数声明**:例如`int...
头文件可以在C++程序中使用#include指令将其包含进来,以便使用其中的函数、类和宏。不同的头文件提供了不同的功能,例如iostream.h头文件提供了数据流输入/输出功能,而cmath头文件提供了数学函数。 头文件的命名...
《C++代码清理工具——cxx-clean-include》 在C++编程中,良好的代码组织和管理对于项目的可维护性至关重要。`cxx-clean-include`是一个旨在优化和清理C++源码中包含(#include)语句的工具,它可以从项目中删除...
【C++课程设计——学生成绩管理系统】是一个典型的面向对象编程项目,旨在通过C++语言实现一个能够管理学生成绩的应用。在这个系统中,学生的信息包括学号、姓名、所选课程名称、平时成绩、期末成绩以及平时成绩所占...
在这个程序中,“#include ”是一个预处理器指令,用于引入iostream库,它提供了输入输出流的功能。“std::cout”是标准输出流,用来将文本打印到屏幕。“std::endl”则是一个操纵符,用于插入一个换行符并刷新缓冲...
TinyXML是C++编程语言中一个轻量级的XML解析库,它被设计为小巧、易用且易于集成到各种项目中。XML(eXtensible Markup Language)是一种用于存储和传输数据的标准格式,尤其在软件开发中广泛用于配置文件、数据交换...
在第一课“走进神秘的C++——软件下载、安装”中,首先介绍了编程的基本概念,通过一个小故事激发学生对编程的兴趣。故事中的主角牛牛看到学长们用编程软件实现了电脑与人的互动,感到好奇并想尝试。学习C++的第一步...
9. **预处理器**:C++的预处理器负责处理#include指令,宏定义(#define)以及条件编译(#ifdef、#ifndef等)。 10. **命名空间**:命名空间用于避免全局命名冲突,使得大型项目中的代码更加清晰和可维护。 《C++...