美文网首页
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语言编译链接

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