Linux系统上的C程序的编译与调试

Ubuntu安装开发环境

       首先,我们要知道Ubuntu是什么,我们都知道Linux是操作系统,那Ubuntu则是它的其中一个发行版本,就好比Linux如果是汽车底盘,那Ubuntu就是一个完整的家用小汽车,而我们的电脑只认识二进制机器码,所以此时我们就需要有编译器来翻译,因此我们就要安装一些编译器。

(因为小编已经提前安装了,所以给出下列详细安装步骤,一起动手试一下吧!)

安装时先切换管理员权限,普通用户是没有资格的--sudo su

然后执行apt update--是为了刷新列表,系统找不到gcc最新安装包,安装就会容易失败。

安装gcc,来编译c程序,执行命令--apt install gcc

安装g++,来编译c++程序,执行命令--apt install g++

安装vim编辑器,执行命令--apt install vim

安装make,执行命令--apt install make

安装网络工具包,执行命令--apt install net-tools

gcc编译

        安装完成后,就引出它真正的使命,就是变成CPU可执行的程序。以我们的main.c文件为例,首先我们经过预处理得到.i文件,然后进行编译得到.s汇编文件,之后进行汇编得到.o目标文件,最后通过链接生成可执行的最终文件,下面我们来详细说一下这四个步骤。

(1)预编译

       简而言之就是处理代码里面带#的东西,删除所有的注释,添加行号和文件名标识,保留所有的#pragma编译器指令,就是把所有"指令"展开,清理代码,得到一份干净,没有任何宏、头文件的纯C代码。

         gcc -E main.c -o main.i

(2)编译

编译过程就是把预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后生成相应的汇编代码文件,这个过程就是最核心最复杂的阶段。

        gcc -S main.i -o main.s

(3)汇编

汇编则是将代码变成机器二进制代码(0和1)

       gcc -c main.s -o main.o

(4)链接

链接就是将多个.o文件+系统库合并在一起,生成可以执行的最终文件。

       gcc main.o -o main

       为什么它们要分四步骤进行,首先肯定是由于分工清晰,便于开发与优化,当然最重要的还是因为代码复用,像printf这些函数所有人都要用,不用每个人代码都写一遍,统一放在数据库中,链接的时候就可以调用。

makefile和make

    为什么会提到makefile与make,是因为若只有一个文件main.c时,则可以手动敲gcc main.c -o main,这条命令内部自动走完上面四个步骤,但若是几十个上百个.c文件呢,如果每次修改代码,一条一条敲速度会非常慢的,因此makefile就是解决这一痛点的!

Makefile是一份“任务清单/脚本”:里面写好规则,我们只需要用就行。

Make是读取这份清单的工具,按照里面写好的规则,自动调用gcc执行4大编译步骤。

简单示例:

新建一个main.c文件

创建最重要的文件Makefile

执行使用

这里的rm -f main其实就是remove force强制删除哦。

gdb调试

下面我们先看一个示例:

建立了一个test.c文件

上述情况就是出现错误了,但是我们的语法又没问题,又可以执行,所以就引出了调试,学会调试是非常重要的。

     首先我们要了解什么是调试,其次我们为什么要调试,调试的对象是谁,最后我们该怎样调试。

①什么是调试:调试是一步一步跟踪程序运行,找到代码bug的过程。

②我们为什么要调试:代码运行结果和我们预想的不同,肉眼看不出错误。

                                    程序直接崩溃闪退,不知道哪里出错。

                                    可以暂停程序,查看变量里面的值,定位逻辑漏洞。

③调试对象是谁:带调试信息的可执行程序。

调试的对象肯定不是上面的test.c,因为它只是一个文本文件,我们是不可以给一个文本文件赋值的。对计算机来讲,test才是磁盘上的程序,而./test就是正在运行的程序。我们为了不让它一次性运行完,想让它走一步停一下,所以我们调试的就是运行起来的程序,我们称它为进程。我们来用gdb调试这个程序。

④怎样进行调试:

前提引入:我们在windows开发的时候有两个版本,一个Debug版本一个Release版本。Debug版本用于开发调试,体积较大,Release版本是发行版本,是提供给用户使用的版本,默认用gcc编译时Release版本。

此处可查看gdb这个工具的一些信息

这告诉我们在test中没有找到任何调试信息

此时运行的还是gdb

先变为Debug版本

重新调试,l:显示代码  l=list

b=break b+行号:在第七行加断点

info break :告诉我们在第七行加了断点

运行程序

n:单步执行

p buff:打印buff中的值

找出问题所在了!你也快来试试!

当然调试肯定还有更加便捷的方法,这个只是最基础版本的。

下一章我们将讲解库文件的生成与使用。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐