C++将函数声明放在头文件中的示例

C++将函数声明放在头文件中的示例

本文可以看作是“C++多文件编程介绍” https://blog.csdn.net/cnds123/article/details/125905593 一文的补充说明。

C++函数原型声明(函数声明)的位置可以有以下几种选择:

1.函数声明放在同一源文件中:这种情况通常适用较小的项目中,通常可以将函数的声明和定义放在同一个源文件中。先声明函数原型,然后定义函数的实现。

2.函数声明放在头文件中,函数定义放在实现文件中。在大型项目中,常常将函数的声明放在一个或多个头文件中,然后将函数的定义放在对应的源文件中。头文件包含函数的原型,以及可能需要的其他声明(例如结构体、宏等),实现源文件则包含函数的具体实现。在另外的源文件(应用自定义头文件的源文件)中使用之。

下面给出示例。

★函数声明放在源文件中,这个常见,例如:

#include <iostream>
using namespace std;

// 函数声明
int add(int a, int b); 

int main() {
    int x = 5;
    int y = 10;
    int sum = add(x, y); //函数调用 ,x 和 y 是实参,它们的值被传递给 add 函数的形参 a 和 b
    cout << "和: " << sum << endl;
    
    return 0;
}

// 函数定义
int add(int a, int b) {
    return a + b;
}

运行效果:

★函数声明放在自定义头文件中,函数定义放在实现源文件中,在另外的源文件(应用自定义头文件的源文件)中使用之。例如:

MathUtils.h文件(头文件)内容如下:

#ifndef MATHUTILS_H
#define MATHUTILS_H

// 函数声明
int add(int a, int b);
int subtract(int a, int b);
double multiply(double a, double b);
double divide(double a, double b);

#endif

 说明,其中

#ifndef MATHUTILS_H

#define MATHUTILS_H

#endif

这是头文件保护宏(header guard)的常见用法。它们的作用是防止头文件的重复包含。

#ifndef MATHUTILS_H这个预处理指令检查是否已定义了名为 MATHUTILS_H 的宏。如果没有定义,表示这是第一次包含该头文件,那么就会执行 #define MATHUTILS_H。

#define MATHUTILS_H:这个预处理指令定义了名为 MATHUTILS_H 的宏。定义这个宏是为了防止多次包含同一个头文件时出现重定义的错误。

#endif:这个预处理指令结束条件编译块。它与 #ifndef 配套使用,将 #ifndef 和 #define 之间的代码包裹起来,确保只有当宏未定义时才会包含这些代码。

头文件保护机制是一个非常常见的做法,它能够确保头文件只被包含一次,避免了由于重复定义而引起的错误。

#ifndef和#define的标识符设置为对应头文件的名称。这样做的好处是可以确保每个头文件都有一个唯一的标识符,避免头文件重复包含的问题。标识符的命名通常会在头文件名称上加上一个下划线,以避免与其他标识符冲突。

例如,对于名为mathutils.h的头文件,我们可以这样设置#ifndef和#define的标识符:

#ifndef MATHUTILS_H

#define MATHUTILS_H

MathUtilsFunctions.cpp文件(头文件的实现源文件)内容如下:

#include "MathUtils.h"

// 函数实现
int add(int a, int b) {
    return a + b;
}

int subtract(int a, int b) {
    return a - b;
}

double multiply(double a, double b) {
    return a * b;
}

double divide(double a, double b) {
    return a / b;
}

mainAPP.cpp文件(应用头文件的源码文件)内容如下:

#include "MathUtils.h" // 自定义头文件
//#include "MathUtilsFunctions.cpp" // 不用包含自定义头文件中函数实现的源文件
#include <iostream>
using namespace std; 

int main() {
    int num1 = 10;
    int num2 = 5;

    int sum = add(num1, num2);
    int difference = subtract(num1, num2);
    double product = multiply(num1, num2);
    double quotient = divide(num1, num2);
   
    cout << "Sum: " << sum << endl;
    cout << "Difference: " << difference << endl;
    cout << "Product: " << product << endl;
    cout << "Quotient: " << quotient << endl;

    return 0;
}

这种方式可以有效地组织代码,提高代码的可维护性和可读性。同时,如果将来需要在其他源文件中使用这些函数,只需包含MathUtils.h头文件即可。

上面例子在mainAPP.cpp文件中只需包含自定义头文件即可。

使用Dev-C++编译和运行带有自定义头文件的C++源代码的步骤如下:

打开Dev-C++,创建一个新项目。

项目类型选Basic页中的Console Application,并为项目起一个名称

在项目中,选择“文件”->“新建”->“源文件”,

添加MathUtils.h、MathUtilsFunctions.cpp、mainAPP.cpp文件

编译运行效果如下:

、在window系统中使用g++编译器编译

如果你在Windows系统上使用g++编译器来编译前面给出的例子,可以按照以下步骤进行:

确保你已经安装了g++编译器。你可以在命令行中输入g++ --version来检查是否已经安装。

1、打开命令提示符cmd或PowerShell,并导航到存储了源代码文件(mainAPP.cpp和functions.cpp)的目录。

2、使用以下命令将两个源代码文件编译为可执行文件(假设头文件header.h位于与main.cpp和MathUtilsFunctions.cpp相同的目录中,你想将可执行文件命名为"program.exe"):

g++ mainAPP.cpp MathUtilsFunctions.cpp -o program.exe

如果代码中没有错误,编译过程将会成功,并且会生成一个名为"program.exe"的可执行文件。

3、双击该可执行文件或者在命令行中输入.\program.exe来运行程序。程序将会在命令行窗口中显示输出结果。

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 在链接过程,如果多个目标文件存在相同名称的函数定义,链接器会选择其一个作为最终的定义。具体选择哪个定义,取决于链接器的实现方式和链接顺序。一般来说,链接器会选择最后被编译的目标文件的函数定义。也就是说,如果文件a的函数定义先被编译,文件b的函数定义后被编译,那么链接器会选择文件b的函数定义作为最终的定义。因此,在编程序时,建议避免在多个文件定义同名的函数。 ### 回答2: 在链接文件的过程,如果多个文件都给出了函数f的定义,按照C语言的链接规则,最终链接的执行文件将采用其一个定义。 具体来说,如果文件a和b均给出了函数f的定义,而且这两个定义是完全一致的(函数名、参数列表、返回类型等都相同),那么链接时会自动将这两个定义合并为一个。 如果两个定义不完全一致,也就是说函数名、参数列表、返回类型等有所差异,那么根据C语言的链接规则,会优先选择文件b的定义,因为文件b在编译和链接的过程后被处理,具有更高的优先级。这样,在链接的执行文件,函数f采用的就是文件b的定义。 需要注意的是,由于两个不完全一致的函数定义会引发编译器的一些警告或错误,因此在实际编程应该避免这种情况的出现。最好的方式是在头文件只声明函数f的原型(函数名、参数列表、返回类型),在a和b等具体的实现文件分别给出函数f的定义,保持定义的一致性,避免编译和链接错误。 ### 回答3: 如果在头文件声明了函数f,意味着函数f的原型已经在头文件进行了声明,但函数的具体实现还未给出。在文件a和b给出了函数f的定义,意味着函数f的具体实现已经在文件a和b给出。 在链接a和b的执行文件时,可能会出现两种情况: 1. 如果在链接时选择文件a进行链接,那么文件a给出的函数f的定义将被采用。这是因为在链接的过程,编译器会先查找引用的函数f的定义,如果在文件a找到了函数f的定义,就会采用文件a的定义。 2. 如果在链接时选择文件b进行链接,那么文件b给出的函数f的定义将被采用。这是因为在链接过程,如果在文件a找不到函数f的定义,编译器会继续查找其他文件是否有函数f的定义。如果在文件b找到了函数f的定义,就会采用文件b的定义。 总结起来,链接a和b的执行文件时,如果在文件a和b都给出了函数f的定义,那么最终采用哪个定义取决于链接时选择的具体文件。如果选择文件a进行链接,则采用文件a的定义;如果选择文件b进行链接,则采用文件b的定义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习&实践爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值