如果再来一个用户 C 呢?有没有感觉很麻烦的样子?那么我们完全可以这样做:
#include <stdio.h>int main(){#ifdef CHARGE//付费用户执行流程printf("该用户已付费,执行付费功\n");#else//白嫖用户执行流程printf("白嫖用户,拒绝执行付费功能\n");#endifprintf("公共功能\n");return 0;}
在编译付费用户的时候,添加 -D CHARGE 参数;编译白嫖用户 , 则不添加 。这样的话,不管来多少用户,都只需要维护一个分支即可 。
1.4.2 指定 C 方言(-std)对于如下 C 语言代码:
#include <stdio.h>int main(){for (int i = 1; i <= 3; i++){printf("i = %d\n", i);}return 0;}
在编译时是会报错的:
文章插图
但如果我们加上 -std=c99,就可以了:
文章插图
二、静态库和动态库2.1 扫盲库是「已经写好的、供使用的」可复用代码,每个程序都要依赖很多基础的底层库 。
从本质上,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行 。程序中调用的库有两种「静态库和动态库」,所谓的「静态、动态」指的是链接的过程 。
2.2 静态库2.2.1 静态库简介在 Linux 中静态库以 lib 作为前缀、以 .a 作为后缀,形如 libxxx.a(其中的 xxx 是库的名字,自己指定即可) 。静态库以之所以称之为「静态库」,是因为在链接阶段 , 会将汇编生成的目标文件 .o 与引用的库一起链接到可执行文件中,对应的链接方式称为静态链接 。
2.2.2 静态库的生成在 Linux 中静态库由程序 ar 生成 。生成静态库,需要先对源文件进行汇编操作得到二进制格式的目标文件(以 .o 结尾的文件),然后再通过 ar 工具将目标文件打包就可以得到静态库文件了 。
文章插图
使用 ar 工具创建静态库的一般格式为
$ ar -rcs libxxx.a 若干原材料(.o文件)
:2.2.3 静态库的制作举例在某目录中有如下源文件,用来实现一个简单的计算器 。
【GCC 指令详解及动态库、静态库的使用】add.c
#include <stdio.h>int add(int a, int b){return a + b;}
sub.c#include <stdio.h>int subtract(int a, int b){return a - b;}
mult.c#include <stdio.h>int multiply(int a, int b){return a * b;}
具体操作步骤如下:# 第一步:将源文件 add.c、sub.c、mult.c 进行汇编,得到二进制目标文件 add.o、sub.o、mult.o$ gcc -c add.c sub.c mult.c# 第二步:将生成的目标文件通过 ar 工具打包生成静态库$ ar rcs libcalc.a add.o sub.o mult.o
2.2.4 静态库的使用定义 main 函数如下所示:main.c
#include <stdio.h>int main(){int a = 20;int b = 12;printf("a = %d, b = %d\n", a, b);printf("a + b = %d\n", add(a, b));printf("a - b = %d\n", subtract(a, b));printf("a * b = %d\n", multiply(a, b));return 0;}
并将静态库 libcalc.a 置于同级目录下:文章插图
通过指令
$ gcc main.c -o main -L ./ -l calc
编译 main.c 文件,并链接静态库 libcalc.a:- -L:指定使用的库的路径(因为在同一级目录下,所以可以直接用了
./
,或者使用绝对路径也是可以的) - -l:指定使用的库(库的名字一定要掐头去尾 。如:libcalc.a 变为 calc)
编译结果会提示三个 warning,这是由于没有定义这些函数导致的 , 先暂时不用管 。运行 main 结果如下:
文章插图
我们思考这么一个问题:由于静态库是我们自己制作的,其所包含的函数我们很清楚,直接链接并使用即可 。但如果别人想要使用呢?他们可不清楚静态库中的函数该如何调用,所以我们有必要提供一个头文件,这样将静态库及头文件交给其他人时 , 他们知道该如何用了 。
head.h
#ifndef _HEAD_H_#define _HEAD_H_int add(int a, int b);int subtract(int a, int b);int multiply(int a, int b);#endif
还记得之前的报错吗?现在有了头文件就要使用起来 。main.c
#include <stdio.h>#include "head.h"int main(){int a = 20;int b = 12;printf("a = %d, b = %d\n", a, b);printf("a + b = %d\n", add(a, b));printf("a - b = %d\n", subtract(a, b));printf("a * b = %d\n", multiply(a, b));return 0;}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- java中GC的日志认识详解
- 我的世界指令附魔攻略(我的世界附魔1000级的指令)
- JUC中的AQS底层详细超详解
- 图文详解 微服务 Zipkin 链路追踪原理
- 唐人街探案3剧情详解_唐人街探案3讲了什么剧情
- C++之值传递&指针传递&引用传递详解
- 非常全面 Dubbo 原理和机制详解
- 未知暗殿走法路线详解(未知暗殿怎么走视频)
- JWT基础概念详解
- Go | 基本数据类型详解