首页 > 应用 > 智能硬件
[导读]c编译器很多,每款c编译器均有其特点。本文对于c编译器的讲解基于gcc c编译器,针对gcc c编译器,小编曾带来诸多文章,但大多基于windows平台。本文中,将基于ubuntu讲解gcc c编译器。此外,本文只为该教程上篇,其余内容将在下篇中予以讲解。

c编译器很多,每款c编译器均有其特点。本文对于c编译器的讲解基于gcc c编译器,针对gcc c编译器,小编曾带来诸多文章,但大多基于windows平台。本文中,将基于ubuntu讲解gcc c编译器。此外,本文只为该教程上篇,其余内容将在下篇中予以讲解。

1.jpg

一、编译简单的 C 程序

C 语言经典的入门例子是 Hello World,下面是一示例代码:

#include

int

main(void)

{

printf("Hello, world!/n");

return 0;

}

我们假定该代码存为文件‘hello.c’。要用 gcc 编译该文件,使用下面的命令:

$ gcc -Wall hello.c -o hello

该命令将文件‘hello.c’中的代码编译为机器码并存储在可执行文件 ‘hello’中。机器码的文件名是通过 -o 选项指定的。该选项通常作为命令行中的最后一个参数。如果被省略,输出文件默认为 ‘a.out’。

注意到如果当前目录中与可执行文件重名的文件已经存在,它将被复盖。

选项 -Wall 开启编译器几乎所有常用的警告──强烈建议你始终使用该选项。编译器有很多其他的警告选项,但 -Wall 是最常用的。默认情况下GCC 不会产生任何警告信息。当编写 C 或 C++ 程序时编译器警告非常有助于检测程序存在的问题。

本例中,编译器使用了 -Wall 选项而没产生任何警告,因为示例程序是完全合法的。

要运行该程序,输入可执行文件的路径如下:

$ ./hello

Hello, world!

这将可执行文件载入内存,并使 CPU 开始执行其包含的指令。 路径 ./ 指代当前目录,因此 ./hello 载入并执行当前目录下的可执行文件 ‘hello’。

二、捕捉错误

如上所述,当用 C 或 C++ 编程时,编译器警告是非常重要的助手。为了说明这一点,下面的例子包含一个微妙的错误:为一个整数值错误地指定了一浮点数控制符‘%f’。

#include

int

main (void)

{

printf ("Two plus two is %f/n", 4);

return 0;

}

一眼看去该错误并不明显,但是它可被编译器捕捉到,只要启用了警告选项 -Wall。

编译上面的程序‘bad.c’,将得到如下的消息:

$ gcc -Wall bad.c -o bad

bad.c: In function 'main':

bad.c:6: warning: double format, different type arg (arg 2)

这表明文件 ‘bad.c’第 6 行中的格式字符串用法不正确。GCC 的消息总是具有下面的格式 文件名:行号:消息。编译器对错误与警告区别对待,前者将阻止编译,后者表明可能存在的问题但并不阻止程序编译。

本例中,对整数值来说,正确的格式控制符应该是 %d。

如果不启用 -Wall,程序表面看起来编译正常,但是会产生不正确的结果:

$ gcc bad.c -o bad

$ ./bad

Two plus two is 2.585495

显而易见,开发程序时不检查警告是非常危险的。如果有函数使用不当,将可能导致程序崩溃或产生错误的结果。开启编译器警告选项 -Wall 可捕捉 C 编程时的多数常见错误。

三、编译多个源文件

一个源程序可以分成几个文件。这样便于编辑与理解,尤其是程序非常大的时候。这也使各部分独立编译成为可能。

下面的例子中我们将程序 Hello World 分割成 3 个文件:‘main.c’,‘hello_fn.c’和头文件‘hello.h’。这是主程序‘main.c’:

#include "hello.h"

int

main(void)

{

hello ("world");

return 0;

}

在先前的例子‘hello.c’中,我们调用的是库函数 printf,本例中我们用一个定义在文件‘hello_fn.c’中的函数 hello 取代它。

主程序中包含有头文件‘hello.h’,该头文件包含函数 hello 的声明。我们不需要在‘main.c’文件中包含系统头文件‘stdio.h’来声明函数 printf,因为‘main.c’没有直接调用 printf。

文件‘hello.h’中的声明只用了一行就指定了函数 hello 的原型。

void hello (const char * name);

函数 hello 的定义在文件‘hello_fn.c’中:

#include

#include "hello.h"

void

hello (const char * name)

{

printf ("Hello, %s!/n", name);

}

语句 #include "FILE.h" 与 #include 有所不同:前者在搜索系统头文件目录之前将先在当前目录中搜索文件‘FILE.h’,后者只搜索系统头文件而不查看当前目录。

要用gcc编译以上源文件,使用下面的命令:

$ gcc -Wall main.c hello_fn.c -o newhello

本例中,我们使用选项 -o 为可执行文件指定了一个不同的名字 newhello。注意到头文件‘hello.h’并未在命令行中指定。源文件中的的 #include "hello.h" 指示符使得编译器自动将其包含到合适的位置。

要运行本程序,输入可执行文件的路径名:

$ ./newhello

Hello, world!

源程序各部分被编译为单一的可执行文件,它与我们先前的例子产生的结果相同。

点击此处下载本节的操作视频

四、简单的 Makefile 文件

为便于不熟悉 make 的读者理解,本节提供一个简单的用法示例。Make 凭借本身的优势,可在所有的 Unix 系统中被找到。要了解关于Gnu make 的更多信息,请参考 Richard M. Stallman 和 Roland McGrath 编写的 GNU Make 手册。

Make 从 makefile(默认是当前目录下的名为‘Makefile’的文件)中读取项目的描述。makefile指定了一系列目标(比如可执行文件)和依赖(比如对象文件和源文件)的编译规则,其格式如下:

目标: 依赖

命令

对每一个目标,make 检查其对应的依赖文件修改时间来确定该目标是否需要利用对应的命令重新建立。注意到,makefile 中命令行必须以单个的 TAB 字符进行缩进,不能是空格。

GNU Make 包含许多默认的规则(参考隐含规则)来简化 makefile 的构建。比如说,它们指定‘.o’文件可以通过编译‘.c’文件得到,可执行文件可以通过将‘.o’链接到一起获得。隐含规则通过被叫做make变量的东西所指定,比如 CC(C 语言编译器)和 CFLAGS(C程序的编译选项);在makefile文件中它们通过独占一行的 变量=值 的形式被设置。对 C++ ,其等价的变量是CXX和CXXFLAGS,而变量CPPFLAGS则是编译预处理选项。

现在我们为上一节的项目写一个简单的 makefile 文件:

CC=gcc

CFLAGS=-Wall

hello: hello.o hello_fn.o

clean:

rm -f hello hello.o hello_fn.o

该文件可以这样来读:使用 C 语言编译器 gcc,和编译选项‘-Wall’,从对象文件‘hello.o’和‘hello_fn.o’生成目标可执行文件 hello(文件‘hello.o’和‘hello_fn.o’通过隐含规则分别由‘hello.c’和‘hello_fn.c’生成)。目标clean没有依赖文件,它只是简单地移除所有编译生成的文件。rm命令的选项 ‘-f’(force) 抑制文件不存在时产生的错误消息。

要使用该 makefile 文件,输入 make。不加参数调用make时,makefile文件中的第一个目标被建立,从而生成可执行文件‘hello’:

$ make

gcc -Wall -c -o hello.o hello.c

gcc -Wall -c -o hello_fn.o hello_fn.c

gcc hello.o hello_fn.o -o hello

$ ./hello

Hello, world!

一个源文件被修改要重新生成可执行文件,简单地再次输入 make 即可。通过检查目标文件和依赖文件的时间戳,程序 make 可识别哪些文件已经修改并依据对应的规则更新其对应的目标文件:

$ vim hello.c (打开编辑器修改一下文件)

$ make

gcc -Wall -c -o hello.o hello.c

gcc hello.o hello_fn.o -o hello

$ ./hello

Hello, world!

最后,我们移除 make 生成的文件,输入 make clean:

$ make clean

rm -f hello hello.o hello_fn.o

一个专业的 makefile文件通常包含用于安装(make install)和测试(make check)等额外的目标。

本文中涉及到的例子都足够简单以至于可以完全不需要makefile,但是对任何大些的程序都使用 make 是很有必要的。

以上便是此次小编带来的“c编译器”相关内容,通过本文,希望大家对本文讲解的内容具备一定的了解。如果你喜欢本文,不妨持续关注我们网站哦,小编将于后期带来更多精彩内容。最后,十分感谢大家的阅读,have a nice day!

换一批

延伸阅读

[智能硬件] c编译器so easy,gcc c编译器生成、使用动静态库(下篇)

c编译器so easy,gcc c编译器生成、使用动静态库(下篇)

对于c编译器,大家并不陌生。小编前期同样为c编译器带来了诸多好文,如果你对c编译器感兴趣,不妨在本网站内进行搜索哦。......

关键字:c编译器 gcc 静态库

[智能硬件] c编译器so easy,gcc c编译器生成、使用动静态库(中篇)

c编译器so easy,gcc c编译器生成、使用动静态库(中篇)

自学c编译器的朋友都知道。c编译器作为常用软件之一,并非具备无法逾越难度。对于c编译器的学习,往往需要具备一定耐心。本文对c编译器的讲解基于gcc c编译器,同时本文承接“c编译器so easy,gcc c编译器生成、使用动静态库(上篇)”......

关键字:c编译器 gcc 静态库

[智能硬件] c编译器so easy,gcc c编译器生成、使用动静态库(上篇)

c编译器so easy,gcc c编译器生成、使用动静态库(上篇)

程序开发人员大多接触过c编译器,请注意,不要将c编译器和编辑器弄混淆哦。本文对c编译器的讲解,同样基于gcc c编译器,本文主要目的在于对linux环境下gcc c编译器生成和使用静态库和动态库予以介绍。......

关键字:c编译器 gcc 静态库

[智能硬件] c编译器高手过招,gcc c编译器程序插装下篇

c编译器高手过招,gcc c编译器程序插装下篇

c编译器在c程序编写过程中发挥着不可替代的作用,对于c编译器,相关人员应当给予足够重视。前文中,小编曾介绍过基于gcc c编译器的程序插装技术,但这并非c编译器插装技术的全面貌。本文,为基于gcc c编译器程序插装技术下篇,一起继续来了解这......

关键字:c编译器 gcc 程序插装

[智能硬件] c编译器高手过招,gcc c编译器程序插装上篇

c编译器高手过招,gcc c编译器程序插装上篇

对于c编译器,大家均有所了解。因此对于c编译器的基本知识,本文将不再介绍。本文中,将基于gcc c编译器,为大家讲解程序插装技术,以帮助大家更好理解c编译器的用处,并推动大家对于c编译器的学习进程。......

关键字:gcc c编译器 程序插装

[智能硬件] gcc c编译器简介,gcc c编译器处理.c文件流程

gcc c编译器简介,gcc c编译器处理.c文件流程

c编译器是c语言编写无法脱离的环境之一,目前市场上主要流通三类c编译器,其中gcc c编译器最为实用。本文将涉及两大内容:1 gcc c编译器简介,2gcc c编译器处理.c文件的流程。......

关键字:c编译器 gcc 编译

[智能硬件] c编译器前篇,不一样的gcc c编译器介绍

c编译器前篇,不一样的gcc c编译器介绍

c编译器是c程序成功运行的必要组件之一,c编译器的用处在于对c程序予以编译,以便电脑解读。那么哪款c编译器是市场宠儿呢?小编个人偏向gcc c编译器。在本文中,你可从多个方面了解gcc c编译器。阅读完本文,如果你爱上了这款c编译器,不妨尝......

关键字:c编译器 gcc 执行过程

[智能硬件] Gcc c编译器很难?击破gcc c编译器参数

Gcc c编译器很难?击破gcc c编译器参数

c编译器是解析c程序不可缺少的部件之一,针对linux系统而言,gcc c编译器无疑是热度最高的c编译器之一。对于gcc c编译器,很多朋友反馈其操作存在一定难度。为帮助大家更加流畅使用gcc c编译器,本文特对gcc c编译器各大参数予以......

关键字:c编译器 linux 参数

[智能硬件] c编译器起步,搞定linux安装gcc c编译器过程

c编译器起步,搞定linux安装gcc c编译器过程

c编译器和c编辑器是大家经常混淆的两大概念,事实上c编译器、c编辑器二者存在极大区别。目前,c编译器存在3大主流分支,gcc便是其中之一。本文中,将讲解gcc c编译器在linux系统的安装过程,为大家后期使用c编译器夯实基础。......

关键字:c编译器 gcc linux

[智能硬件] 大牛讲解c编译器,gcc c编译器超详解析

大牛讲解c编译器,gcc c编译器超详解析

不同c编译器通常配备不同的c编译器,但目前主流的c编译器分为三种,gcc便是三大出色c编译器之一。本文中,将为大家介绍这款c编译器的入门知识,以为大家的后期学习夯实基础。......

关键字:c编译器 gcc 库依赖

[智能硬件] 了解c编译器三剑客,gcc c编译器编译流程详解

了解c编译器三剑客,gcc c编译器编译流程详解

gcc是当前三大主流c编译器之一,对于这款c编译器,想必诸多人士均有使用体验。在本文中,将对gcc c编译器编译流程加以介绍,以帮助大家更好了解这款c编译器的工作流程。gcc是当前三大主流c编译器之一,对于这款c编译器,想必诸多人士均有使用......

关键字:c编译器 gcc 编译流程

[智能硬件] c编译器三剑客之一,秒杀gcc c编译器编译警告

c编译器三剑客之一,秒杀gcc c编译器编译警告

c编译器是程序运行的基础,一款好的c编译器具备优良性能。目前,GCC是三大主流c编译器之一。对于这款c编译器,可能大家并非十分了解。本文中,将为大家介绍gcc常见的编译警告以及解决方法。如果你对这款c编译器比较感兴趣,不妨继续往下看哦。......

关键字:c编译器 gcc 编译警告

[智能硬件] c编译器救星,搞懂GCC c编译器

c编译器救星,搞懂GCC c编译器

对c编译器关注较多的朋友,都知道目前市场上主要流通3大c编译器。本文中,主要介绍GCC c编译器,讲解内容为该c编译器的入门必备知识。如果你对GCC的入门知识不够了解,那本文无疑是你的救星!!!......

关键字:c编译器 GCC 入门知识

[智能硬件] c编译器高级篇!!搞定c编译器优化

c编译器高级篇!!搞定c编译器优化

对于c编译器,想必大家也有所了解,3款主流c编译器也是活跃在不同人群的PC上。网络上很多文章都止步于对c编译器的介绍,并未探索c编译器更加深层次的内容。而在本文中,将涉及c编译器的高级部分——c编译器及其优化。所以,本文的讲解需要大家具备一......

关键字:c编译器 优化 处理器

[智能硬件] c编译器如何选择?小妙招选定c编译器

c编译器如何选择?小妙招选定c编译器

C程序成功运行,离不开c编译器支持。目前市场上主要流通3种c编译器,那么在c程序开发过程中,应当选择最佳的c编译器呢?在本文中,将向你介绍c编译器的选择,以及IDE(集成开发环境)的选择,不妨一起来了解下。......

关键字:c编译器 编译器 IDE

我 要 评 论

网友评论

技术子站

更多

项目外包

更多

推荐博客

米乐彩票平台