C语言(Head First C)-5_2:使用多个源文件:共享函数和共享变量

该系列文章系个人读书笔记及总结性内容,任何组织和个人不得转载进行商业活动!

5_2 使用多个源文件:

链接多个源文件,共享函数、共享变量; 


 保留字/关键字:

 C语言是一种很小的语言,所有的保留字和关键字如下:

 auto   if      break

 int    case    long

 char   register    continue

 return default short

 do     sizeof  double

 static else    struct

 entry  switch  extern

 typedef    float   union

 for    unsigned    goto

 while  enum    void

 const  signed  volatile

 

 所有的C程序都可以分解为这些关键词和若干字符;如果用这些关键字来命名,编译器将无法识别;

 

 示例:

 file_hider():从文件中读取内容,使用异或加密创建一个加密版本;

 message_hider():从标准输入读取字符串,进行异或加密,然后在标准输出显示密文;

 

 异或加密:

 是一种简单的加密方法,它将文本中的每个字符与某个值进行异或;虽然不安全,但是容易操作,而且加、解密使用同一段代码;

 (Code5_1)

/*
 * 异或加密
 */

void encrypt(char * message){
    char c;
    while (*message) {
        *message = *message ^ 31;//可以对char进行运算,因为他是数值类型
        message++;
    }
}

 这是一个异或加密算法,显然,上面两个函数都会使用encrypt()函数;最好的选择就是共享代码;

 

 怎样才能共享函数?

 

 把代码分成多个文件:

 若在多个文件中共享一组代码,自然要把共享的代码放到一个单独的.c文件中;编译时包含即可;

 

 为了理解C编译器如何用多个文件创建程序,我们来看看-

 编译器的过程:

 将多个源文件编译成一个程序,编译器到底怎么工作;

 1)预处理:修改代码

 编译器做的第一件事就是修改代码;编译器需要用#include指令添加相应的头文件;编译器可能还需要跳过程序中的某些代码,或补充一些代码;

 改完之后就可以随时编译源代码了;(指令 是 命令 更花哨的说法)

 可以用#define和#ifdef来实现指令,稍后会学习;

 

 2)编译:转换成汇编代码

 C语言看似底层,但是计算机还是无法识别的,计算机只能理解更低层的机器代码指令;

 生成机器代码的第一步就是把C语言源代码转化成为汇编语言代码;

 汇编语言描述了程序运行时中央处理器需要执行的指令;但是汇编也不够低层,所以需要...

 

 3)汇编:生成目标代码

 编译器需要将这些符号代码汇编成机器代码或目标代码,即CPU内部电路执行的二进制代码;

 

 目前为止,你已经把C语言源代码转换成电路所需的0和1了;还差最后一步:你给了编译器几个文件来编译程序,编译器就会为每个源代码生成一个目标代码,为了生成可执行程序,还需要对这些目标文件做一件事...

 

 4)链接:放在一起

 有了全部的目标代码,就需要拼接起来,构成可执行程序;

 当某个目标代码的代码调用了另一个目标代码的函数时,编译器会把它们连接在一起;同时,廉洁还会确保程序能够调用库代码;

 最后,程序会写到一个可执行文件中,文件格式视操作系统而定;操作系统会根据文件格式把程序加载到存储器中运行;

 

 那么,怎么让gcc知道我们想用几个单独的源文件生成可执行程序呢?

 

 共享代码需要自己的头文件:

 想共享encrypt对应源文件的代码,需要让其他程序知道它,为此可以使用头文件;

 我们创建一个encrypt.h头文件,其中包含了encrypt()函数声明,在程序中包含encrypt.h;

 在这里使用头文件不是为了能够调整函数之间的顺序,而是为了让其他程序知道encrypt()函数;

 

 我们实际操作下:

 (Code5_2)

encrypt.h

extern int passcode;

void encrypt(char * message);

5_2-encrypt.c

/*
 * 异或加密
 */
#include <stdio.h>
#include "encrypt.h"

int passcode = 3;

void encrypt(char * message){
    printf("%s",message);
    char c;
    while (*message) {
        *message = *message ^ 31;//可以对char进行运算,因为他是数值类型
        message++;
    }
}

5_2-message_hider.c

/*
 * 在程序中包含encrypt.h
 */
#include <stdio.h>
#include "encrypt.h"

int main() {
    
    printf("%i",passcode);
    
    char msg[80];
    while (fgets(msg,80,stdin)) {
        encrypt(msg);
        printf("main2-msg:%s\n",msg);
    }
    
    return 0;
}

 主程序有encrypt.h,这表示编译器知道encrypt()函数,这样才能编译代码;

 在链接阶段,message_hider.c中的encrypt(msg)调用连接到encrypt.c中的encrypt()函数;

 

 最后把所有东西编译到一起,只需把源文件传给gcc:gcc 5_2-message_hider.c 5_2-encrypt.c -o 5_2 && ./5_2

 log:

 wewaera

 wewaera

 main2-msg:hzh~zm~

 

 共享变量:

 为了防止两个源文件中的同名变量相互干扰,变量的作用域仅限于某个文件内;如果想共享变量,就应该在文件中声明,并在变量名前加上extern关键字;

 extern int passcode;//extern是告诉编译器我这个变量将在其他外部c文件中定义,我这里只是声明它;

 参照5_2代码的passcode变量:

 在.h头文件中使用extern声明,在5_2-encrypt.c源文件中进行实现,在main所在的源文件中就可以使用该变量了;

 运行上面的程序,会将passcode的值3打印出来;

 

 现在,只是把encrypt()函数放在了一个单独的文件中,就可以在任何程序中使用它了;若想修改,也只要修改一个该函数所在的源文件就好了

 

 要点:

 -为了共享代码,可以把代码放到一个单独的C文件中;

 -需要把函数声明放到一个单独的.h头文件中;

 -在所有需要使用共享代码的C文件中包含这个头文件;

 -在编译的命令中列出所有的C文件;

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值