##########################################################################################################

新的理解:

  

  

 然后我的wangchao.h文件内容

 //防止头文件重复包含
#pragma once
//我的这个是C语言代码,但是以后,我可能把我的这个C语言代码和C++融合在一起,那么
//我就得兼容C++编译器 //当前如果是C++编译器,就按照C编译器编译 #ifdef __cplusplus//这个是C语言编译器已经有的一个宏 //如果当前是C语言编译器,想按照C++标准编译
extern "C"
{ #endif
//但是上面有半个括号,要是代码很多的话,很容易发生问题,所以 我们一般再加了下面的代码。 //中间写你的函数声明,就是你的接口。
void hanshu(); //下面的是应该加的代码
#ifdef __cplusplus
}
#endif

我的b.c的代码:

 #include"wangchao.h"

 void hanshu()
{
printf("你获得赛点\n");
}

我的a.c的代码

 //函数的实现
#include<stdio.h>
#include"wangchao.h"
int main()
{
printf("jldksajf\n");
hanshu();
return ;
}

为啥,我在a.c中调用wangchao.h  就能使用那个hanshu()  ?

比方说 我在aaa.h里定义了一个函数的声明,然后我在aaa.h的同一个目录下建立aaa.c , aaa.c里定义了这个函数的实现,然后是在main函数所在.c文件里#include这个aaa.h

然后我就可以使用这个函数了。 main在运行时就会找到这个定义了这个函数的aaa.c文件。这是因为:main函数为标准C/C++的程序入口,编译器会先找到该函数所在的文件。

假定编译程序编译myproj.c(其中含main())时,发现它include了mylib.h(其中声明了函数void test()),那么此时编译器将按照事先设定的路径(Include路径列表及代码文件所在的路径)查找与之同名的实现文件(扩展名为.cpp或.c,此例中为mylib.c),如果找到该文件,并在其中找到该函数(此例中为void test())的实现代码,则继续编译;

如果在指定目录找不到实现文件,或者在该文件及后续的各include文件中未找到实现代码,则返回一个编译错误.

其实include的过程完全可以“看成”是一个文件拼接的过程,将声明和实现分别写在头文件及C文件中,或者将二者同时写在头文件中,理论上没有本质的区别。以上是所谓动态方式。

http://www.cnblogs.com/infiniti/archive/2013/03/19/2968689.html

###############################################################################################

首先是  我创建多个.c和.h文件   然后他们的目录关系是:

      

在 b.h中的内容

 #include"c.h"

 void hanshu();

在c.h中的内容

 #include"b.h"

 void hanshu1();

在b.c中的内容

 void hanshu()
{
printf("你获得赛点\n");
}

在c.c中的内容

 void hanshu1()
{
hanshu();
printf("我是CCCC");
}

在a.c中内容

 //函数的实现
#include<stdio.h>
#include"c.h"
int main()
{
printf("jldksajf\n");
hanshu1();
return ;
}

很明显,我的代码中,在b的代码中包含c,在c的代码中包含b。然后 在我调用那个c中的函数hanshu1()时,就会报错

然后  我加了改动

    

在c.h中,我加了这个:

    

然后  就可以通过了。

##############################################################################################3

接着上面的问题,我想在我的.cpp文件中用刚刚的那个c,h文件,于是 我的b.h   b.c  c.c  c.h代码没动,aa.cpp中的代码是

 //函数的实现
#include<stdio.h>
#include"c.h"
int main()
{
printf("jldksajf\n");
hanshu1();
return ;
}

但是  不行  会报错。

于是  我加了下面的改动:

    

我的那个b.h的改动是:
    

然后就可以运行了,所以  你现在知道  为啥  多文件时,要加上面的代码,  这就是来由。

2)#ifndef和#pragma once的更多相关文章

  1. 看了看 #ifndef 和#pragma once 的区别

    刚开始学习程序的时候,老师就说过用#ifndef 这样的结构防止头文件被重复包含,所以就没有关心那么多.今天可能由于自家底层系统缘故,陈工说最好还是用#pragma once ,于是查了下两个的区别, ...

  2. c++中#ifndef ... 与#pragma once的区别

    原文链接:https://www.cnblogs.com/qiang-upc/p/11407364.html (1)C/C++防止头文件被include多次的方法:#ifnde..  及  #prag ...

  3. pragma

    在所有的预处理指令中,#pragma指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个 编译器给出了一个方法,在保持与C和C++语言完全兼容的 ...

  4. 嵌入式Linux驱动学习之路(二十六)DM9000C网卡驱动程序

    基于DM9000C的原厂代码修改dm9000c的驱动程序. 首先确认内存的基地址 iobase. 确定中断号码. 打开模块的初始化函数定义. 配置内存控制器的相应时序(结合DM9000C.C的手册). ...

  5. 当年只会C# 所以写C++就成这样了! log4cplus -> log4net

    属实C++不会. 目前帮朋友弄个小项目需要小折腾一下. c# 一直采用 log4net ,c++的呢,找找有个log4cplus  知识有限,做个通用类吧.别把精力放在这里. 动手创建个静态类. 为了 ...

  6. dm9000c 移值新内核 linux-4.1.24

    错误 1 /home/dm9000/dm9dev9000c.c:309: error: conflicting types for 'phy_read'include/linux/phy.h:637: ...

  7. IOS AFNetworking配置进IOS

    Prefix Header 中填入绝对路径 //PCH 里面加入这个写代码 #ifndef TARGET_OS_IOS #pragma mark ---------- for AFNetwork st ...

  8. 转:EasyHook远程代码注入

    EasyHook远程代码注入 最近一段时间由于使用MinHook的API挂钩不稳定,经常因为挂钩地址错误而导致宿主进程崩溃.听同事介绍了一款智能强大的挂钩引擎EasyHook.它比微软的detours ...

  9. libCEF总结01下载、编译、入门

    目 录 第1章 下载    1 1.1 下载    1 1.2 合并    1 第2章 cmake    4 2.1 编译简介    4 2.2 下载cmake    4 2.3 运行cmake    ...

随机推荐

  1. linux 下shell 编写脚本

    linux 下shell 编写脚本: 1.程序结构练习:编写一个脚本,给定一个正整数,计算出这个数所有位的数字之和. 例如:程序给定输入123,那么应该返回1+2+3=6. 2.程序结构练习:编写一个 ...

  2. kube-controller-manager配置详解

    KUBE_MASTER="--master=http://10.83.52.137:8080" KUBE_CONTROLLER_MANAGER_ARGS=" "

  3. Python调用OpenCV读显写

    OpenCV提供了python的接口,而且很重要的一点是python下的很多接口名与C++的接口名是一样的,这一篇先记录python调用OpenCV去读取图像.显示图像和保存图像. 1.OpenCV读 ...

  4. 目录服务不能与此服务器复制,因为距上一次与此服务器复制的时间已经超过了 tombstone 生存时间。

    1.PDC数据正常 2.其他DC无法复制,报如下错误:目录服务不能与此服务器复制,因为距上一次与此服务器复制的时间已经超过了 tombstone 生存时间. 3.直接强制复制即可 repadmin / ...

  5. hook键盘钩子_非dll

    unit Unit1; // download by http://www.codefans.net interface uses Windows, Messages, SysUtils, Class ...

  6. rewrite例子集合

    在 httpd 中将一个域名转发到另一个域名 虚拟主机世界近期更换了域名,新域名为 www.wbhw.com, 更加简短好记.这时需要将原来的域名 webhosting-world.com, 以及论坛 ...

  7. 吴裕雄--天生自然MySQL学习笔记:MySQL NULL 值处理

    MySQL 使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作. 为了处理这种情况,MySQL提供了三大运算符 ...

  8. jupyter notebook 安装配置使用,+目录插件安装

    1.安装 pip3 install jupyter 2.配置 2.1. 生成一个 notebook 配置文件 jupyter notebook --generate-config /root/.jup ...

  9. Maven相关:mvn的配置和简单命令

    1.配置mvn: 点击链接 http://maven.apache.org/download.cgi 下载 解压到文件夹: 配置系统环境变量: 测试:mvn -v 2.mvn命令: 1. 显示版本信息 ...

  10. LeetCode——48. 旋转图像

    给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: 你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵.请不要使用另一个矩阵来旋转图像. 示例 1: 给定 m ...