范文一:头文件和源文件的区别
c 语言笔记--头文件和源文件的区别 在那电子|学 习电子|了 解电子|电 子信息|体 验世界 先进科 技|) o: [" r! `" G$ e! d) K' C; f 首先,我们可以将所有东西都放在一个.cpp 文件内. 然后编译器就将这个.cpp 编译成.obj,obj 是什么东西? 我的梦想, 电子入 门学习 ,入门 到精通& s) ~/ N2 s " F, T2 q)
Y 就是编译单元了.一个程序,可以由一个编译单元组成, 也可以有多个编译单元组成. 如果你不想让你的源代码变得很难阅读的话, 在那电子,应用电 子,模拟 电子, 数字 电子,$ h) |+ U! Q9 D2 _, f0 e* h( X 就请使用多个编译单元吧.(一个函数不能放到两个编译单元里面,但两个以上 就可以分别放在一个单元,也就是 cpp 里面) " ~* n, M( X) d; |: s* K8 Q 在那电子,应用电 子,模拟 电子, 数字 电子,' z: k7 j. a) N H7 @( K, G* H 我的梦想,电子入 门学习, 入门到 精通! n, M' M- X. K& S# k! C 那么就是一个.cpp 对应一个.obj,然后将所有的 obj 链接起来(通过一个叫链接器的程序), ( \& i; n2 \+ B 组成一个.exe,也就是程序了. 如果一个.cpp 要用到另一个.cpp 定义的函数怎么办? 只需在这个.cpp 种写上他的函数声明 www.gmzn.cn, N : U5 w/ \/ `: O8 w3 ^ 就可以了.其余工作由链接器帮你完成,你可以随便调用该函数. 在那电子|学习电子|了 解电子|电 子信息|体 验世界 先进科 技|% F+ E6 Q3 w& }' S/ W 链接器将所有的 obj 连接起来,但是如果碰巧有相同的函数或外部变量怎么办?他如何识
别? f$ g$ ]" [$ b www.gmzn.cn3 ]- S ?( r% m; {1 I" y " p &
A! F+ d# D1 一般来说是不能允许在同一个程序中,出现两个一样的函数名或外部变量名. 在那电子, y & x; ~8 A9 j; Q- C3 i 但是只得庆幸的是,c++可以通过一种叫做链接属性的关键字来限定,你这个函数是属于整个 程序 在那电子# A+ L2 Y7 |4 G/ {* e1 j 公用的,还是只是在一个编译单元 obj 里面使用的. 我的梦想,电子入门 学习,入 门到精 通/ M . R m6 r4 ^( {# V 这些关键字就是 extern 和 static; extern 是外部链接的意思,也就是除了这个单元,外部的单 元 在那电子, 应用电 子,模 拟电子, 数字电 子," r; m' v8 c+ V( J3 j! w# q 也是能够访问这个函数的.static 是内部链接,自属于自己单元. 说了这么久,还没有说.h 的作用呢? 在那电子,应用电子, 模拟电 子,数字 电子,+ X# ]# n! L6 D 其实没有.h 也能很好的工作,但是当你发现一个外部链接的函数或外部变量,需要许多份 进科技|$ [7 G- k* |% w; s) H: `/ S www.gmzn.cn: S+ q. d 5 Y9 Z( Z2 z) c 在那电子|学习电子|了 解电子|电 子信息|体 验世界 先 声明,因为 c++这种语言,在使用函数和变量的时候,必须将他声明,为何要声明?声明之后才 www.gmzn.cn" _4 y ; ?7 @.
i
知道他的规格,才能更好的发现不和规格的部分.你别妄想一个编译单元,会自动从另一个 A V' n1 T* _& B 在那电子,应用 电子,模 拟电子 ,数字 电子,, S* 编译单元那里得到什么信息,知道你是如何定义这个函数的. 8 A5 [- c1 L) B; N. l( v5 R 所以说,只要使用到该函数的单元,就必须写一份声明在那个.cpp 里面,这样是不是很麻烦, www.gmzn.cn6 J1 u/ {+ }- |- `5 R; g 而且,如果要修改,就必须一个一个修改.这真让人受不了. .h 就是为了解决这个问题而诞生,他包含了这些公共的东西.然后所有需要使用该函数的.cpp, 只需要 在那电子, 应用电 子,模 拟电子, 数字电 子, }- I5 j, O* p/ `; P 用#include 包含进去便可.以后需要修改,也只是修改一份内容. 在那电子) e$ \9 L8 H Q ; Y; `+ D 请注意不要滥用.h,.h 里面不要写代码,.h 不是.cpp 的仓库,什么都塞到里面. 如果在里面写代码,当其他.cpp 包含他的时候,就会出现重复定义的情况, 比如将函数 func(){printf};放到头文件 a.h,里面还有一些 a.cpp 需要的声明等; 我的梦想, 电子入 门学习 ,入门 到精通. v" ]2 h : x+ V4 @/ b 然后你发现 b.cpp 需要用到 a.cpp 里面的一个函数,就很高兴的将 a.h 包含进来. 在那电子' U! K+ h Z) w1 s www.gmzn.cn$ u 4 ];
j; s: X0 j5 E/ A 注意,#include 并不是什么申请指令,他就是将指定的文件的内容,原封不动的拷贝 进来. 在那电子,应 用电子, 模拟电 子,数字 电子,# v8 K" ]; ?( h* H1 b# [8 ?+ x" f & D+ D9 G3 U- E7 U- U1 C 在那电子, 应用电 子,模 拟电子, 数字电 子,& H' M( F4 d) e4 Q& P, D4
f 这时候实际上 a.cpp 和 b.cpp 都有一个 func()函数的定义. 在那电子|学 习电子|了 解电子|电 子信息|体 验世界 先进科 技|, U; j! @6 ]; k! s # q( V 如果这个函数是内部链接 static 的话,还好,浪费了一倍空间; 我的梦想, 电子入 门学习 ,入门 到精通 0 Q- ~( }* @+ `' |0 Z 在那电子|学习电子|了解 电子|电子 信息|体验 世界先 进科技|3 g8 p6 F5 E4 N+ J 如果是 extern,外部链接(这个是默认情况),那么根据在同一个程序内不可出现 在那电子+ E : E9 r6 B: j3 f3 _8 {. _ 同名函数的要求,连接器会毫不留情给你一个连接错误! ;如果你还不太理解.那么就尝试不用 h,只用多个 cpp 看看应该如何写. ) Y/ `7 z7 o& P4 K% M+ n 尝试在两个 cpp 中写同名函数.看看是否链接出错. / ^5 p+ H' W+ G6 H) C0 j9
y 尝试在 cpp 使用其他 cpp 定义的函数.看看应该如何做. 头文件是没有编译意义的,一般只是编译.cpp 生成.obj. 在那电子; {5 O $ @* z& u+ ~4 R 但是.cpp 里面有#include 将指定头文件(其实任何文件都行)插进来,组成完整的.cpp. 在那电子( ^, v, m- q* G% l 在那电子,应用 电子, 模拟电 子,数字 电子,' I# f8 a7 ~% y, U) j;
范文二:关于CMD文件和GEL文件的区别
今天看到一个文档说CMD文件和GEL文件的区别的,觉得还不错,分享一下。
一、cmd文件分析
1,系统定义:
.cinit 存放C程序中的变量初值和常量;
.const 存放C程序中的字符常量、浮点常量和用const声明的常量;
.switch 存放C程序中switch语句的跳针表;
.text 存放C程序的代码;
.bss 为C程序中的全局和静态变量保留存储空间;
.far 为C程序中用far声明的全局和静态变量保留空间;
.stack 为C程序系统堆栈保留存储空间,用于保存返回地址、函数间的参数传递、存储局部变量和保存中间结果;
.sysmem 用于C程序中malloc、calloc和realloc函数动态分配存储空间。
2,用户定义:
#pragma CODE_SECTION (symbol, "section name"); #pragma DATA_SECTION (symbol, "section name")
单个地址的时候可以使用 #define
如 #define my_data *(volatile unsigned int*)0x000C
在数组变量时 使用#pragma 宏
如
XXX.h/XXX.c
#pragma DATA_SECTION(my_data,".data_section")
unsigned char my_data[1024];
在xxx.cmd中建立.data_section并赋予地址就可以了。
3.cmd作用
cmd由3部分组成:
1)输入/输出定义:.obj文件:链接器要链接的目标文件;.lib文件:链接器要链接的库文件;.map文件:链接器生成的交叉索引文件;.out文件:链接器生成的可执行代码;链接器选项;
2)MEMORY命令:描述系统实际的硬件资源;
3)SECTIONS命令:描述“段”如何定位。
Link的cmd文件用于DSP代码的定位。由于DSP的编译器的编译结果是未定位的,DSP没有操作系统来定位执行代码,每个客户设计的DSP系统的配置也不尽相同,因此需要用户自己定义代码的安装位置。以C5000为例,基本格式为:
-o sample.out
-m sample.map
-stack 100
sample.obj meminit.obj
-l rts.lib
MEMORY {
PAGE 0: VECT: origin = 0xff80, length 0x80
PAGE 0: PROG: origin = 0x2000, length 0x400
PAGE 1: DATA: origin = 0x800, length 0x400
}
SECTIONS {
.vectors : {} >PROG PAGE 0
.text : {} >PROG PAGE 0
.data : {} >PROG PAGE 0
.cinit : {} >PROG PAGE 0
.bss : {} >DATA PAGE 1
}
二、gel文件
ccs的gel语言是一种交互式的命令,它是解释执行的,即不能被编译成可执行文件。它的作用在于扩展了ccsstudio的功能,可以用gel来调用一些菜单命令,对DSP的存储器进行配置等等。但是作者建议对于使用仿真器和DSP功能板的仿真环境用户来说,这种GEL语言文件是没必要加入到配置中的。gel语言的重要性在于针对计算机模拟环境的用户,使用gel可以为其准备一个虚拟的DSP仿真环境,但也不是非用不可的。
GEL文件的功能同emuinit.cmd的功能基本相同,用于初始化DSP。但它的功能比emuinit的功能有所增强,GEL在CCS下有一个菜单,可以根据DSP的对象不同,设置不同的初始化程序。以TMS320LF2407为例:
#define SCSR1 0x7018 ;定义scsr1寄存器
#define SCSR2 0X7019 ;定义scsr2寄存器
#define WDKEY 0x7025 ;定义wdkey寄存器
#define WDNTR 0x7029 ;定义wdntr寄存器
StartUp() ; 开始函数
{
GEL_MapReset(); ; 存储空间复位 GEL_MapAdd(0x0000,0,0x7fff,1,1); 定义程序空间从0000-7fff 可读写
GEL_MapAdd(0x8000,0,0x7000,1,1); 定义程序空间从8000-f000 可读写
GEL_MapAdd(0x0000,1,0x10000,1,1); 定义数据空间从0000-10000可读写
GEL_MapAdd(0xffff,2,1,1,1); 定义i/o 空间0xffff可读写
GEL_MapOn(); 存储空间打开
GEL_MemoryFill(0xffff,2,1,0x40); 在i/o空间添入数值40h
*(int *)SCSR1=0x0200; 给scsr1寄存器赋值
*(int *)SCSR2=0x000C; 给scsr2寄存器赋值,在这里可以进行mp/mc方式的转换
*(int *)WDNTR=0x006f; 给wdntr寄存器赋值
*(int *)WDKEY=0x055; 给wdkey寄存器赋值
*(int *)WDKEY=0x0AA; 给wdkey寄存器赋值
}
范文三:.H文件和.C文件的使用区别
在网上找到了一篇关于.h和.c 的文章,复制下来了。以下是正文: 在网上看到一篇关于.H和.C的文章,感觉不错,帖出与大家共享.
一、总述
其实要理解C文件与头文件有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程:
1.预处理阶段;
2.词法与语法分析阶段;
3.编译阶段,首先编译成纯汇编语句,再将之汇编成跟CPU相关的二进制码,生成各个目标文件 ;
4.连接阶段,将各个目标文件中的各段代码进行绝对地址定位,生成跟特定平台相关的可执行文件。
当然,最后还可以用objcopy生成纯二进制码,也就是去掉了文件格式信息。编译器在编译时是以C文件为单位进行的,也就是说如果你的项目中一个C文件都没有,那么你的项目将无法编译,连接器是以目标文件为单位,它将一个或多个目标文件进行函数与变量的重定位,生成最终的可执行文件,在PC上的程序开发,一般都有一个main函数,这是各个编译器的约定,当然,你如果自己写连接器脚本的话,可以不用main函数作为程序入口!!!!
二、举例
有了这些基础知识,再言归正传,为了生成一个最终的可执行文件,就需要一些目标文件,也就是需要C文件,而这些C文件中又需要一个main函数作为可执行程序的入口,那么我们就从一个C文件入手,假定这个C文件内容如下:
#include #include "mytest.h" int main(int argc,char **argv) { test = 25; printf("test.................%d\n",test); } 现在以这个例子来讲解编译器的工作: 1.预处理阶段:编译器以C文件作为一个单元,首先读这个C文件,发现第一句与第二句是包含一个头文件,就会在所有搜索路径中寻找这两个文件,找到之后,就会将相应头文件中再去处理宏,变量,函数声明,嵌套的头文件包含等。然后检测依赖关系,进行宏替换,看是否有重复定义与声明的情况发生,最后将那些文件中所有的东东全部扫描进这个当前的C文件中,形成一个中间“C文件”。 2.编译阶段,在上一步中相当于将那个头文件中的test变量扫描进了一个中间C文件,那么test变量就变成了这个文件中的一个全局变量,此时就将所有这个中间C文件的所有 变量,函数分配空间,将各个函数编译成二进制码,按照特定目标文件格式生成目标文件,在这种格式的目标文件中进行各个全局变量,函数的符号描述,将这些二进制码按照一定的标准组织成一个目标文件。 3.连接阶段,将上一步生成的各个目标文件,根据一些参数,连接生成最终的可执行文件,主要的工作就是重定位各个目标文件的函数,变量等,相当于将个目标文件中的二进制码按一定的规范合到一个文件中再回到C文件与头文件各写什么内容的话题上: 理论上来说C文件与头文件里的内容,只要是C语言所支持的,无论写什么都可以的,比如你在头文件中写函数体,只要在任何一个C文件包含此头文件就可以将这个函数编译成目标文件的一部分(编译是以C文件为单位的,如果不在任何C文件中包含此头文件的话,这段代码就形同虚设),你可以在C文件中进行函数声明,变量声明,结构体声明,这也不成问题!!那为何一定要分成头文件与C文件呢?又为何一般都在头件中进行函数,变量声明,宏声明,结构体声明呢?而在C文件中去进行变量定义,函数实现呢? 原因如下: 1.如果在头文件中实现一个函数体,那么如果在多个C文件中引用它,而且又同时编译多个C文件,将其生成的目标文件连接成一个可执行文件,在每个引用此头文件的C文件所生成的目标文件中,都有一份这个函数的代码,如果这段函数又没有定义成局部函数,那么在连接时,就会发现多个相同的函数,就会报错。 2.如果在头文件中定义全局变量,并且将此全局变量赋初值,那么在多个引用此头文件的C文件中同样存在相同变量名的拷贝,关键是此变量被赋了初值,所以编译器就会将此变量放入DATA段,最终在连接阶段,会在DATA段中存在多个相同的变量,它无法将这些变量统一成一个变量,也就是仅为此变量分配一个空间,而不是多份空间。假定这个变量在头文件没有赋初值,编译器就会将之放入BSS段,连接器会对BSS段的多个同名变量仅分配一个存储空间。 3.如果在C文件中声明宏,结构体,函数等,那么我要在另一个C文件中引用相应的宏,结构体,就必须再做一次重复的工作,如果我改了一个C文件中的一个声明,那么又忘了改其它C文件中的声明,这不就出了大问题了,程序的逻辑就变成了你不可想象的了,如果把这些公共的东东放在一个头文件中,想用它的C文件就只需要引用一个就OK了!!!这样岂不方便,要改某个声明的时候,只需要动一下头文件就行了。 4.在头文件中声明结构体,函数等,当你需要将你的代码封装成一个库,让别人来用你的代码,你又不想公布源码,那么人家如何利用你的库呢?也就是如何利用你的库中的各个函数呢?一种方法是公布源码,别人想怎么用就怎么用;另一种是提供头文件,别人从头文件中看你的函数原型,这样人家才知道如何调用你写的函数,就如同你调用printf函数一样,里面的参数是怎样的?你是怎么知道的?还不是看人家的头文件中的相关声明啊!当然这些东东都成了C标准,就算不看人家的头文件,你一样可以知道怎么使用。 三、各种说法 程序源码中".h"文件与".c"文件有什么区别呀?? 在一个程序源码中,看到了udp.h文件又看到了udp.c文件,不知道这两者是什么关系呀?又有何区别呢?哪位高手前来帮忙,谢谢谢谢。 一级最佳答案:.c就是C语言系列的源文件,以文本形式存在,而.h系列则是头文件,即C系列中存放函数和全局变量的文件,因为C中的函数是被封装起来的,即无法看到其代码。 头文件与之实现文件的的关系 今天在网上看到一篇解释.h与.c(.cpp)的文章,我读完后感到有些地方不妥,特此按照我的 理解,给初学者一些指导~ 你理解简单的含义吗? 关于两者以前的关系,要从N年以前说起了~ long long ago,once aupon a time .......那是一个被遗忘的年代,在编译器只认识.c(.cpp))文件,而不知道.h是何物的年代。那时的人们写了很多的.c(.cpp)文件,渐渐地,人们发现在很多.c(.cpp)文件中的声明语句就是相同的,但他们却不得不一个字一个字地重复地将这些内容敲入每个.c(.cpp)文件。但更为恐怖的是,当其中一个声明有变更时,就需要检查所有的.c(.cpp)文件,并修改其中的声明,啊~简直是世界末日降临! 终于,有人(或许是一些人)再不能忍受这样的折磨,他(们)将重复的部分提取出来,放在一个新文件里,然后在需要的.c(.cpp)文件中敲入#include XXXX这样的语句。这样即使某个声明发生了变更,也再不需要到处寻找与修改了---世界还是那么美好! 因为这个新文件,经常被放在.c(.cpp)文件的头部,所以就给它起名叫做“头文件”,扩展名是.h. 从此,编译器(其实是预处理器)就知道世上除了.c(.cpp)文件,还有个.h的文件,以及一个叫做#include命令。虽然后来又发生很多的变化,但是这样的用法一直延续至今,只是时日久远了,人们便淡忘了当年的缘由罢了。 提到了头文件,就说说它的作用吧~ 想到了林锐GG写的高质量C/C++编程上头文件的作用的简短描述: (1)通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。用户只需要按照头文件中的接口声明来调用库功能,而不必关心接口怎么实现的。编译器会从库中提取相应的代码。 (2)头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件中的声明不一致,编译器就会指出错误,这一简单的规则能大大减轻程序员调试、改错的负担。 预处理是编译器的前驱,作用是把存储在不同文件里的程序模块集成为一个完整的源程序.#include本身只是一个简单的文件包含预处理命令,即为把include的后面文件放到这条命令这里,除此之外,没有其它的用处(至少我也样认为). 我对乾坤一笑兄的观点,十分赞同,基础的东东一定要弄明白. 我下面就乾坤一笑兄的例子做讲,完备他的一些让人迷惑不解的时候~ 例子: //a.h void foo(); //a.c #include "a.h" //我的问题出来了:这句话是要,还是不要? void foo() { return; } //main.c #include "a.h" int main(int argc, char *argv[]) { foo(); return 0; } 针对上面的代码,请回答三个问题: 1.a.c 中的 #include "a.h" 这句话是不是多余的? 2.为什么经常见 xx.c 里面 include 对应的 xx.h? 3.如果 a.c 中不写,那么编译器是不是会自动把 .h 文件里面的东西跟同名的 .c 文件绑定在一起? 第三个问题我给他改了一下:如果 a.c 中不写include<>,那么编译器是不是会自动把 .h 文件里面的东西跟同名的.c文件绑定在一起? 下面是乾坤一笑的原话: 从C编译器角度看,.h和.c皆是浮云,就是改名为.txt、.doc也没有大的分别。换句话说,就是.h和.c没啥必然联系。.h中一般放的是同名.c文件中定义的变量、数组、函数的声明,需要让.c外部使用的声明。这个声明有啥用?只是让需要用这些声明的地方方便引用。因为 #include "xx.h" 这个宏其实际意思就是把当前这一行删掉,把 xx.h 中的内容原封不动的插入在当前行的位置。由于想写这些函数声明的地方非常多(每一个调用 xx.c 中函数的地方,都要在使用前声明一下子),所以用 #include "xx.h" 这个宏就简化了许多行代码——让预处理器自己替换好了。也就是说,xx.h 其实只是让需要写 xx.c 中函数声明的地方调用(可以少写几行字),至于 include 这个 .h 文件是谁,是 .h 还是 .c,还是与这个 .h 同名的 .c,都没有任何必然关系。 这样你可能会说:啊?那我平时只想调用 xx.c 中的某个函数,却 include了 xx.h 文件,岂不是宏替换后出现了很多无用的声明?没错,确实引入了很多垃圾 ,但是它却省了你不少笔墨,并且整个版面也看起来清爽的多。鱼与熊掌不可得兼,就是这个道理。反正多些声明(.h一般只用来放声明,而放不定义,参见拙著“过马路,左右看”)也无害处,又不会影响编译,何乐而不为呢? 翻回头再看上面的3个问题,很好解答了吧? 它的解答如下: 答:1.不一定。这个例子中显然是多余的。但是如果.c中的函数也需要调用同个.c中的其它函数,那么这个.c往往会include同名的.h,这样就不需要为声明和调用顺序而发愁了(C语言要求使用之前必须声明,而include同名.h一般会放在.c的开头)。有很多工程甚至把这种写法约定为代码规范,以规范出清晰的代码来。 2.答:1中已经回答过了。 3.答:不会。问这个问题的人绝对是概念不清,要不就是想混水摸鱼。非常讨厌的是中国的很多考试出的都是这种烂题,生怕别人有个清楚的概念了,绝对要把考生搞晕。 over! 在此里要明确一点,编译器是按照编译单元进行编译的,所谓的编译单元,是指一个.c文件以及它所include的所有.h文件.最直观的理解就是一个文件,一个工程中可以包含很多文件,其中有一个程序的入口点,即我们通常所说的main()函数(当然也可以没有这个函数,程序照样能启动,详细见我的blog中).在没有这个程序入口点的情况下,编译单元只生成目标文件object file(.o文件,windows下叫做.obj). 这个例子中总共包含了二个编译单元,分别是a.c,main.c,按照我所说的,在编译阶段只是生成各自的.o文件.这个阶段不和其它的文件发生任何的关系. 而include这个预处理指令发生在预处理阶段(早先编译阶段,只是编译器的一个前驱处理程 序). .h .c不见得是浮云,脱离了编译器谈这些没有任何的意义,抛开更深层次的这些,比如说,OS如何启动这个文件,PE结构(linux 下为elf)等等。编译器首先要识别这个文件才可能去编译它,这是前提.如果你改了它的扩展名那么你的编译器还能认识它吗~上升到一个更高的层次上看待这个问题,XX兄说的也不错~我想XX兄说的意思就是两者不可因为名字相同就认为两者有什么关系,名字是可以随便的~ 两者之间的联系,我在前面说过了,是由于历史的原因造成的,再加上人的习惯,我想谁也不想多去记那么多文件名吧.(拿我举个例子,一个数据表如果多于30个字段,我就觉得头大了,现在弄的表有的多达上百个字段,真希望那位高人研究出什么好的方法来~,也让我们的世界美好一些~) 乾坤一笑的第三个问题很有代表性,多次在网上看到,现在的编译器绝对没有那么智能,而且也没有必须那么做.下面我们主要聊聊编译器的处理过程.(我想初学者有疑问的正在于此,即是对于编译过程.h .c(.cpp)的变化不太了解,) 下面我说举个简单的例子来聊聊~ 例子如下: //a.h class A { pubic: int f(int t); }; //a.cpp #include "a.h" int A::f(int t) { return t; } //main.cpp #include "a.h" void main() { A a; a.f(3); } 在预处理阶段,预处理器看到#include "文件名"就把这个文件读进来,比如它编译main.cpp,看到#include "a.h",它就把a.h的内容读进来,它知道了,有一类A,包含一个成员函数f,这个函数接受一个int型的参数,返回一个int型的值。再往下编译很容易就把A a这行读懂了,它知道是要拿A这个类在栈上生成一个对象。再往下,它知道了下面要调用A的成员函数f了,参数是3,由于它知道这个函数要一个整形数用参数,这个3正好匹配,那就正好把它放到栈上,生成一条调用f(int)函数的指令(一般可能是一句call),至于这个f(int)函数到底在哪里,它不知道,它留着空,链接时再解决。它还知道f(int)函数要返回一个int,所以也许它也为这一点做好了准备(在例子中,我们没用这个返回值,也许它就不处理)。再往下到文件末尾了main.cpp编译好了,生成了main.obj。整个编译过程 中根本就不需要知道a.cpp的内容。 同理,编译器再编译a.cpp,把f()函数编译好,编译a.cpp时,它也不用管别的,把f()编译好就行了。生成了a.obj。 最后一步就是链接的阶段了,链接器把项目中所有.cpp生成的所有.obj链接起来, 在这一步中,它就明确了f(int)函数的实现所在的地址,把main.obj中空着的这个地址位置填上正确的地址。最终生成了可执行文件main.exe。 明白了吗?不明白那就多说几句了,我们在学编译原理的时候都知道,编译器是分阶段进行的,每一个阶段将源程序从一种表示转换成另一种表示,一般情况下都进行如下顺序:源程序->词法分器->语法分析器->语义分析器->中间代码生成器->代码优化器->代码生成器->目标程序. 其中这中间6项活动都要涉及的两项主要活动是:符号管理器与错误处理器. 归根原因,这里有一个叫做符号表的东东在里面让你着魔一样不明白,其实符号表是一个数据结构.编译器的基本一项功能就是要记录源程序中使用的标识符并收集与每个标识符相关的各种属性信息.属性信息表明了该标识符的存储位置/类型/作用域(在那个阶段有效)等信息,通俗的说一下就是,当编译器看到一个符号声明时,例如你的函数名它就会把它放到这个符号表中去登记一下~符号表里存放着你的函数的入口地址,参数个数,返回信息等等一堆东西~而在联接阶段主要是处理工程中的符号表与调用对应处理关系,即我们通常所说的解引用. 经过前面的,不知明白与否? 最后引用一下XXX兄的结尾三点: 搞清楚语法和概念说易也易,说难也难。窍门有三点: 1.不要晕着头工作,要抽空多思考思考,多看看书; 2.看书要看好书,问人要问强人。烂书和烂人都会给你一个错误的概念,误导你; 3.勤能补拙是良训,一分辛苦一分才; 如果认为.c和.h文件是仅仅名字不一样难免理解得肤浅了点.有op的历史看来,语言的发展是趋向与oop..h文件的出现.有点类的性质在里边..h文件的隐蔽性好.这个道理不难发现.只要大开c自己的.h文件看看,就很明显了.所以,我同意XXX兄认为乾坤一笑的肤浅. 但是,从另外一个方面看.: (至于编译器的实现.我还没了解.不过.我相信.象) //a.cpp #include "a.h" int A::f(int t) { return t; } 这样的程序不会出现吧....呵呵.所以现在的人要理解.h和.c简单化.也有点历史和时代的影响. 小弟愚钝.看了几次终于是看懂了. 现在总结一下:(有不对的请pk) 1.头文件可以预先告诉编译器一些必要的声明,让编译器顺利进行下去,在连接实现以前.未必出现实际的定义. 头文件的意义在于: a.使得程序简明,清晰. b.避免了重复编 写相同的声明代码. 2.**.c和**.h文件没有必然的联系. (原文摘自:http://blog.csdn.net/21aspnet/article/details/149810,有所整理) 质监站图书及文件管理办法 1 目的 为提高质监站图书和文件等项目管理水平, 促进项目管理的科学化和规范化, 有效共享信息资源, 根据集团公司要求, 制定本办法。 2 适用范围 本办法适用于质监站各项图书文档管理, 是规范质监站图书文件项目管理行为, 明确项目存档的操作流程和操作规程的基本依据。 3 细则 3.1 图书的购置 质监站各类图书资料由综合部负责集中统一购置, 各部门可根据实际工作需要随时向总经理办公室推荐图书资料目录。购置前须先提出申请, 由站领导批准后方可购置。 3.2 图书及文件的管理 3.2.1 质监站应指派专人负责所有图书及文件的管理、归档、文档查阅等工作。 3.2.2 新购图书或新接收文件应登记书名或文件名于专门档案内。 3.2.3 报纸、期刊及2013年7月前购置的非工具类书籍存放于图书角, 借阅者可在图书角随意翻阅。阅后需放回原处, 不得擅自带出质监站, 不得撕剪、涂写。 3.2.4 工具类书籍存放于书柜, 借阅者在综合部进行登记后借阅, 允许带出质监站。阅后需归还综合部, 不得撕剪、涂写。 3.2.5 2013年7月后购置的非工具类书籍存放于书柜,借阅者在综合部进行登记后借阅, 允许带出质监站。阅后需归还综合部, 不得撕剪、涂写。 3.2.6 文件存放于书柜, 借阅者可随意翻阅, 不得擅自带出质监站。需要带出参阅时, 可在综合部复印文件, 复印后将原件归还综合部。 3.2.7 非工具类借阅图书一次不得超过2本,工具类无限制。所有书籍借阅时间不得超过一月,到期续借需至综合部进行续借登记。 3.2.8 图书资料管理人员应于每年年终前对登记在册的各类图书文件资料进行一次全面清查。 3.3 赔偿 员工借阅图书如有破损、污迹、缺页、遗失等情况, 一律照原图书版本购赔或照原价赔偿。 3.4 报废 图书及文件需报废时, 须先提出申请, 由站领导批准后方可销毁。工具类书籍报废前须先购置新版书籍进行替换。 编制部门:供水工程质量监督站 编制人:陈韵文 编制日期:2013年7月8日 重要机密文档,彻底删除就绝对安全了吗?我们安装某些杀毒软件后,通常会在鼠标右键中出现一个类似“文件粉碎”的选项,它跟我们平常的文件删除有什么区别呢?怎么起到“粉碎”文件的作用呢? 各有千秋??“删除文件”和“粉碎文件”的区别和作用 删除与粉碎各有什么用处?什么时候该删除?什么时候该粉碎?简而言之,利用删除文件后,当我们发现误删重要数据后,可以用某种方法将其恢复,而粉碎文件则具有不可恢复性,它将文件数据彻底从硬盘分区中清除,用普通办法将无法恢复,比如一些特别隐私的文件不希望被别人恢复的话(比如借别人U盘拷贝东西后),就可以采取“文件粉碎”的办法将文件“毁尸灭迹”。 寻根问低??“删除文件”和“粉碎文件”的方式和原理 文件删除 Windows删除文件有两种: 一种是普通删除,即我们选中文件后,按下键盘Delete按钮或者在鼠标右键中选择“删除”选项。普通删除只是把文件放到回收站,任何被删除的文件都可以在回收站中进行恢复,相当于误删文件后你也有“后悔药”吃; 另一种是彻底删除,即选择文件之后按下Shift+Delete键,被删除的文件将不会移到回收站而直接从硬盘分区中删除。 但是无论是普通删除文件也好,彻底删除文件也罢,在删除文件之后如果我们没有再对硬盘分区作读写操作的话,文件数据信息仍然“保留”在硬盘数据区中。因此通过某些硬盘管理工具或者数据恢复软件(比如EasyRecovery),被彻底删除的文件还是很容易被恢复过来。 文件粉碎 顾名思义,就是把计算机上的文件彻底删除,不留痕迹。使用一些文件粉碎工具,可以做到这一点。 文件粉碎和直接删除文件是不一样的,这要从Windows的文件系统来说了。Windows文件系统包括FAT12、FAT16、FAT32等FAT系统和NTFS文件系统。在FAT文件系统中,如果创建一个文件,需要在磁盘上开辟一个“分配表”,就像图书馆的书目一样。这个表包括一个指针,指向文件的内容的地址。然后由系统在指向的地址进行文件的读写。同时,其他文件如果要创建的话,就被禁止指向这个地址,以防文件错乱。而操作系统删除文件就方便的多了:直接把“书目”销毁就可以了。“书目”指向的地址被认为是空。计算机中的数据都是由二进制组成的,在磁盘上显示为“凹”和“凸”。由于系统无法预测将要存入的文件详细信息,因此,文件内容可以认为是随机的。由数学知识可知,磁盘中的“0”和“1”对重新写信息没有在速度方面的影响。 我们的信息可能被不速之客探测到,可以根据磁盘上的蛛丝马迹,重新建立起来整个文件,或者文件的一部分,从而刺探到我们的隐私。那样对我们是很不利的。因此,有了“文件粉碎”这个概念。 “文件粉碎”是将内容和“书目”一块删除,这样,文件的内容对任何人来说都是不可知了。而且一般的文件粉碎软件都可以将Word、WPS等工具中的历史纪录和系统创建的临时文件删除,让任何人都无法得知我们的隐私。 删粉操作 “后悔药”要吃得安全放心和彻底 在日常的办公应用中,遇到不需要的文件总是随手直接删除,当发现误删之后才大呼救命,因此不妨先将删除的文件放进回收站,并且在删除前进行确认。右击桌面的“回收站”图标,选择“属性”打开属性对话框,在“全局”选项卡确保选中了“显示删除确认对话框”,这样每次删除都会提示你将文件删除进回收站,即使发现误删文件,也可以进入回收站选中文件后将其还原。对于当次操作甚至直接按下Ctrl+Z键,删除的文件立马又回来了。 对于一些确认不需要的文件,不想别人利用某种办法恢复过来,可以直接“碎”之。如果你电脑中安装了瑞星杀毒套装,在需要粉碎的文件(夹)上右击选择“粉碎文件”,将打开文件粉碎器窗口,如果还需要粉碎其他的文件,依次拖放到粉碎器窗口中,点击“开始”即可开始粉碎。 现在很多杀毒软件都集成了类似的功能,原理基本相同。另外也可以选择一些更加专业的文件粉碎工具,这里就不再具体介绍了。 编辑于:2010年7月 转载请注明出处范文大全网 » 头文件和源文件的区别范文四:图书和文件
范文五:删除文件和粉碎文件的区别和作用