基于Linux(Ubuntu)系统下使用g++和Makefile编译C语言程序
前言
本文是基于Ubuntu系统使用g++和Makefile进行C语言编译实操,阐述编译时的语法规则,通过分别在Ubuntu系统和Windows系统上进行C语言的编译,来展示文件编译并执行的过程。
一、安装Ubuntu
Ubuntu简介
Ubuntu是一款基于Debian的Linux发行版,由南非公司Canonical Ltd.开发和支持。
Ubuntu的主要特点和优点如下:
易用性强:Ubuntu采用 GNOME和Unity作为默认的桌面环境,界面简洁明了,操作流程规范化,对新手用户友好。
安全性高:Ubuntu采用了稳定的Debian作为基础,更新及时,安全漏洞能及时修补,相对于其他Linux发行版更加稳定安全。
软件包丰富:Ubuntu的软件仓库软件包数量众多,几乎包含所有常用软件,无需从第三方下载就可以直接安装和使用。
长期支持版本。Ubuntu每两年会发布一个长期支持版本(LTS),这些版本将获得5年的技术支持和安全更新。
开源免费:Ubuntu完全开源和免费,用户可以自由下载、使用、修改和发布。
跨平台支持:Ubuntu不仅支持桌面系统,还支持服务器和云平台等多个环境。
社区活跃:Ubuntu拥有众多活跃的开发者和用户社区,问题解答更快,使用和学习资源更丰富。
所以总体来说,Ubuntu是一个易于使用、功能强大、安全可靠的Linux发行版,尤其适合Linux新手及服务器环境使用。它以开放和免费著称,是目前最受欢迎的Linux系统之一。
Ubuntu安装步骤
Ubuntu安装步骤见以下链接(注意查看自己电脑的类型来决定安装方式)
链接: link
安装完进入系统
二、使用g++编译
安装g++
使用快捷键Ctrl+Alt+T打开窗口,输入以下命令:
sudo apt install g++
当然,如果发现出现无依赖包等报错,或者安装缓慢等问题,通常是因为镜像源在国外而导致的,Ubuntu换源(建议换清华源或者华为云)的操作见以下链接,此处不多阐述:
链接: link
安装完成后,输入以下命令,查看g++的版本:
g++ -v
输入命令的结果如下图:
编写程序并编译运行
在桌面建立文件夹并创建hello.c文件
cd 桌面
mkdir c++
cd c++
vim hello.c
编写程序:
按ESC(进入命令行模式),然后输入”:wq”,冒号表示开始输入命令,字母w代表保存文件,字母q代表退出编辑器。
编译并运行:
g++ hello.c -o hello
./hello
上述命令由两部分组成。我们将分别对它们进行解析。
g++ hello.c -o hello
这是一个在命令行中使用g++
编译器编译 C 程序的命令。让我们分解下这个命令:
g++
:这是编译器的名称。在这个例子中,我们使用的是 GNU 的 C++ 编译器。hello.c
:这是你要编译的源代码文件。虽然.c
通常是 C 语言代码的扩展名,但g++
也可以编译该文件,只不过它会以 C++ 的方式进行编译和链接。-o hello
:这是一个选项,用于指定输出的可执行文件名。在这个例子中,输出的文件名将为hello
。
./hello
这是一个在命令行中执行程序的命令。让我们分解下这个命令:
./
:在 Unix 和类 Unix 系统(比如 Linux,macOS)中,./
前缀表示在当前目录中。hello
:这就是你要运行的程序。在上一个命令中,我们将编译后的可执行文件命名为hello
。
所以,./hello
命令就是在当前目录下运行名为hello
的程序。
g++和gcc的区别
笔者发现自己在编写上述内容的时候使用g++进行编译,进过查询得知g++和gcc的区别,如下:
GCC
和 G++
是 GNU 编译器套件 (GCC
,GNU Compiler Collection) 的两个不同的驱动程序。他们的主要区别在于它们处理源代码和链接库的方式。
GCC (GNU Compiler Collection):
GCC
是一个编译器套件,它支持多种编程语言,包括 C, C++, Objective-C, Fortran, Ada 和 Go 等。- 当使用
GCC
命令来编译程序时,如果不明确指定编程语言,它将默认为 C 语言。
**-G++
是GCC
套件中的一个特定驱动程序,它是专门用于编译和链接 C++ 代码的。 - 当使用
G++
命令来编译程序时,它将默认为 C++ 语言,并会自动链接 C++ 标准库。
因此,如果你正在编译 C++ 程序,你应该使用G++
。如果你正在编译 C 程序,你可以使用GCC
。但是,也可以使用G++
来编译和链接 C 程序,只是在这种情况下,链接的将是 C++ 标准库,这可能会导致一些不必要的开销。
实验案例
实验要求
编写一个主程序文件 main1.c 和一个子程序文件 sub1.c, 要求:子程序sub1.c 包含一个算术运算函数 float x2x(int a,int b),此函数功能为对两个输入整型参数做某个运算,将结果做浮点数返回;主程序main1.c,定义并赋值两整型变量,然后调用函数 x2x,将x2x的返回结果printf出来。
实验一请在ubuntu系统用gcc 命令行方式编译主程序main1.c 并运行;
实验二请在windows系统下用熟悉的编译工具编译主程序main1.c 并运行。
实验三在任务4基础上,在ubuntu系统下用Makefile方式编程主程序
实验一
新增三个窗口,按要求编写程序:
编译但遇见报错:
其中报错是因为#include“sub1.h”写成#include<sub1.h>
#include 和 #include"filename"的区别如下:
- 查找路径不同:
#include 会在编译器默认路径下查找filename头文件,如标准
#include"filename" 会先在当前源文件目录下查找filename文件,如果没有找到再去默认路径查找。 - 文件名处理不同:
#include 的filename不会处理文件名的路径信息和引号。
#include"filename" 的filename会保留完整的路径信息和引号,这对包含相对路径的文件更友好。 - 只能包含头文件:
#include 只能包含头文件(.h),不能包含源文件(.include"filename" 可以包含头文件也可以包含源文件(.结来说:
- #include 用在标准头文件中
- #include"filename" 用在用户自定义的本地头文件中
- 前者只查找默认路径,后者先查找本地再查找默认路径
- 前者只能包含头文件,后者可以包含头文件也可以包含源文件
一般情况下: - 标准库头文件使用#include
- 本地头文件使用#include"filename"
这样可以更好的管理头文件包含。
修改后再次遇见了错误:
此处再次提醒读者要按规范编写程序
修改后再次编译运行
先输入 gcc -c sub1.c
将sub1.c文件变成sub1.o目标文件
再输入 gcc main.c sub1.o -o main1
编译main.c文件为目标文件main1.o,再与sub1.o文件链接,生成main 可执行文件
输入./main
注意:文件的名称需要对应自己创建的文件的名称,此处只是一个示例
实验二
编写程序:
编译运行:
实验三
makefile简介:
makefile是makefile文件,它是makefile的简称。makefile是makefile文件中最重要的一个概念。
- makefile是一种用于自动编译源代码的文件,它描述了源代码如何从头编译成可执行文件。
- makefile中定义了项目的依赖关系,以及如何编译项目中的每个源文件成目标文件和最终的可执行文件。
- make命令读取makefile文件,根据依赖关系判断哪些文件需要重新编译,从而实现自动编译项目。
makefile的主要组成部分: - 目标:依赖项 指令 指令
- 目标通常是可执行文件或库文件等。
- 依赖项是目标依赖的源文件或其他文件。
- 指令描述如何更新目标。
makefile的主要功能:
- 自动化编译过程,避免手动编译每个源文件。
- 只编译依赖项发生变化的文件,提高效率。
- 统一项目的编译配置,便于维护。
- 可以设置编译参数、链接库等配置。
所以总体来说,makefile是自动化编译重要文件,它描述了项目的依赖关系和编译规则。通过makefile可以实现项目的自动编译功能。
运行结果
总结
通过本次实验,读者不仅了解了GCC和Makefile的基本语法规则,更重要的是掌握了整个流程:
- 使用GCC预处理源文件,生成预处理文件。这一步处理了头文件包含和宏定义等。
- 编译预处理文件,生成汇编代码文件。这一步将指令。
- 汇编汇编代码文件,生成目标文件。这一步将汇编代码组织成机器可以直接执行的格式。
- 链接目标文件,生成可执行文件。这一步将多个目标文件链接成一个完整的可执行程序。
使用Makefile可以自动化这个流程,避免每次都手动编译链接。Makefile也定义了项目的依赖关系,只编译依赖项更新的文件。
相比Windows,Ubuntu让我们更深入地理解编译原理。Windows对用户更友好,但Ubuntu能让我们学习底层知识。两者都有各自的优点。总之,这次实验让读者不仅能掌握工具的使用,更重要的是能理解程序从源代码到可执行文件的整个转换过程,对深入学习编程很有帮助。
参考文献
https://blog.csdn.net/Monajim/article/details/120293690
https://blog.csdn.net/weixin_47156401/article/details/125653897?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169460546116800192242627%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=169460546116800192242627&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allbaidu_landing_v2~default-1-125653897-null-null.142v93insert_down1&utm_term=g%2B%2B%20gcc&spm=1018.2226.3001.4187
https://blog.csdn.net/weixin_46410217/article/details/123786316?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169460464416800222881828%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=169460464416800222881828&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-2-123786316-null-null.142v93insert_down1&utm_term=Ubuntu%E6%8D%A2%E6%BA%90&spm=1018.2226.3001.4187
https://blog.csdn.net/weixin_38391755/article/details/80380786?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169459603616800184172169%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=169459603616800184172169&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-80380786-null-null.142v93insert_down1&utm_term=makefile&spm=1018.2226.3001.4187