准备工作
如果你还没装编译环境或自己不确定装没装,不妨先执行
sudo apt-get install
build-essential
如果你需要编译
Fortran 程序,那么还需要安装
gfortran(或
g77)
sudo apt-get install
gfortran
如果你已经了解一些
vim 的知识,而且想用它来编辑源代码,那么我们不妨装个完整版
sudo apt-get install
vim-full
如果你不了解
vim,选择
gedit、
kate或
mousepad来编辑源代码就好了
注意:本文可能会让你失望,如果你看完后有下列疑问的话:为什么要在终端输命令啊?
GCC 是什么东西,怎么在菜单中找不到?
GCC 不能有像
VC 那样的窗口吗?……
那么你真正想要了解的可能是
anjuta,
kdevelop,
geany,
code
blocks,
eclipse,
neatbean
等
IDE 集成开发环境。即使在这种情况下,由于
GCC 是以上
IDE
的后台的编译器,本文仍值得你稍作了解。
[
编辑
]
编译简单的
C
程序
C 语言经典的入门例子是
Hello World,下面是一示例代码:
#include <stdio.h>
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 <stdio.h>
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 <stdio.h>
#include "hello.h"
void
hello (const char *
name)
{
printf ("Hello,
%s!\n", name);
}
语句
#include "FILE.h" 与
#include <FILE.h>
有所不同:前者在搜索系统头文件目录之前将先在当前目录中搜索文件‘
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 是很有必要的。
[
编辑
]
链接外部库
库是预编译的目标文件
(object
files)的集合,它们可被链接进程序。静态库以後缀为‘
.a’的特殊的存档文件
(archive
file)存储。
标准系统库可在目录
/usr/lib 与
/lib 中找到。比如,在类
Unix 系统中
C 语言的数学库一般存储为文件
/usr/lib/libm.a。该库中函数的原型声明在头文件
/usr/include/math.h 中。
C
标准库本身存储为
/usr/lib/libc.a,它包含
ANSI/ISO C 标准指定的函数,比如‘
printf’。对每一个
C 程序来说,
libc.a
都默认被链接。
下面的是一个调用数学库
libm.a 中
sin
函数的的例子,创建文件
calc.c:
#include <math.h>
#include <stdio.h>
int
main (void)
{
double x = sin
(2.0);
printf ("The
value of sin(2.0) is %f\n", x);
return 0;
}
尝试单独从该文件生成一个可执行文件将导致一个链接阶段的错误:
$ gcc -Wall calc.c
-o calc
/tmp/ccbR6Ojm.o: In
function 'main':
/tmp/ccbR6Ojm.o(.text+0x19):
undefined reference to ‘sin’
函数
sin,未在本程序中定义也不在默认库‘
libc.a’中;除非被指定,编译器也不会链接‘
libm.a’。
为使编译器能将
sin
链接进主程序‘
calc.c’,我们需要提供数学库‘
libm.a’。一个容易想到但比较麻烦的做法是在命令行中显式地指定它:
$ gcc -Wall calc.c
/usr/lib/libm.a -o calc
函数库‘
libm.a’包含所有数学函数的目标文件,比如
sin,cos,exp,log及
sqrt。链接器将搜索所有文件来找到包含
sin 的目标文件。
一旦包含
sin 的目标文件被找到,主程序就能被链接,一个完整的可执行文件就可生成了:
$ ./calc
The value of
sin(2.0) is 0.909297
可执行文件包含主城许的机器码以及函数库‘
libm.a’中
sin 对应的机器码。
为避免在命令行中指定长长的路径,编译器为链接函数库提供了快捷的选项‘
-l’。例如,下面的命令
$ gcc -Wall calc.c
-lm -o calc
与我们上面指定库全路径‘
/usr/lib/libm.a’的命令等价。
一般来说,选项
-lNAME使链接器尝试链接系统库目录中的函数库文件
libNAME.a。一个大型的程序通常要使用很多
-l 选项来指定要链接的数学库,图形库,网络库等。
[
编辑
]
编译
C++
与
Fortran
GCC 是
GNU 编译器集合(
GNU
Compiler Collection)的首字母缩写词。
GNU
编译器集合包含
C,
C++,
Objective-C,
Fortran,
Java
和
Ada
的前端以及这些语言对应的库(
libstdc++,
libgcj,……)。
前面我们只涉及到
C 语言,那么如何用
gcc
编译其他语言呢?本节将简单介绍
C++ 和
Fortran 编译的例子。
首先我们尝试编译简单的
C++ 的经典程序
Hello
world:
#include <iostream>
int main(int
argc,char *argv[])
{
std::cout <<
"hello, world\n";
return 0;
}
将文件保存为‘
hello.cpp’,用
gcc 编译,结果如下:
$ gcc -Wall
hello.cpp -o hello
/tmp/cch6oUy9.o: In
function `__static_initialization_and_destruction_0(int, int)':
hello.cpp:(.text+0x23):
undefined reference to `std::ios_base::Init::Init()'
/tmp/cch6oUy9.o: In
function `__tcf_0':
hello.cpp:(.text+0x6c):
undefined reference to `std::ios_base::Init::~Init()'
/tmp/cch6oUy9.o: In
function `main':
hello.cpp:(.text+0x8e):
undefined reference to `std::cout'
hello.cpp:(.text+0x93):
undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& std::operator<<
<std::char_traits<char> >(std::basic_ostream<char,
std::char_traits<char> >&, char const*)'
/tmp/cch6oUy9.o:(.eh_frame+0x11):
undefined reference to `__gxx_personality_v0'
collect2: ld
returned 1 exit status
出错了!!而且错误还很多,很难看懂,这可怎么办呢?在解释之前,我们先试试下面的命令:
$ gcc -Wall
hello.cpp -o hello -lstdc++
噫,加上
-lstdc++选项後,编译竟然通过了,而且没有任何警告。运行程序,结果如下:
$ ./hello
hello, world
通过上节,我们可以知道,
-lstdc++
选项用来通知链接器链接静态库
libstdc++.a。而从字面上可以看出,
libstdc++.a
是
C++ 的标准库,这样一来,上面的问题我们就不难理解了──编译
C++ 程序,需要链接
C++
的函数库
libstdc++.a。
编译
C 的时候我们不需要指定
C
的函数库,为什幺
C++
要指定呢?这是由于早期
gcc
是指
GNU 的
C 语言编译器(
GNU C
Compiler),随着
C++,
Fortran
等语言的加入,
gcc的含义才变化成了
GNU 编译器集合(
GNU
Compiler Collection)。
C作为
gcc 的原生语言,故编译时不需额外的选项。
不过幸运的是,
GCC
包含专门为
C++ 、
Fortran
等语言的编译器前端。于是,上面的例子,我们可以直接用如下命令编译:
$ g++ -Wall
hello.cpp -o hello
GCC 的
C++ 前端是
g++,而
Fortran 的情况则有点复杂:在
gcc-4.0 版本之前,
Fortran
前端是
g77,而
gcc-4.0之後的版本对应的
Fortran 前端则改为
gfortran。下面我们先写一个简单的
Fortran 示例程序:
C Fortran 示例程序
PROGRAM
HELLOWORLD
WRITE(*,10)
10 FORMAT('hello,
world')
END PROGRAM
HELLOWORLD
将文件保存‘
hello.f’,用
GCC 的
Fortran 前端编译运行该文件
$ gfortran -Wall
hello.f -o hello
$ ./hello
hello, world
我们已经知道,直接用
gcc 来编译
C++ 时,需要链接
C++ 标准库,那么用
gcc
编译
Fortran时,命令该怎么写呢?
$ gcc -Wall hello.f
-o helloworld -lgfortran -lgfortranbegin
注意:上面这条命令与
gfortran 前端是等价的(
g77
与此稍有不同)。其中库文件
libgfortranbegin.a (通过命令行选项
-lgfortranbegin 被调用
)
包含运行和终止一个
Fortran
程序所必须的开始和退出代码。库文件
libgfortran.a 包含
Fortran
底层的输入输出等所需要的运行函数。
对于
g77 来说,下面两条命令是等价的(注意到
g77 对应的
gcc 是
4.0 之前的版本):
$ g77 -Wall hello.f
-o hello
$ gcc-3.4 -Wall
hello.f -o hello -lfrtbegin -lg2c
命令行中的两个库文件分别包含
Fortran 的开始和退出代码以及
Fortran 底层的运行函数
分享到:
相关推荐
该项目是一款基于Vue、JavaScript、HTML和CSS构建的myshop电商平台设计源码,总计包含94个文件,涵盖32个PNG图片、22个JavaScript文件、13个Vue组件文件、13个JPG图片文件、3个GIF图片文件、3个SCSS样式文件,以及其他必要的配置和管理文件。
基于c语言的对自己电脑系统测试.zip
基于Labview的--转子动平衡测控系统
基于c语言的青蛙过河小游戏.zip
酒店管理系统-酒店管理系统-酒店管理系统-酒店管理系统-酒店管理系统-酒店管理系统-酒店管理系统-酒店管理系统-酒店管理系统-酒店管理系统-酒店管理系统-酒店管理系统 1、资源说明:酒店管理系统源码,本资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 2、适用人群:计算机相关专业(如计算计、信息安全、大数据、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工等学习者,作为参考资料,进行参考学习使用。 3、资源用途:本资源具有较高的学习借鉴价值,可以作为“参考资料”,注意不是“定制需求”,代码只能作为学习参考,不能完全复制照搬。需要有一定的基础,能够看懂代码,能够自行调试代码,能够自行添加功能修改代码。 4. 最新计算机软件毕业设计选题大全(文章底部有博主联系方式): https://blog.csdn.net/2301_79206800/article/details/135931154 技术栈、环境、工具、软件: ① 系统环境:Windows ② 开发语言:Java ③ 框架:SpringBoot ④ 架构:B/S、MVC ⑤ 开发环境:IDE
本项目为基于DWR技术的Java与JavaScript无刷新聊天室设计源码,包含31个文件,涵盖9个Java源文件、4个JavaScript脚本文件、4个JAR库文件、3个XML配置文件以及其他相关文件,旨在实现一个无需刷新的即时聊天功能。
CSDN海神之光上传的全部代码均可运行,亲测可用,直接替换数据即可,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,可私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描博主博客文章底部QQ名片; 4.1 CSDN博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
基于asp.net的兼职就业平台设计与实现.docx
手写数字识别
2024C++期末大作业-英语翻译机.zip 电子词典模拟软件 1.创建关键词中英文词典 2.显示关键词中英文词典 3.输入英文关键字,查阅英汉词典 4.输入中文关键字,查阅英汉词典 5.退出
在线考试系统-在线考试系统-在线考试系统-在线考试系统-在线考试系统-在线考试系统-在线考试系统-在线考试系统-在线考试系统-在线考试系统-在线考试系统-在线考试系统 1、资源说明:在线考试系统源码,本资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 2、适用人群:计算机相关专业(如计算计、信息安全、大数据、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工等学习者,作为参考资料,进行参考学习使用。 3、资源用途:本资源具有较高的学习借鉴价值,可以作为“参考资料”,注意不是“定制需求”,代码只能作为学习参考,不能完全复制照搬。需要有一定的基础,能够看懂代码,能够自行调试代码,能够自行添加功能修改代码。 4. 最新计算机软件毕业设计选题大全(文章底部有博主联系方式): https://blog.csdn.net/2301_79206800/article/details/135931154 技术栈、环境、工具、软件: ① 系统环境:Windows ② 开发语言:Java ③ 框架:SpringBoot ④ 架构:B/S、MVC ⑤ 开发环境:IDE
在Java中使用DES进行加解密的示例DESUtil,注意,DES算法为不安全算法,主要因为它的56位密钥太短,容易被暴力破解。建议使用更安全的加密算法,如AES。
重要说明:图片数量太多,图片分辨率都调整为104x128 数据集类型:图像分类用,不可用于目标检测无标注文件 数据集格式:仅仅包含jpg图片,每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数):225639 分类类别数:262 更多信息:https://blog.csdn.net/FL1623863129/article/details/142592763
VMware-player-full-17.5.0-22583795.zip VMware-player-full-17.5.0-22583795.zip VMware-player-full-17.5.0-22583795.zip VMware-player-full-17.5.0-22583795.zip VMware-player-full-17.5.0-22583795.zip VMware-player-full-17.5.0-22583795.zip VMware-player-full-17.5.0-22583795.zip VMware-player-full-17.5.0-22583795.zip VMware-player-full-17.5.0-22583795.zip VMware-player-full-17.5.0-22583795.zip VMware-player-full-17.5.0-22583795.zip VMware-player-full-17.5.0-22583795.zip
3d_magic.apk
旅游管理系统-旅游管理系统-旅游管理系统-旅游管理系统-旅游管理系统-旅游管理系统-旅游管理系统-旅游管理系统-旅游管理系统-旅游管理系统-旅游管理系统-旅游管理系统 1、资源说明:旅游管理系统源码,本资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 2、适用人群:计算机相关专业(如计算计、信息安全、大数据、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工等学习者,作为参考资料,进行参考学习使用。 3、资源用途:本资源具有较高的学习借鉴价值,可以作为“参考资料”,注意不是“定制需求”,代码只能作为学习参考,不能完全复制照搬。需要有一定的基础,能够看懂代码,能够自行调试代码,能够自行添加功能修改代码。 4. 最新计算机软件毕业设计选题大全(文章底部有博主联系方式): https://blog.csdn.net/2301_79206800/article/details/135931154 技术栈、环境、工具、软件: ① 系统环境:Windows ② 开发语言:Java ③ 框架:SpringBoot ④ 架构:B/S、MVC ⑤ 开发环境:IDE
oracle的OCI库文件19.23,dbru,java
本文件是一份关于 Matlab 软件基础入门的文本文件,旨在为初学者提供基本的 Matlab 软件使用方法和技巧。文件内容涵盖了 Matlab 的基本概念、语法规则、常用函数以及一些实用的编程技巧。通过本文件的学习,读者可以快速掌握 Matlab 软件的基本操作,为进一步学习和应用 Matlab 软件打下坚实的基础。 本文件的内容丰富、结构清晰,适合初学者系统学习和掌握 Matlab 软件的基础知识和技能。同时,本文件也提供了一些实用的编程技巧和应用实例,帮助读者更好地理解和应用 Matlab 软件。
ofd阅读器版本 3.0
漏洞 Chrome 浏览器惊现严重漏洞