项目九 使用gcc和make调试程序

项目九 使用gcc和make调试程序

#职业能力目标和要求
1,理解程序调试。
2,掌握利用gcc进行调试的方法。
3,掌握使用make编译的方法。

9.1 了解程序的调试

9.1.1 编译时错误

  • 主要是语法错。

9.1.2 运行时错误

  • 编译器检查不出这类错误,仍然可以生成可执行文件,但是运行时会出错而导致程序崩溃。

  • 要区分编译时和运行时。

9.1.3 逻辑错误和语义错误

  • 如果程序里有逻辑错误,编译和运行都会很顺利,看上去也不产生任何错误信息,但是程序没有干它该干的事情,而是干了别的事情。

9.2 使用传统程序语言进行编译

9.2.1 安装GCC

1,认识GCC

  • GCC是一套由GNU开发的编程语言编译器,以GPL许可证发行的自由软件。
  • 可以处理C语言等。

2,安装GCC

#1,检查是否安装
[root@localhost ~]# rpm -qa | grep gcc
libgcc-4.8.5-39.el7.x86_64	#没有安装#2,如果系统还没有安装GCC软件包,可以使用yum命令安装所需软件包。
#挂载ISO安装映像:
[root@localhost ~]# mount /dev/cdrom /iso
#制作用于安装的yum源文件
[root@localhost ~]# vim /etc/yum.repos.d/dev.repo
# /etc/yum.repos.d/dvd.repo
# or for ONLY the media repo, do this:
# yum --disablerepo=\* --enablerepo=c6-media [command]
[dvd]
name=dvd
baseurl=file:///iso
gpgcheck=0
enabled=1
#使用yum命令查看GCC软件包的信息
[root@localhost ~]# yum info gcc
#使用yum命令安装GCC。
[root@localhost ~]# yum clean all		#清除缓存
[root@localhost ~]# yum -y install gcc		#Complete!表示安装成功
#所有软件包安装完毕,可以使用rpm命令再一次进行查询
[root@localhost ~]# rpm -qa | grep gcc
libgcc-4.8.5-39.el7.x86_64
gcc-4.8.5-39.el7.x86_64

9.2.2 单一程序:打印 hello world

1,编辑程序代码即源码

[root@localhost ~]# vim hello.c
#include <stdio.h>		#这个#号不是注解
int main(void)
{printf("Hello World\n");
}

2,开始编译与测试运行

[root@localhost ~]# gcc hello.c
[root@localhost ~]# ll hello.c a.out	#默认生成的文件
-rwxr-xr-x. 1 root root 8360 Nov 28 14:17 a.out
-rw-r--r--. 1 root root   68 Nov 28 14:16 hello.c
[root@localhost ~]# ./a.out
Hello World
#要生成目标文件(object file),进行其他操作,而且执行文件的文件名也不能用默认的a.out
[root@localhost ~]# gcc -c hello.c[root@localhost ~]# ll hello.*
-rw-r--r--. 1 root root   68 Nov 28 14:16 hello.c
-rw-r--r--. 1 root root 1496 Nov 28 14:29 hello.o		#目标文件
[root@localhost ~]# gcc -o hello hello.o
[root@localhost ~]# ll hello*
-rwxr-xr-x. 1 root root 8360 Nov 28 14:30 hello		#可执行文件(-o的结果)
-rw-r--r--. 1 root root   68 Nov 28 14:16 hello.c
-rw-r--r--. 1 root root 1496 Nov 28 14:31 hello.o
[root@localhost ~]# ./hello
Hello World

9.2.3 主程序,子程序链接,子程序的编译

1,撰写所需要的主程序、子程序

#我们以thanks.c这个主程序去调用thanks_2.c子程序
[root@localhost ~]# vim thanks.c
#include <stdio.h>
int main(void)
{printf("Hello Word\n");thanks_2();
}[root@localhost ~]# vim thanks_2.c
#include <stdio.h>
void thanks_2(void)
{printf("Thak you\n");
}

2,进行程序的编译与链接(Link)

1,开始将源码编译成为可执行的binary file。
[root@localhost ~]# gcc -c thanks.c thanks_2.c
[root@localhost ~]# ll thanks*
-rw-r--r--. 1 root root   71 Nov 28 14:40 thanks_2.c
-rw-r--r--. 1 root root 1496 Nov 28 15:55 thanks_2.o	<==生成的目标文件
-rw-r--r--. 1 root root   86 Nov 28 15:55 thanks.c
-rw-r--r--. 1 root root 1560 Nov 28 15:55 thanks.o		<==生成的目标文件
[root@localhost ~]# gcc -o thanks thanks.c thanks_2.c
[root@localhost ~]# ll thanks*
-rwxr-xr-x. 1 root root 8424 Nov 28 15:56 thanks
-rw-r--r--. 1 root root   71 Nov 28 14:40 thanks_2.c
-rw-r--r--. 1 root root 1496 Nov 28 15:55 thanks_2.o
-rw-r--r--. 1 root root   86 Nov 28 15:55 thanks.c
-rw-r--r--. 1 root root 1560 Nov 28 15:55 thanks.o		<==生成可执行标文件2,执行可执行文件
[root@localhost ~]# ./thanks
Hello Word
Thak you    

9.2.4 调用外部函数库:加入链接的函数库

#计算三角函数里面的sin90°,大多数程序语言都使用弧度而不是“角度”,180度等于3.14弧度。
[root@localhost ~]# vim sin.c
#include <stdio.h>
int main(void)
{float value;value = sin ( 3.14 / 2 );printf("%f\n",value);
}
#该结果会报错,我们编译时加入额外函数库链接的方式
[root@localhost ~]# gcc sin.c -lm -L/lib -L/usr/lib
[root@localhost ~]# ./a.out
<==I:是加人某个函数库( library) 的意思。
<==m.县libm.so函数库,其中,lib与扩展名(.a或.so)不需要写。

9.2.5 GCC的简易用法(编译、参数与链接)

1,仅将原始码编译成为目标文件,并不制作链接等功能。

[root@localhost ~]# gcc -c hello.c

  • 会生成hello.o文件,但不会产生二进制可执行文件。

2,在编译的时候,依据作业环境给予执行速度优化。

[root@localhost ~]# gcc -c hello.c -O

3,在进行二进制可执行文件制作时,将链接的函数库与相关的路径填入

[root@localhost ~]# gcc sin.c -lm -l/usr/lib -I/usr/include

  • -lm指的是libm.so或libm.a函数库文件。
  • -L后面接的路径是刚刚上面那个函数库的搜索目录。
  • -I后面接的是源码内的include文件所在的目录。

4,将编译的结果生成某个特定文件。

[root@localhost ~]# gcc -o hello hello.c

  • -0后面接的是要输出的二进制可执行文件名。

5,在编译的时候,输出较多的信息说明。

[root@localhost ~]# gcc -o hello hello.c -Wall

9.3 使用make进行宏编译

9.3.1 为什么要用make

**1,make功能:**可以简化编译过程里面所下达的命令

**2,案例:**假设执行文件里面包含了4个源码文件,分别是main.c、haha.c 、sin value.c和cos _value.c, 这4个文件的功能如下。

  • main.c:主要目的是让用户输人角度数据与调用其他3个子程序。
  • haha.c:输出一堆信息。
  • sin value.c:计算用户输人的角度( 360)正弦数值。
  • cos value.c:计算用户输人的角度( 360)余弦数值。
[root@localhost ~]# mkdir /c
[root@localhost ~]# cd /c
[root@localhost c]# vim main.c
#include <stdio.h>
#define pi 3.14159
char name[15];
float angle;int main(void)
{  printf ("\n\nPlease input your name: ");scanf ("%s", &name);printf ("\nPlease enter the degree angle (ex> 90): " );scanf ("%f", &angle );haha(name);sin_value(angle);cos_value(angle);
}
[root@localhost c]# vim haha.c
#include <stdio.h>
int haha(char name[15] )
{printf ("\n\nHi, Dear %s, nice to meet you.", name);
}
[root@localhost c]# vim sin_value.c#include <stdio.h>
#define pi 3.14159
float angle;
void sin_value (void)
{float value;value = sin( angle / 180.* pi );printf ("\nThe Sin is: %5.2f\n", value);
}
[root@localhost c]# vim cos_value.c
#include <stdio.h>
#define pi 3.14159
float angle;
void cos_value(void)
{float value;value=cos(angle/180. * pi);printf ("The Cos is: %5.2f\n", value) ;
}
1,先进行目标文件的编译,最终会有4*.o的文件名出现。
[root@localhost c]# gcc -c main.c
[root@localhost c]# gcc -c haha.c
[root@localhost c]# gcc -c sin_value.c
[root@localhost c]# gcc -c cos_value.c2,再链接形成可执行文件main,并加人libm的数学函数。
[root@localhost c]# gcc -o main main.o haha.o sin_value.o cos_value.o -lm -L/usr/lib -L/lib3,本程序的运行结果,必须输人姓名、360度角的角度值来完成计算。    
[root@localhost c]# ./main    
Please input your name: Bobby
Please enter the degree angle (ex> 90): 30
Hi, Dear Bobby, nice to meet you.
The Sin is:  0.50
The Cos is:  0.874,用一个步骤完成上述操作
#先编辑makefile这个规则文件,内容是制作出main这个可执行文件
[root@localhost c]# vim makefile    
main: main.o haha.o sin_value.o con_value.ogcc -o main main.o haha.o sin_value.o cos_value.o
#尝试使用makefile制订的规则进行编译
[root@localhost c]# rm -f main *.o	<==先将之前的目标文件删除
[root@localhost c]# make
cc    -c -o main.o main.c
cc    -c -o haha.o haha.c
....       

9.3.2 了解makefile的基本语法与变量

1,基本的Makefile守则

目标(target):目标文件1  目标文件2
<tab>  gcc  -0  欲创建的可执行文件  目标文件1  目标文件2

注:创建可执行文件的语法就是按“Tab”键开头的那一行。

  • 在makefile当中的#代表注解。
  • 需要在命令行(例如gcc这个编译器命令)的第一个字节按 “Tab” 键。
  • 目标(target) 与相关文件(就是目标文件)之间需以“:” 隔开。
#例如执行一个命令就直接清除掉所有的目标文件与可执行文件
(1)先编辑makefile 来建立新的规则,此规则的目标名称为clean。
[root@localhost c]# vim makefile    
main: main.o haha.o sin_value.o con_value.ogcc -o main main.o haha.o sin_value.o cos_value.o -lm
clean:rm -f main main.o haha.o sin_value.o cos_value.o(2)以新的目标(clean)测试,看看执行make的结果。            
[root@localhost c]# make clean
rm -f main main.o haha.o sin_value.o cos_value.o(3)我们可以通过shell script的“变量”来简化Makefile。
[root@localhost c]# vim makefile    
LIBS = -lm
OBJS =  main.o haha.o sin_value.o con_value.o
main:$(OBJS)gcc -o main $(OBJS) $(LIBS)
clean:rm -f main $(OBJS)                   
  • 变量与变量内容以“=” 隔开,同时两边可以有空格。
  • 变量左边不可以按“Tab"键,例如上面范例的第一行LIBS左边不可以按“Tab’键。
  • 变量与变量内容在“=”两边不能具有“:”。
  • 习惯上,变量最好是以“大写字母”为主。
  • 运用变量时,使用$ {变量}或$ (变量)。
  • 该shell的环境变量是可以被套用的,例如提到的CFLAGS这个变量。
  • 在命令行模式也可以定义变量。

**2,**由于GCC在进行编译的行为时,会主动地去读取CFLAGS这个环境变量,所以,可以直接在shell定义这个环境变量,也可以在makefile文件里面去定义,或者在命令行当中定义。

[root@localhost c]# CFLAGS="-Wall" make clean main
#这个操作在make上进行编译时,会取用CFLAGS的变量内容#也可以这样:
[root@localhost c]# vim makefile    
LIBS = -lm
OBJS =  main.o haha.o sin_value.o con_value.o
CFLAGS = -Wall
main:$(OBJS)gcc -o main $(OBJS) $(LIBS)
clean:rm -f main $(OBJS)              

3,环境变量使用的规则如下:

  • make 命令行后面加上的环境变量优先。
  • makefile 里面指定的环境变量第二。
  • shell原本具有的环境变量第三。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/181027.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法刷题】Day7

文章目录 283. 移动零1089. 复写零 283. 移动零 原题链接 看到题目&#xff0c;首先看一下题干的要求&#xff0c;是在原数组内进行操作&#xff0c;平切保持非零元素的相对顺序 这个时候我们看到了示例一&#xff1a; [ 0, 1, 0, 3,12 ] 这个时候输出成为了 [ 1, 3, 12, 0, …

ground truth 在深度学习任务中代表的是什么意思?

1、概念 在深度学习领域&#xff0c;ground truth (中文意思是“地面真实值”或“基准真实值”&#xff0c;简单理解就是真实值) 是指用于训练和评估模型的准确标签或数据。它是机器学习算法的参考标准&#xff0c;用于衡量模型的性的和判断模型的准确性&#xff0c;本文将介绍…

泗博Modbus转Profinet网关TS-180对水表流量的监控应用

应用场景&#xff1a; 陕西某工程技术有限公司在一民生工程项目中&#xff0c;需要对公园直饮水进行净化保证其水质。直饮水净化装置需根据用水量不定期的维护&#xff0c;通过统计各个净化装置净化的直饮水的流量&#xff0c;来实现提前维护目的。 应用痛点&#xff1a; 项目…

dsp cmd文件详解

DSP学习&#xff08;8&#xff09;—— linker.cmd文件解析-CSDN博客

4/150:寻找两个正序数组的中位数⭐

题目&#xff1a;寻找两个正序数组的中位数 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 题解1&#xff1a;暴力 暴力思路简介&#xff0c;…

基于ArcGIS Pro、R、INVEST等多技术融合下生态系统服务权衡与协同动态分析实践应用

生态系统服务是指生态系统所形成的用于维持人类赖以生存和发展的自然环境条件与效用&#xff0c;是人类直接或间接从生态系统中得到的各种惠益。联合国千年生态系统评估&#xff08;Millennium ecosystem assessment&#xff0c;MA&#xff09;提出生态系统服务包括供给、调节、…

项目中的svg图标的封装与使用

1.安装 npm install vite-plugin-svg-icons -D2.在vite.config.ts中配置 **所有的svg图标都必须放在assets/icons // 引入svg import { createSvgIconsPlugin } from vite-plugin-svg-iconsexport default defineConfig({plugins: [vue(),createSvgIconsPlugin({iconDirs: [p…

项目:基于UDP的网络聊天室

项目需求&#xff1a; 1.如果有用户登录&#xff0c;其他用户可以收到这个人的登录信息 2.如果有人发送信息&#xff0c;其他用户可以收到这个人的群聊信息 3.如果有人下线&#xff0c;其他用户可以收到这个人的下线信息 4.服务器可以发送系统信息 服务器代码&#xff1a; #i…

【C 语言经典100例】C 练习实例14 - 将一个正整数分解质因数

题目&#xff1a;将一个正整数分解质因数。例如&#xff1a;输入90,打印出90233*5。 程序分析&#xff1a;对n进行分解质因数&#xff0c;应先找到一个最小的质数k&#xff0c;然后按下述步骤完成&#xff1a; (1)如果这个质数恰等于&#xff08;小于的时候&#xff0c;继续执…

《数据结构与测绘程序设计》试题详细解析(仅供参考)

一. 选择题&#xff08;每空2分&#xff0c;本题共30分&#xff09; &#xff08;1&#xff09;在一个单链表中&#xff0c;已知q所指结点是p所指结点的前驱结点&#xff0c;若在q和p之间插入结点s&#xff0c;则执行( B )。 A. s->nextp->next; p->nexts; …

Vue 打包上线后的缓存问题

问题描述 在使用vue脚手架搭建前端工程时&#xff0c;经常会遇到打包上线后的缓存问题。具体表现为&#xff0c;当程序版本升级时&#xff0c;用户仍然访问到旧版本的页面。许多开发者会直接在index.html中加入类似以下代码来解决缓存问题&#xff1a; <meta http-equiv&q…

Linux配置SFTP用户的详细过程

0. 背景 Linux机器上已有路径/data/tomcat/apache-tomcat-8.5.96/webapps/webroot,需要在该路径之下配置一个目录对外暴露给业务人员使用。业务人员使用sftp协议上传文件。 下面是相关配置&#xff1a; SFTP 用户名&#xff1a;iios SFTP主目录&#xff1a;/data/tomcat/apa…

用人部门职位说明书模板

用人部门职位说明书模板 岗位名称 岗位职责&#xff1a; 1. 2. 3. 4. 任职要求&#xff1a; 1. 2. 3. 4. 岗位名称 岗位职责&#xff1a; 1. 2. 3. 4. 任职要求&#xff1a; 1. 2. 3. 4. 【例如】 售前咨询顾问 岗位职责&#xff1a; 1、负责电子政务…

王者荣耀游戏制作

1.创建所需要的包 2.创建怪物类 bear package beast;import wangzherogyao.GameFrame;public class Bear extends Beast {public Bear(int x, int y, GameFrame gameFrame) {super(x, y, gameFrame);setImg("img/bear.jpg");width 85;height 112;setDis(65);}} b…

Encoder、Decoder和Encoder-Decoder

首先LLM有3种架构&#xff1a;Encoder-only、Decoder-only、encode-decode 整体情况 1、Encoder将可变长度的输入序列编码成一个固定长度的向量&#xff0c;比如在bert中应用的encoder&#xff0c;其实是输入和输出是等长的向量。通常情况下&#xff0c;encoder是用来提取特征…

实现产品License验证功能

通过研究调查&#xff0c;可以利用Truelicense开源框架实现&#xff0c;下面分享一下如何利用Truelicense实现授权验证功能。 在此之前先介绍一下License授权和验证的原理&#xff1a; 1、 首先需要生成密钥对&#xff0c;方法有很多&#xff0c;JDK中提供的KeyTool即可生成…

c++socket的select函数以及多路复用

csocket的select函数以及多路复用 1.select函数原型使用示例及解释 2.select()函数返回值3.select()函数与socket阻塞的关系与原因4.select函数的意义5.深入理解select模型&#xff08;1&#xff09;特点&#xff08;2&#xff09;带外数据&#xff08;2&#xff09;select函数…

和鲸全程支持:第二届粤港澳大湾区(黄埔)国际算法算例大赛初赛赛程圆满收官!

随着新一轮科技革命与产业变革的加速演进&#xff0c;算法&#xff0c;作为一种战略性的科技、生产要素&#xff0c;已成为推动数字技术与实体经济深度融合的核心支撑。为助力地区大数据与人工智能算法的生态体系建设、赋能社会经济的高质量发展&#xff0c;琶洲实验室&#xf…

如何与LEONI建立EDI连接?

莱尼LEONI是一家为汽车及其他行业提供能源数据管理产品、解决方案及服务的全球供应商。供应链范围从研发生产标准化电缆、特种电缆和数据电缆到高度复杂的布线系统和相关组件。本文将介绍如何与莱尼LEONI建立EDI连接。 什么是EDI&#xff1f; EDI全称Electronic Data Interch…

C# WPF上位机开发(乘法计算小软件)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 上面一篇文章&#xff0c;我们简单了解了怎么用xaml来设计界面。和传统的c# form不一样&#xff0c;它除了可以通过拖拽的方法来实现界面的编写之外…