美文网首页
C语言编译链接

C语言编译链接

作者: Co酱_秋乏术 | 来源:发表于2023-02-04 14:36 被阅读0次

#编译(默认生成 a.out)

$gcc hello.c

#执行helloworld!

$./a.out 

上述gcc命令其实依次执行了四步操作:

预处理(Preprocessing)

编译(Compilation)

汇编(Assemble)

链接(Linking)


假设我们自己定义了一个头文件mymath.h,实现一些自己的数学函数,并把具体实现放在mymath.c当中。然后写一个test.c程序使用这些函数。程序目录结构如下:

程序代码如下:

// test.c

#include<stdio.h>

#include"mymath.h"

// 自定义头文件

int main()

{

inta=2;intb=3;intsum=add(a,b);

printf("a=%d, b=%d, a+b=%d\n",a,b,sum);

}

头文件定义:

// mymath.h

#ifndef MYMATH_H

#define MYMATH_H

int add(inta,intb);

int sum(inta,intb);

#endif

头文件实现:

// mymath.c

int add(inta,intb)

{return a+b;}

int sub(inta,intb)

{return a-b;}


头文件.h的作用

.h中一般放的是同名.c文件中定义的变量、数组、函数的声明,需要让.c外部使用的声明。

1)h文件作用:

    1.方便开发:包含一些文件需要的共同的常量,结构,类型定义,函数,变量申明;

  2. 使函数的作用域从函数声明的位置开始,而不是函数定义的位置(实践总结)

  3 .提供接口:对一个软件包来说可以提供一个给外界的接口(例如: stdio.h)。

2)h文件里应该有什么:常量,结构,类型定义,函数,变量申明。

3)h文件不应该有什么:变量定义, 函数定义。

4)extern问题:

  1.对于变量需要extern;

  2.对于函数不需要因为函数的缺省状态是extern的.如果一个函数要改变为只在文件内可见,加static。

5)include包含问题:

虽然申明和类型定义可以重复,不过推荐使用条件编译。

#ifndef _FILENAME_H,

#define _FILENAME_H……

#endif

实践总结:

先看最简单的程序:hello world

/*test1.c*/

main()

{printf("Hello World!\n");}

/*test2.c*/

prtstr()

{printf("Hello World!\n");}

main()

{prtstr();}

上述“test1.c”和“test2.c”中并没有.h文件,编译可以顺利通过。把程序做下改动,下面这个:

/*test3.c*/

main()

{

  prtstr();

}

prtstr()

{

  printf("Hello World!\n");

}

没有.h文件,编译失败,这跟作用域有关。

我们在这里只讲述与.h文件相关的顶层作用域, 顶层作用域就是从声明点延伸到源程序文本结束, 就prtstr()这个函数来说,他没有单独的声明,只有定义,那么就从他定义的行开始,到文件结束, 也就是说,在test2.c的main()函数的引用点上,已经是他的作用域。 test3.c的main()函数的引用点上,还不是他的作用域,所以会编译出错. 这种情况怎么办呢? 有两种方法 ,一个就是让我们回到test2.c, 顺序对我们来说没什么, 谁先谁后不一样呢,只要能编译通过,程序能运行, 就让main()文件总是放到最后吧。那就让我们来看另一个例程,让我们看看这个方法是不是在任何时候都会起作用.

/*test4.c*/

2 play2()

3 {

4      play1(); 

5 }

6   

7 play1()

8 {

9      play2();       

10 }

11   

12 main()

13 {

14      play1();

15 }

这就是经常用到的一种算法, 函数嵌套。play1 和play2 这两个函数哪个放到前面呢?这时就需要我们来使用第二种方法,使用声明.

1 /*test5.c*/

2 play1();

3 play2();

4

5 play2()

6 {

7   play1();

8 }

9   play1()

10 {

11   play2();

12 }

13 main()

14 {

15   play1();

16 }

一个大型的软件项目,可能有几千个,上万个 play, 而不只是 play1,play2这么简单, 这样就可能有 N 个类似 play1(); play2(); 这样的声明, 这个时候就需要我们想办法把这样的 play1(); play2(); 另行管理, 而不是把他放在.c文件中, 于是.h 文件出现了.

/*test.h */

play1();

play2();

/* test6.C */

#include “test.h”

play2()

{play1();}

play1();

{play2();}

main()

{

  play1();

}

相关文章

  • C语言程序内存布局

    C语言笔记之02-C语言程序内存布局 我们知道C语言的编译过程分为:预处理-编译-汇编-链接-生成可执行文件,而这...

  • 预处理命令

    C语言的执行流程 c语言执行分为三步编译:编译成目标代码(.obj)链接:将目标代码与C函数库连接合并,形成最终的...

  • 不同系统下如何玩转c++程序

    C++ 和C语言类似,也要经过编译和链接后才能运行。在《C语言入门教程》中我们讲到了 C-Free、VC 6.0、...

  • gcc_clang的使用_day93

    编译命令 编译流程 预编译 编译 链接, 动态链接/静态链接 编写文件 add.c clang -g -c ad...

  • C语言生成可执行文件的编译过程

    C语言源文件要经过编译、链接才能生成可执行程序: 1、 编译(Compile)会将源文件(.c文件)转换为目标文件...

  • C语言编译过程详解

    C语言编译过程详解C语言的编译链接过程是要把我们编写的一个C程序(源代码)转换成可以在硬件上运行的程序(可执行代码...

  • C语言:编译链接的流程

    编译链接的流程图 第一个过程:预处理预处理器对.c源程序进行一些预先处理,为后续编译打好基础预处理的内容(这些内容...

  • C 语言编译链接过程

    C 语言从源代码变成可执行文件经过了以下步骤: 预处理(preprocessing)、编译(compilation...

  • Java不能单文件编译的原因之一

    前言 1.一些语言编译的过程是【编译】+【链接】,如c语言 2.java作为一种后来的语言却不具备单文件编译的特性...

  • C语言 目标文件和可执行文件(ELF文件)

    1.C语言创建程序 1.1C语言创建(分为4个步骤) 编辑 编译 链接 执行 编辑:就是创建和修改C程序的源代码-...

网友评论

      本文标题:C语言编译链接

      本文链接:https://www.haomeiwen.com/subject/jiyohdtx.html