C语言主程序如何引用外部源代码中的函数
Introduction
代码要实现比较复杂的功能时,往往会包含非常多的函数。
当我们想再向其中添加其他功能或修改一些功能时,主程序所在的源代码会越来越冗长,查找并准确地修改某功能对应的函数也变得十分困难。
这时候我们不禁希望拥有一个干净简洁的主程序,就像大树的枝干,把每一个“分支”(即不同的功能模块)集成到一个专门的源代码文件中,方便查找和修改;需要添加全新功能时,写一个新的文件包含进主程序文件即可。
下面以经典Hello wolrd为例,简要阐明如何实现这一想法 —— 在主程序中引用外部源代码中的函数。
Method
- 先写一个常规的 hello world,并且编译运行它:
touch hello.c //linux下终端创建源代码文件
在 hello.c
中写入
#include <stdio.h>
int main(void)
{printf("Hello World!\n");return 0;
}
用 gcc
命令编译为hello文件,然后 ./
运行一下
Well done!
- 接下来,我们试图把输出“Hello world!”的这个功能封装到一个名为Hello的函数中,并且把这个函数给移到别的文件。
此时我们想要的主程序代码是这样的:
#include <stdio.h>
int main(void)
{ Hello();return 0;
}
其中,这个Hello函数定义应该是这样:
void Hello(void)
{printf("Hello world again!"); #为了区别于第一次的输出,这里加了again
}
可是怎么才能跨文件调用这个Hello函数呢?
- C语言中,使用函数通常需要经过 声明、定义、引用,外部文件中的函数也不例外。
所以我们首先在同一个目录下再创建另外两个文件:
touch declaration.h functions.c //这是linux下的终端操作
我们现在有三个文件了:
- hello.c
主程序所在的源文件(大树的“树干”,作用是引用)
- declaration.h
专门用于声明函数的头文件(最好起个更短的名字 )
- functions.c
定义函数的源文件(大树的“分支”)
- 写函数声明和定义
- 在
declaration.h
中声明函数Hello:
void Hello(void);
Tips:*此后每新加一个函数,就在该声明头文件中添一行即可*
- 在
functions.c
中定义函数Hello:
void Hello() #函数类型和参数都为空,要和声明对应一致
{printf("Hello world again!");
}
- 在
hello.c
中使用/引用函数Hello:
#include <stdio.h>
#include "declaration.h" #在主函数开始前添加包含函数声明的头文件 declaration.h
int main(void)
{ Hello(); #试图调用的外部函数return 0;
}
#include "functions.c" #包含函数定义的外部文件 functions.c
Tips: #include < > 是从C语言标准库中查找头文件;#include " " 是从源代码所在目录中查找头文件,一般自己编写的头文件用引号。
引用要比声明和定义略显复杂,需要使用两个#include
,用于包含声明函数的头文件,和定义函数的.c文件。需要特别注意的是,声明头文件必须放在main函数前面,不然会报错找不到这个函数!
- 运行一下试试看!
Well done!
现在我们已经知道怎么正确地在主程序中引用外部函数了,但实际应用中我们势必面临更多类型的函数,就算没多复杂,它至少会有那么几个变量。
所以我们想知道,跨文件函数中的变量要怎么定义呢?
——答案很简单,和不跨文件的一模一样!
Further example
下面的例子声明了两个变量,数组a[]
在主函数外(相当于全局变量),b[]
在主函数内(只在主函数内有效的局部变量)。
#include <stdio.h>
#include "declaration.h"
char a[20] = "Hello wolrd A!"; #相当于全局变量
int main(void)
{char b[20] = "Hello wolrd B!"; #相当于局部变量Hello();return 0;
}
#include "functions.c"
我们在外部函数Hello中使用这两个变量看看效果:
void Hello()
{printf(a);printf(b);printf("Hello world again!\n");
}
编译运行一下:
运行结果告诉我们,变量b没有声明(undeclared),不能使用。
- 把变量b也放在main函数前面就可以使用了:
hello.c
#include <stdio.h>
#include "declaration.h"
char a[20] = "Hello wolrd A!"; #相当于全局变量
char b[20] = "Hello wolrd B!"; #相当于全局变量
int main(void)
{Hello();return 0;
}
#include "functions.c"
function.c
void Hello()
{printf(a);printf(b);printf("Hello world again!\n");
}
编译运行:
- 事实上,使用
#include
包含外部函数文件相当于在主程序后面“续”上一段代码,大可合起来看作一个源代码。 - 所以,在外部函数中改变全局变量a,b的值会导致主程序中变量值的改变,新手应当注意这一点,以避免一些不易发现的错误。
- 我们试试:
hello.c
#include <stdio.h>
#include <string.h> #使用字符串数组函数时需要的头函数
#include "declaration.h"
char a[20] = "Hello wolrd!"; #相当于全局变量
int main(void)
{printf(a);Hello();printf(a);return 0;
}
#include "functions.c"
function.c
void Hello()
{printf(a);strcpy(a, "Goodnight world!\n"); #使用字符串copy函数,给数组a重新赋值printf(a);
}
- 结果会是什么呢?
Completely done !
现在你已经学会怎么修剪打理“程序树”的枝干了,开始真正的编程工作吧!
C语言主程序如何引用外部源代码中的函数相关推荐
- c语言非静态成员引用方式,C++中静态成员函数访问非静态成员的实例
C++中静态成员函数访问非静态成员的实例 实现代码: #include /* 静态成员函数只能访问静态数据成员.静态成员函数和类以外的函数和数据,不能访问非静态数据成员,但静态成员函数或静态数据成员可 ...
- WPF引用外部类库中的资源文件提示不能找到的解决方法
WPF引用外部类库中的资源文件提示不能找到的解决方法 参考文章: (1)WPF引用外部类库中的资源文件提示不能找到的解决方法 (2)https://www.cnblogs.com/scy251147/ ...
- C语言beep中有什么作用,C++中发声函数Beep用法
当我们听到电脑上出现美妙的旋律的时候,是不是发现这是一个很伟大的开发,这就是C语言中Beep,下面爱站技术频道小编就给大家介绍C++中发声函数Beep用法. 下面是正文: •其实啊,Windows A ...
- 《TensorFlow 实战》第五章源码 5.2 源代码中权重函数中初始化函数 tf.truncated_normal(shape, stddev=0.1) 中 stddev 的重要性
<TensorFlow 实战>黄文坚 黄源著 源码地址:https://github.com/sundaygeek/tensorflow-in-action/blob/master/5_ ...
- 调用外部 DLL 中的函数(显示调用)
unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Di ...
- r语言写内曼最优分配_R中最优化函数optim
最优化函数optim 目标函数: $$f(x_1,x_2)=(1-x_1)^2+100(x_2-x_1^2)^2$$ 该函数全局最小值在($x_1=1,x_2=1$)时取到. 下面这种写法是因为有多个 ...
- Angular7中引用外部JS文件
Angular7中引用外部JS文件,步骤如下: 1. 将引入的js文件放到项目的src/assets下 2. 在angular.json文件中找到scripts项并配置js文件的相对路径 3. 在sr ...
- 页面中如何引用外部的HTML(四种方法)
页面中如何引用外部的HTML(四种方法) 一.总结 一句话总结:a.iframe标签 b.ajax引入代码片段 c.link import的方法导入 d.re ...
- 【C 语言】动态库封装与设计 ( 动态库调用环境搭建 | 创建应用 | 拷贝动态库相关文件到源码路径 | 导入头文件 | 配置动态库引用 | 调用动态库中的函数 )
文章目录 一.在 Visual Studio 2019 中创建 " 控制台应用 " 程序 二.拷贝 xxx.lib.xxx.dll.xxx.h 到源码路径 三.导入 xxx.h 头 ...
最新文章
- idea设置开发方式
- java中hashCode()在Map中的作用
- OEA 框架演示 - 快过原型的开发
- python定义一个空数组_python如何创建空数组?
- php try catch
- 关于 mysql.test 数据库
- java后端怎么返回音频流_Java语言中的IO流read()方法返回值为什么是int而不是byte?...
- 文字生成视频,只需一步
- 自动运维化tools篇2:通过SSH信任关系,批量修改LINUX密码
- Keil(MDK) 5 软件安装教程
- 腾讯智图让我的webp压缩感觉像白忙活一样
- 几种不同的json格式解析
- 电商平台10大商业与盈利模式
- C相关笔试题或者面试题中的概念以及技巧题2
- 一文搞懂天使轮、A轮、B轮、C轮、D轮融资
- 手机处理器天梯图2021
- 神经网络实现手写数字识别
- android之基于百度语音合讯飞语音识别的语音交互
- 火车头采集器V10下载-火车头采集器免费
- VAPS XT开发入门教程02:安装配置
热门文章
- Linux在线安装MySQL
- java设置右击菜单_windows7中右键菜单添加powershell
- Matlab/simulink MIL自动化测试工具使用说明
- 强势来袭!取代传统PC开辟新增长极,这款“云电脑”凭啥?
- atom编辑器的常用插件
- 计算机硬件闫宏印答案,计算机硬件技术基础
- System.Diagnostics.Process 用处
- 智慧农业“黑科技”,FCU1101智能灌溉控制器方案
- 海康摄像头与萤石云web集成记录
- 迎接全电发票的管理方式,iBox电子会计档案管理系统