本节主要讲 gcc
gcc(GNU Compiler Collection)是由GNU开发的编程语言译器
gcc 一般对 C,g++ 对 C++,主要就是库不同
gcc 在乎文件后缀( gcc 不是 linux 的 shell ,shell 不在乎后缀名)
目录
动态库与静态库
编译与链接
优化打包
如何做静态库
gcc 工程示例
gcc 默认连接动态库
静态库:(static,.a 文件)函数已经存在在可执行程序中,兼容性好,但不利于程序的升级,要升级还要去程序里找升级了哪些库函数
动态库:(shared,.s 文件)函数不在可执行程序中,要用到这个函数的时候还要跳转到库,兼容性不好
链接静态库,可执行程序可以在没有 gcc 的机器上运行,如果你这个程序以后都不动了(比如一些简单的嵌入式)可以考虑;
链接动态库,可执行程序只能在有 gcc 的机器上运行,但是便于升级,对于没装 gcc 的普通用户来说,只要把最新的 gcc 升级(覆盖旧的 gcc ),软件就升级了,通常都用动态库
一般的一个 gcc 工程的文件目录如下
project/src/*.c Makefile focus
/include/*.h
/lib/*.a *.so libstuff.a lisstuff.so
/bin/ *
/tools/*.sh *.py
看一个最简单的 gcc 程序
gcc 一行命令完成编译和链接
编译:把程序代码(.c文件)变成机器码(.o 文件);头文件(.h文件)和 .c 文件放在同一目录下,命令行编译时候 shell 会自己找
链接:把源代码中的库函数找出来,跳转到系统中这个库函数的定义,生成可执行程序(只有 main 函数才能干这事)
先 -c 再 -o
-o 的时候要注意顺序,把最底层的库写在最右边,也就是左边的库会依赖右边的库
有六个优化级别
在调试阶段不要优化,调试完了再优化(也就是说用完 -g 再用 -O),同时用 -g 和 -O 可能会出现奇怪的错误
因为优化加快了程序速度,但兼容性会变差,一般就用 O2 别太高
调试 -g 后是可以看到源代码的,优化后 -O 就看不到源代码了
库文件必须 lib 打头
现在有一个文件1.txt ,内容如下:
$ vi 1.txt
0.3
5
5.77
5.3
55
667
55
332
55.6
77.8
343.01
788
设计一个含 Makefile 文件的工程, 实现求最大数(文件max.c),最小数(文件min.c),算术平均数(文件m-mean.c),几何平均数(文件g-mean.c),方差(文件var.c), 写出:
注:以下所有文件均在同一个目录下,头文件就按 .c 文件中的去声明就OK
makefile
CC = gcc
CFLAGS = -Wall
main:main.o var.o m_mean.o g_mean.o min.o max.o
$(CC) -o main $^ -lm
%.o:%.c
$(CC) $(CFLAGS) -c $^
clean:
rm -rf main.o max.o min.o m_mean.o g_mean.o var.o
main.c
#include
#include
#include
#include "max.h"
#include "min.h"
#include "m_mean.h"
#include "g_mean.h"
#include "var.h"
int main()
{
char filename[] = "1.txt";
FILE *fp;
char StrLine[10]; //max char numbers that can be read in each linew
if((fp=fopen(filename,"r")) == NULL) //file not exists
return -1;
float arr[100];
int j=0;
while(!feof(fp))
{
fgets(StrLine,10,fp); //readline
//strtok(StrLine,"\n");
StrLine[strlen(StrLine)-1]='\0'; //delete \n in the end
arr[j]=(float)atof(StrLine); //change char to num
//printf("%s ",StrLine); //print
j++;
}
fclose(fp); //remenber to close
int size=j-1;
printf("read %d numbers in 1.txt\n",size);
printf("they are:\n");
for(int i=0;i
max.c
#include
float max(float arr[], int size)
{
float result=arr[0];
for(int i=0;iresult)
result=arr[i];
return result;
}
min.c
#include
float min(float arr[], int size)
{
float result=arr[0];
for(int i=0;i
g_mean.c
#include
#include
float g_mean(float arr[],int size)
{
float mul=0;
for(int i=0;i
m_mean.c
#include
float m_mean(float arr[], int size)
{
float sum=0;
for(int i=0;i
var.c
#include
#include "m_mean.h"
float var(float arr[],int size)
{
float og_m = m_mean(arr,size); //m-mean of the original arr
float new_arr[size];
for(int i=0;i
如何运行: