news 2026/6/15 16:09:02

内存模型和名称空间(单独编译)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
内存模型和名称空间(单独编译)

单独编译

和C 语言一样,C++也允许甚至鼓励程序员将组件函数放在独立的文件中。第1 章介绍过,可以单独
编译这些文件,然后将它们链接成可执行的程序。(通常,C++编译器既编译程序,也管理链接器。)如果
只修改了一个文件,则可以只重新编译该文件,然后将它与其他文件的编译版本链接。这使得大程序的管
理更便捷。另外,大多数C++环境都提供了其他工具来帮助管理。例如,UNIX 和Linux 系统都具有make
程序,可以跟踪程序依赖的文件以及这些文件的最后修改时间。运行make 时,如果它检测到上次编译后
修改了源文件,make 将记住重新构建程序所需的步骤。大多数集成开发环境(包括Embarcadero C++
Builder、Microsoft Visual C++、Apple Xcode 和Freescale CodeWarrior)都在Project 菜单中提供了类似的
工具。

现在看一个简单的示例。我们不是要从中了解编译的细节(这取决于实现),而是要重点介绍更通用的
方面,如设计。

例如,假设程序员决定分解程序清单7.12 中的程序,将支持函数放在一个独立的文件中。清单7.12
将直角坐标转换为极坐标,然后显示结果。不能简单地以main( )之后的虚线为界,将原来的文件分为两个。
问题在于,main( )和其他两个函数使用了同一个结构声明,因此两个文件都应包含该声明。简单地将它们
输入进去无疑是自找麻烦。即使正确地复制了结构声明,如果以后要作修改,则必须记住对这两组声明都
进行修改。简而言之,将一个程序放在多个文件中将引出新的问题。

谁希望出现更多的问题呢?C 和C++的开发人员都不希望,因此他们提供了#include 来处理这种情况。
与其将结构声明加入到每一个文件中,不如将其放在头文件中,然后在每一个源代码文件中包含该头文件。
这样,要修改结构声明时,只需在头文件中做一次改动即可。另外,也可以将函数原型放在头文件中。因
此,可以将原来的程序分成三部分。

  • 头文件:包含结构声明和使用这些结构的函数的原型。
  • 源代码文件:包含与结构有关的函数的代码。
  • 源代码文件:包含调用与结构相关的函数的代码。

这是一种非常有用的组织程序的策略。例如,如果编写另一个程序时,也需要使用这些函数,则只需
包含头文件,并将函数文件添加到项目列表或make 列表中即可。另外,这种组织方式也与OOP 方法一致。
一个文件(头文件)包含了用户定义类型的定义;另一个文件包含操纵用户定义类型的函数的代码。这两
个文件组成了一个软件包,可用于各种程序中。

请不要将函数定义或变量声明放到头文件中。这样做对于简单的情况可能是可行的,但通常会引来麻
烦。例如,如果在头文件包含一个函数定义,然后在其他两个文件(属于同一个程序)中包含该头文件,
则同一个程序中将包含同一个函数的两个定义,除非函数是内联的,否则这将出错。下面列出了头文件中
常包含的内容。

  • 函数原型。
  • 使用#define 或const 定义的符号常量。
  • 结构声明。
  • 类声明。
  • 模板声明。
  • 内联函数

将结构声明放在头文件中是可以的,因为它们不创建变量,而只是在源代码文件中声明结构变量时,
告诉编译器如何创建该结构变量。同样,模板声明不是将被编译的代码,它们指示编译器如何生成与源代
码中的函数调用相匹配的函数定义。被声明为const 的数据和内联函数有特殊的链接属性(稍后将介绍),
因此可以将其放在头文件中,而不会引起问题。

程序清单9.1、程序清单9.2 和程序清单9.3 是将程序清单7.12 分成几个独立部分后得到的结果。注意,
在包含头文件时,我们使用“coordin.h”,而不是<coodin.h>。如果文件名包含在尖括号中,则C++编译器
将在存储标准头文件的主机系统的文件系统中查找;但如果文件名包含在双引号中,则编译器将首先查找
当前的工作目录或源代码目录(或其他目录,这取决于编译器)。如果没有在那里找到头文件,则将在标准
位置查找。因此在包含自己的头文件时,应使用引号而不是尖括号。

图9.1 简要地说明了在UNIX 系统中将该程序组合起来的步骤。注意,只需执行编译命令CC 即可,
其他步骤将自动完成。g++和gpp 命令行编译器以及Borland C++命令行编译器(bcc32.exe)的行为类似。Apple
Xcode、Embarcadero C++ Builderr 和Microsoft Visual C++基本上执行同样的步骤,但正如第1 章介绍的,
启动这个过程的方式不同——使用能够创建项目并将其与源代码文件关联起来的菜单。注意,只需将源代
码文件加入到项目中,而不用加入头文件。这是因为#include 指令管理头文件。另外,不要使用#include
来包含源代码文件,这样做将导致多重声明。

警告:在IDE 中,不要将头文件加入到项目列表中,也不要在源代码文件中使用#include 来包含其他
源代码文件。

#ifndef COORDIN_H_ #define COORDIN_H_ #include <iostream> struct polar { double distance; double angle; }; struct rect { double x; double y; }; polar rect_to_polar(rect xypos); void show_polar(polar dapos); #endif

头文件管理

在同一个文件中只能将同一个头文件包含一次。记住这个规则很容易,但很可能在不知情的情况下将头
文件包含多次。例如,可能使用包含了另外一个头文件的头文件。有一种标准的C/C++技术可以避免多次包
含同一个头文件。它是基于预处理器编译指令#ifndef(即if not defined)的。下面的代码片段意味着仅当以前
没有使用预处理器编译指令#define 定义名称COORDIN_H_时,才处理#ifndef 和#endif 之间的语句:

#ifndef COORDIN_H_ ... #endif

通常,使用#define 语句来创建符号常量,如下所示:

#define MAXIMUM 4096

但只要将#define 用于名称,就足以完成该名称的定义,如下所示:

#inndef COORDIN_H_ #define COORDIN_H_ #endif

编译器首次遇到该文件时,名称COORDIN_H_没有定义(我们根据include 文件名来选择名称,并加上
一些下划线,以创建一个在其他地方不太可能被定义的名称)。在这种情况下,编译器将查看#ifndef 和#endif
之间的内容(这正是我们希望的),并读取定义COORDIN_H_的一行。如果在同一个文件中遇到其他包含
coordin.h 的代码,编译器将知道COORDIN_H_已经被定义了,从而跳到#endfi 后面的一行上。注意,这种方
法并不能防止编译器将文件包含两次,而只是让它忽略除第一次包含之外的所有内容。大多数标准C 和C++
头文件都使用这种防护(guarding)方案。否则,可能在一个文件中定义同一个结构两次,这将导致编译错误。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 11:59:56

JAX JIT编译:超越即时编译的静态计算图革命

JAX JIT编译&#xff1a;超越即时编译的静态计算图革命 摘要 在深度学习框架激烈竞争的今天&#xff0c;JAX凭借其独特的函数式编程范式和对高性能计算的深度优化脱颖而出。其中&#xff0c;Just-In-Time&#xff08;JIT&#xff09;编译作为JAX最核心的特性之一&#xff0c;不…

作者头像 李华
网站建设 2026/6/14 13:42:42

【Matlab】MATLAB if-else语句详解:二选一条件执行与简单分支逻辑应用

MATLAB if-else语句详解:二选一条件执行与简单分支逻辑应用 在MATLAB流程控制语法中,if-else语句是实现“二选一”分支逻辑的核心工具,承接基础单条件if语句,兼顾简洁性与实用性,广泛应用于需覆盖“满足/不满足”两种场景的编程需求。与单条件if语句仅执行单一逻辑、跳过…

作者头像 李华
网站建设 2026/6/15 12:01:13

分库分表下的分页查询,到底该怎么搞?(实战完整版)

在后端开发中&#xff0c;分库分表是解决单库单表数据量爆炸、并发瓶颈的必经之路。但随之而来的&#xff0c;是一系列“简单功能变复杂”的坑——分页查询就是最典型的一个。 单库单表时代&#xff0c;我们用 LIMIT offset, size 就能轻松实现分页&#xff0c;比如查询第11页…

作者头像 李华
网站建设 2026/6/15 12:44:44

电网负载测试新纪元:联邦学习的稳定性框架解析

一、测试框架的技术重构 1.1 分布式测试架构设计 隐私保护型测试环境&#xff1a;采用联邦学习三层架构&#xff08;中心协调层-区域代理层-终端设备层&#xff09;&#xff0c;实现原始数据本地化处理&#xff0c;仅交换加密模型参数&#xff08;梯度/权重&#xff09; 动态…

作者头像 李华