IE盒子

搜索
查看: 128|回复: 1

C语言中如何实现多文件编程

[复制链接]

1

主题

5

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2022-11-30 19:26:19 | 显示全部楼层 |阅读模式
众所周知源代码是通过 预编译、编译、汇编、链接、 最后生成的可执行文件的↓


通过Linux的GCC可以主动的进行全过程
但是在很多时候初学者会在不知情的情况下直接忽略了链接这一实质性的过程,毕竟大多数的初学者都是优先选择IDE(集成开发环境)。
所以这一期让我们用C语言的角度来进行多文件的链接(调用)吧!
<hr/>首先看一下这段代码清单↓
main函数部分
/* BasicMain.c */
#include        "stdio.h"
void fun_1(void)
{
        printf("--------");
}

int        main(void)
{
           fun_1();
        printf("Hello! Multifile Call!");
          fun_1();
  return 0;
} 这是一段非常简单的调用函数的小例子;即便把这些代码写的再复杂,它也只局限于这一单个文件中。
那么应该如何突破单个文件的局限呢?
首先介绍 extern关键字;有它当做“向导”告诉编译器其他文件的位置就可以解决多文件调用的问题了。
其次看一下这块代码↓
/* stack.h */
#ifndef        STACK_h
#define        STACK_h
extern /****void CodeArea_0(void)*****/;
extern /****void CodeArea_1(void)*****/;
extern /****void CodeArea_2(void)*****/;
#endif 当然这块代码的用法还有很多,这里只举例了一种配合extern关键字的使用方法。
(文章结尾还会更多的介绍一下 #ifdnef #endif的)
<hr/>有了#define 的支持以及 extern的指向就可以实现多文件的简单链接调用了↓
下面写一个简易的凯撒密码环的加密程序来做一个多文件调用的实验↓
库头文件部分
/* HeadGroup.h */
#pragma once
#include        "stdio.h"
#include        "stdlib.h" 链接头文件部分
/* stack.h */
#ifndef STACK_h
#define STACK_h

extern int Caesar(void);

#endif CaesarFunction函数部分
#include        "stdafx.h"
#include        "stack.h"
int Caesar(void)
{
        int Iturn;
        long Lpointer=0;
        char CPassward[50];
        printf("input original PASSWORD ------>");
        scanf("%s",CPassward);
        printf("setting Iturn ");
        scanf("%d",&Iturn);
        while(CPassward[Lpointer]!='\0')
        {
                CPassward[Lpointer]+=turn;
                Lpointer++;
        }
        printf("your encrypted PASSWORD ------>");
        puts(CPassward);
        return 0;
} main函数部分
#include        "stdafx.h"
#include        "stack.h"
int main(void)
{
        Caesar();
        return 0;
} 嫌麻烦的同学可以把调用文件换成 HelloWorld (doge ↑
写好头文件 就可以直接在main方法中直接调用咱们写好的程序文件了。
后记- #ifndef #endif 与 #pragma once 的区别

为了避免同一个头文件被包含(include)多次,C/C++中有两种宏实现方式:
一种是#ifndef #endif 方式;另一种是#pragma once方式。
在能够支持这两种方式的编译器上,二者并没有太大的区别。但两者仍然有一些细微的区别。
<hr/>#ifndef


#ifndef的方式受C/C++语言标准支持。它不仅可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含。
当然,缺点就是如果不同头文件中的宏名不小心“撞车” 可能就会导致你看到头文件明明存在,但编译器却硬说找不到声明的状况——这种情况有时非常让人郁闷。
由于编译器每次都需要打开头文件才能判定是否有重复定义,因此在编译大型项目时,ifndef会使得编译时间相对较长,因此一些编译器逐渐开始支持#pragma once的方式。
#pragma once

#pragma once 一般由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。
你无法对一个头文件中的一段代码作pragma once声明,而只能针对文件。

其好处是,你不必再担心宏名冲突了,当然也就不会出现宏名冲突引发的奇怪问题。大型项目的编译速度也因此提高了一些。
对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名冲突引发的“找不到声明”的问题,这种重复包含很容易被发现并修正。
另外,这种方式不支持跨平台!

#pragma once 方式产生于#ifndef之后,因此很多人可能甚至没有听说过。目前看来#ifndef更受到推崇。因为#ifndef受C/C++语言标准的支持,不受编译器的任何限制;而#pragma once方式却不受一些较老版本的编译器支持,一些支持了的编译器又打算去掉它,所以它的兼容性可能不够好。
<hr/>END
今天的分享到此结束了,如果在编程学习的路上遇到问题,不妨来我的编程学习交流基地一起来学习探讨
回复

使用道具 举报

3

主题

5

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2025-3-23 05:28:01 | 显示全部楼层
支持,楼下的跟上哈~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表