概述
什么是gcc
linux系统下的Gcc(GNU C Compiler)是GNU推出的功能强大、性能优越的多平台编译器,是GNU的代表作品之一。gcc是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比平均效率要高20%~30%。
Gcc编译器能将C、C++语言源程序、汇程式化序和目标程序编译、链接成可执行文件。
gcc工作流程图
牢记4个 阶段
预处理(生成C文件.i),具体的工作比如宏替换、头文件展开、去掉注释等等。
编译(生成汇编文件.s)
汇编(生成二进制文件.o)
执行
需要注意的是:gcc工作流程一共是4步,但是这4步并不是都是由gcc来完成的,gcc只完成1步,剩下的都是调用其它的处理器来完成的。预处理阶段调用了预处理器cpp,编译就是由gcc完成的,汇编是由汇编器as完成,链接是由链接器ld完成。
头文件在编译过程中的作用?
头文件并不参加链接和编译。编译器第一步要做的就是简单的把头文件在包含它的源文件中展开。不知你是否能理解这句话。也就是头文件里面有什么内容,通通把它移到包含这个头文件的源文件里。(我觉得这是个很重要的概念,可以帮助我们简化理解编译链接的过程,包括理解头文件中定义静态变量或静态函数是怎么回事)。编译器经过这一步转换后剩下什么呢?就是一堆cpp文件了。而头文件已经不再是编译器需要关心的东西了。编译器接下来就要处理这一堆cpp文件了。
所以第一个阶段是预处理阶段,在正式的编译阶段之前进行。预处理阶段将根据已放置在文件中的预处理指令来修改源文件的内容。如#include指令就是一个预处理指令,它把头文件的内容添加到.cpp文件中。 第二个阶段编译、优化阶段。
之所以不在头文件中进行定义是防止多重定义。
gcc常用参数
1. -v/version:指定版本信息
2. -I(大写i) 编译的时候指定头文件的路径,写程序的时候,包含的头文件默认是处于同一级的,如果当前的路径下没有这个文件,有两种方式解决,要么#include "include/head.h"这样指出,要么就是利用-I指出。
eg:
sum.c
#include <stdio.h>
#include "head.h"
#include "include/head.h"
int main(void)
{
int a=NUM1;
int b=NUM2;
int sum=a+b;
printf("%dn",sum);
return 0;
}
include目录下有头文件head.h
head.h
#ifndef __HEAD_H__
#define __HEAD_H__
#define NUM1 10
#define NUM2 20
#endif
3.. -c 将汇编文件生成二进制文件,得到了一个.o文件
4. -o 指定生成的文件的名
比如执行可执行文件时,如果未使用-o,则默认的可执行文件名字是a.out
5. -D 在编译的时候指定一个宏,所以我们可以在测试的时候使用,比如不知道哪个地方出错,那么加上printf()函数,当找出错误以后,如果不删printf函数,是会影响效率的,这时我们就可以借助这种手段,不指定宏的时候,printf也就不会输出。
更改刚才的sum.c
#include <stdio.h>
#include "head.h"
//#define DEBUG
int main(void)
{
int a=NUM1;
int b=NUM2;
int sum=a+b;
#ifdef DEBUG
printf("%dn",sum);
#endif
return 0;
}
如果在程序中没有定义DEBUG宏,那么可以在编译时指出,如果不指出,则不会运行printf("%dn",sum);
6. -Wall 添加警告信息
#include <stdio.h>
#include "head.h"
//#define DEBUG
int main(void)
{
int a=NUM1;
int b=NUM2;
int c;
int sum=a+b;
#ifdef DEBUG
printf("%dn",sum);
#endif
return 0;
}
程序中的c变量没有使用,加上-Wall会提出警告
7. -On 优化代码,n是优化级别,有1、2、3级别,3最高
int a=10;
int b=a;
int c=b;
printf("%d",c);
//经过编译器优化之后,实际执行的可能如下
int c=10;
printf("%d",c);
8. -g GDB调试的时候需要加
常用GCC编译选项
编译选项 | 说明 |
---|---|
-c | 只进行预处理、编译和汇编,生成.o文件 |
-S | 只进行预处理和编译,生成.s文件 |
-E | 只进行预处理,产生预处理后的结果到标准输出 |
-C | 预处理时不删除注释信息,常与-E同时使用 |
-o | 指定目标名称,常与-c、-S同时使用,默认是.out |
-D | 定义一个宏,功能等同源代码中的#define macro[defval] |
-U | 取消一个宏,功能等同源代码中的#undefine macro |
-Idir | 优先在选项后的目录中查找包含的头文件 |
-Iname | 链接后缀为.out的动态链接库来编译程序 |
-Ldir | 指定编译搜索库的路径 |
-g | 编译器编译时加入debug信息 |
-share | 使用动态库 |
-static | 禁止使用动态库 |
gcc和g++的区别
对于 *.c和*.cpp文件,gcc分别当做c和cpp文件编译(c和cpp的语法强度是不一样的)
对于 *.c和*.cpp文件,g++则统一当做cpp文件编译
使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL。
最后
以上就是美丽麦片为你收集整理的GCC详解的全部内容,希望文章能够帮你解决GCC详解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复