C_文件包含.h文件和包含.c文件总结
很多人对C语言中的 “文件包含”都不陌生了,文件包含处理在程序开发中会给我们的模块化程序设计带来很大的好处,通过文件包含的方法把程序中的各个功能模块联系起来是模块化程序设计中的一种非常有利的手段。
文件包含处理是指在一个源文件中,通过文件包含命令将另一个源文件的内容全部包含在此文件中。在源文件编译时,连同被包含进来的文件一同编译,生成目标目标文件。
多文件程序: 是在源文件编译时把多个文件进行编译、连接在一起生成一个可执行文件。
包含.c文件: 按照我们上边的说法则是把多个文件合并为一个文件进行编译。
(1)包含.c文件:
1: //file1: main.c
2: #include
3: #include "fun.c"
4: int main()
5: {
6: int a=5,b=19;
7: c = a;
8: sun(a,b);
9: printf("c=%d\n",c);
10: return 0;
11: }
12: //end of file1
1: //file2: fun.c
2: int c=0;
3: void sun(int a, int b)
4: {
5: printf("a+b=%d\n",a+b);
6: c=0;
7: printf("c=%d\n",c);
8: }
9: //end of file2
10:
编译命令:
gcc main.c -o main
gcc -E main.c -o main.cpp
在main.cpp文件末尾可以看来下面一段代码:
1: //main.cpp文件中
2: 931 # 2 "main.c" 2
3: 932 # 1 "fun.c" 1
4: 933 //注意这里是fun.c里边的内容
5: 934 int c=0;
6: 935 void sun(int a, int b)
7: 936 {
8: 937 printf("a+b=%d\n",a+b);
9: 938 c=0;
10: 939 printf("c=%d\n",c);
11: 940 }
12: //这里是main函数
13: 941 # 3 "main.c" 2
14: 942 int main()
15: 943 {
16: 944 int a=5,b=19;
17: 945 c = a;
18: 946 printf("c=%d\n",c);
19: 947 sun(a,b);
20: 948 printf("c=%d\n",c);
21: 949 return 0;
22: 950 }
同样是上边的例子,把main.c中“ #include "fun.c" ”注释掉,加上一句:“extern int c;”因为 c 变量在另外一个文件(fun.c)中定义。
1: //file1: main.c
2: #include
3: //#include "fun.c" //注释掉
4: extern int c; //添加这一句
5: int main()
6: {
7: int a=5,b=19;
8: c = a;
9: sun(a,b);
10: printf("c=%d\n",c);
11: return 0;
12: }
13: //end of file1
14:
15:
16: //file2: fun.c
17: int c=0;
18: void sun(int a, int b)
19: {
20: printf("a+b=%d\n",a+b);
21: c=0;
22: printf("c=%d\n",c);
23: }
24: //end of file2
编译命令:
gcc -c fun.c -o fun.o #编译fun.c
gcc main.o fun.o -o main #用main.o fun.o生成main
1. 包含.c文件的方法: 容易产生"重定义",大家想想如果一个工程中有多个文件都同时包含了某一个件,那么这个被包含文件的内容就会被复制到多个文件中去,也就相当于每个包含该文件的文件中都定义被包含文件中的变量和函数,这样在链接时就会产生"重定义"错误。
上边这个例子大家会发现,在main.c中需要加上“extern int c;”这样一句声明,如果包含的文件较多?如果全局变量较多?...这个我们可以省掉吗?回答是肯定的!方法就是给它写上一个头文件。
1: //file1: main.c
2: #include
3: #include "fun.h" //fun.c修改为fun.h
4: //extern int c; //这行也不要了
5: int main()
6: {
7: int a=5,b=19;
8: c = a;
9: sun(a,b);
10: printf("c=%d\n",c);
11: return 0;
12: }
13: //end of file1
1:
2: //file2: fun.c
3: #include "fun.h"
4: int c=0; //变量c的定义
5: void sun(int a, int b) //函数sun()的定义
6: {
7: printf("a+b=%d\n",a+b);
8: c=0;
9: printf("c=%d\n",c);
10: }
11: //end of file2
1: //file3: fun.h
2: extern int c; //把c声明为外部可用的
3: void sun(int a, int b); //sun()函数的声明
4: //end of file3
(1) 对应的.c文件中写变量、函数的定义
(2) 对应的.h文件中写变量、函数的声明
(3) 如果有数据类型的定义 和 宏定义 ,请写的头文件(.h)中
(4) 头文件中一定加上#ifndef...#define....#endif之类的防止重包含的语句
(5) 模块的.c文件中别忘包含自己的.h文件
C_文件包含.h文件和包含.c文件总结的更多相关文章
- 配置apue的头文件apue.h和unp的头文件anp.h
配置apue的头文件apue.h和unp的头文件anp.h 如果要使用gcc -g 来生成可调试文件一定要修改Make.defines.linux文件中的CFLAGS变量 修改为:CFLAGS=-an ...
- Visual Studio中头文件stdafx.h的作用
在较新版的Visual Studio中,新生成的C++项目文件的的头文件夹下会默认有头文件stdafx.h,而源文件夹下则默认有源文件stdafx.cpp,手动将这些文件删除后,编译时系统还会报错.下 ...
- 在源文件(.c)和头文件(.h)中声明和定义的区别——C语言
最近在看多文件编程的时候遇到的一个问题,本来以为理解了声明和定义的区别(然而并没有····),也算是重新认识了一次声明和定义,下面上代码 情形一:在源文件(.c)中 相信大部分读者对声明和定义的理解是 ...
- 第3章 文件I/O(2)_文件I/O系统调用及文件描述符
2. 文件I/O系统调用及文件描述符 2.1 文件I/O系统调用 (1)主要函数 函数 功能 函数 功能 open() 打开文件 read() 读取文件 creat() 创建文件 write() 写入 ...
- APUE包含头文件"apue.h"问题
下载源码 从unix高级编程书籍官网下载书籍的上的所有源码. wget http://www.apuebook.com/src.tar.gz 解压这个文件 tar -zxvf src.tar.gz 解 ...
- C++中#include包含头文件带 .h 和不带 .h 的区别
C++中#include包含头文件带 .h 和不带 .h 的区别? 如 #include <iostream> 和 #include <iostream.h> 包含的东西有哪些 ...
- Path,Files巩固,题目:从键盘接收两个文件夹路径,把其中一个文件夹中(包含内容)拷贝到另一个文件夹中
这个题目用传统的File,InputStream可以做,但是如果用Files,Path类做,虽然思路上会困难一些,但是代码简洁了很多,以下是代码: import java.io.IOException ...
- VFS 上传文件到sftp 报错 包含中文路径 或者中文文件名称
之前用Apache commons-vfs工具进行ftp操作(FTP服务器是 FileZilla Server) 上传本地文件 到 ftp服务器上,如果文件名称 包含 中文 报错 org.apache ...
- java实现将包含多个<REC>的文件拆成若干只包含一个<REC>的文件
遍历文件夹里的文件,将包含多个<REC>的文件拆成若干只包含一个<REC>的文件 package com.prepub; import java.io.BufferedRead ...
随机推荐
- oracel become INDEX UNUSABLE
1. IMPORT PARTITION or conventional path SQL*Loader. 2. Direct-path SQL*Loader leaves affected local ...
- ubuntu 下安装配置open-iscsi并自动挂载
1.安装open-iscsi apt-get install open-iscsi 2.发现iscsi-target(ISCSI服务器IP:192.168.1.104) iscsiadm -m dis ...
- MySQL Event计划任务刷慢日志
前言 最近在尝试一个日志系统graylog来收集mysql的慢查询日志提,供后续的分析.监控和报警等.测试步骤已经到日志已成功收集到graylog,测试时需要刷一些慢查询日志出来.为了刷比较多的日志和 ...
- 使用autoconfig
1. 增加maven 依赖 <properties> <maven.compiler.target>1.8</maven.compiler.target> < ...
- 〖Android〗/system/etc/event-log-tags
一博客中,一段的注释的解释:[From: http://blog.csdn.net/hustpzb/article/details/8525324] /** * Access to the syste ...
- Android逆向之旅---带你爆破一款应用的签名验证问题
一.前言 在之前的文章中说过Android中的安全和破解是相辅相成的,为了防止被破解.非常多应用做了一些防护策略.可是防护策略也是分等级.一般简单的策略就是混淆代码和签名校验.而对于签名校验非常多应用 ...
- 基于CUDA的粒子系统的实现
基于CUDA的粒子系统的实现 用途: 这篇文章作为代码实现的先导手册,以全局的方式概览一下粒子系统的实现大纲. 科普: 对粒子进行模拟有两种基本方法: Eulerian(grid-based) met ...
- 使用spring的@Async异步执行方法
应用场景: 1.某些耗时较长的而用户不需要等待该方法的处理结果 2.某些耗时较长的方法,后面的程序不需要用到这个方法的处理结果时 在spring的配置文件中加入对异步执行的支持 <beans x ...
- try/except/else语句
# -*- coding: utf-8 -*- #python 27 #xiaodeng #Python学习手册 868 #try/except/else语句 #try语句分句形式 except: # ...
- 【laravel5.4】 Composer移除依赖
1.在一次使用composer安装依赖的时候,安装错了包,在其中文网站却找不到移除依赖的命令,只好使用按照官网说法: 为了从命令行获得帮助信息,请运行 composer 或者 composer lis ...