Linux-GCC、makefile、GDB
GCC
gcc -E test.c -o test.i | 预处理(-o指定文件名) |
gcc -S test.i -o test.s | 编译 |
gcc -c test.s -o test.o | 汇编 |
gcc test.o -o test | 链接(生成一个可执行程序的软连接) |
gcc test.c -o test | 一条指令可以完成以上所有内容 |
gcc *.c -I(大写的i) include | 由于在main.c中找不到当前文件夹中的头文件,所以用-I指定在include文件夹中找对应的头文件。 |
head.h包含所有运算的函数声明。
以下代码由于程序中没有DEBUG宏,所以不会输出"我被执行"。
#include<stdio.h>int main(){#ifdef DEBUGprintf("我被执行\n");#endifprintf("hello world");return 0;
}
gcc test.c -D DEBUG | 由于局外定义了宏所以会输出"我被执行"。 |
制作静态库:
gcc -c add.c sub.c div.c mult.c -I(大写的i) ./include | 生成add.o sub.o div.o mult.o |
ar rcs libcal.a *.o | 将所有.o文件打包(如果静态库要发布出去要有libcal.a 和 head.h两个文件)。 |
使用静态库:
head.h和libcal.a和main.c在同一个目录。
gcc main.c -o cal -L ./ -l(小写的L) cal | -L指定库路径 -l指定库名称,掐头(lib)去尾(.a) |
./cal | 执行 |
制作动态库:
gcc -c -fpic add.c sub.c mult.c div.c -I(大写的i) ./include | 生成.o文件 |
gcc -shared *.o -o libcal.so | 生成动态库 |
使用动态库:
head.h和libcal.so和main.c要在同一个目录。
gcc main.c -L ./ -l(小写L) cal -o app | 生成app可执行文件 |
./app | 执行 |
ldd app | 可以查看app文件所需的动态库。 |
当app文件和libcal.so不在同一目录,执行app文件会报错。
解决方案:
一、
sudo vim /etc/ld.so.conf |
添加新路径:动态库所在的路径 |
sudo ldconfig |
二、
sudo ln -s /xxx/xxx/libxxx.so /user/lib/libxxx.so |
makefile
当目录下有makefile文件和一系列.c文件。
gcc *.c -o app | 生成一个app可执行文件。 |
make | 由于上述过程过于繁琐,用make可以自动化编译。(生成.o文件和一个可执行程序) |
make clean | 删除.o文件和那个可执行文件。 |
makefile的编写:
vim makefile |
cal:add.c div.c main.c mult.c sub.cgcc add.c div.c main.c mult.c sub.c -o cal
make | 此时会生成cal可执行文件。 |
./cal | 执行cal程序 |
但是以上规则效率太低。
修改:
cal:add.o div.o main.o mult.o sub.ogcc add.o div.o main.o mult.o sub.o -o caladd.o:add.cgcc add.c -cdiv.o:div.cgcc div.c -cmult.o:mult.cgcc mult.c -cmain.o:main.cgcc main.c -csub.o:sub.cgcc sub.c -c
自动变量:
$< | 表示依赖项中第一个依赖文件的名称。 |
$@ | 表示目标文件的名称,包含文件扩展名。 |
$^ | 依赖项中,所有不重复的依赖文件,这些文件之间以空格分开。 |
# 这是一个规则的普通写法
cal:add.o div.o main.o mult.o sub.ogcc add.o div.o main.o mult.o sub.o -o cal# 这是一个规则,用了自动变量
cal:add.o div.o main.o mult.o sub.ogcc $^ -o $@
模式匹配:
# %是一个通配符,匹配的是文件名
%.o:%.cgcc $< -c
以下代码太冗余:
cal:add.o div.o main.o mult.o sub.ogcc add.o div.o main.o mult.o sub.o -o caladd.o:add.cgcc add.c -cdiv.o:div.cgcc div.c -cmult.o:mult.cgcc mult.c -cmain.o:main.cgcc main.c -csub.o:sub.cgcc sub.c -c
修改后:
target=cal
obj=add.o div.o main.o mult.o sub.o$(target):$(obj)gcc $(obj) -o $(target)%.o:%.cgcc -c $^
函数:
一、wildcard
$(wildcard *.c ./sub/*.c) | 返回值格式:a.c b.c c.c d.c e.c f.c ./sub/aa.c ./sub/bb.c |
二、patsubst
src = a.cpp b.cpp c.cpp e.cpp | 接下来要把变量src中的所有文件名的后缀从.cpp替换为.o |
obj = $(patsubst %.cpp, %.o, $(src)) | obj 的值为: a.o b.o c.o e.o |
以下代码还可以优化:
target=cal
obj=add.o div.o main.o mult.o sub.o$(target):$(obj)gcc $(obj) -o $(target)%.o:%.cgcc -c $^
优化后:
target=cal# 搜索磁盘源文件
src=$(wildcard *.c)# 后缀的替换
obj=$(patsubst %.c, %.o, $(src))$(target):$(obj)gcc $(obj) -o $(target)%.o:%.cgcc -c $^
只有当在make后面写clean时才会执行clean
target=cal# 搜索磁盘源文件
src=$(wildcard *.c)# 后缀的替换
obj=$(patsubst %.c, %.o, $(src))$(target):$(obj)gcc $(obj) -o $(target)%.o:%.cgcc -c $^clean:rm $(obj) $(target)
make clean | 删除了.o和目标可执行文件 |
由于当目录中有了clean文件后,再执行make clean会出错,所以要把clean声明为伪目标。
修改后:
target=cal# 搜索磁盘源文件
src=$(wildcard *.c)# 后缀的替换
obj=$(patsubst %.c, %.o, $(src))$(target):$(obj)gcc $(obj) -o $(target)%.o:%.cgcc -c $^.PHONY:clean
clean:rm $(obj) $(target)
现在即使当前目录有clean文件也不影响。
make clean |
由于mkdir没有管理员权限无法执行,默认往后的所有语句都无法执行
target=cal# 搜索磁盘源文件
src=$(wildcard *.c)# 后缀的替换
obj=$(patsubst %.c, %.o, $(src))$(target):$(obj)gcc $(obj) -o $(target)%.o:%.cgcc -c $^.PHONY:clean
clean:mkdir arm $(obj) $(target)
想要rm执行要在mkdir前面加个-
target=cal# 搜索磁盘源文件
src=$(wildcard *.c)# 后缀的替换
obj=$(patsubst %.c, %.o, $(src))$(target):$(obj)gcc $(obj) -o $(target)%.o:%.cgcc -c $^.PHONY:clean
clean:-mkdir arm $(obj) $(target)
GDB
gcc main.c -g -Wall -o0 -o app | 生成一个调试的可执行文件app |
gdb app | 进入调试的命令 |
l(小写的L) | 查看代码(回车继续往下查看) |
q | 退出 |
set args 1 2 3 | 传入参数1 2 3(如果有函数参数) |
show args | 查看参数 |
run | 运行程序 |
g++ -g *.cpp -o app | 生成调试的可执行文件 |
gdb app | 进入调试的命令 |
l(小写的L) insert.cpp:19 | 查看insert.cpp第19行和上下相关内容 |
l(小写的L) insertSort | 在insert.cpp文件中找到insertSort函数 |
set list 20 | 设置显示行数为20行 |
show list | 查看显示行数 |
l(小写的L) test.cpp:main | 查看到test.cpp里面的main函数 |
b 16 | 在第16行设置断点 |
b if i==5 | 用于例如在for循环里面当i==5时停止 |
b insert.cpp:16 | 在insert.cpp中的第16行设置断点 |
i b | 查看已设置的断点 |
d 1 | 删除第1个断点 |
d 1-2 | 删除第1-2断点 |
d 3 5 | 删除3 和 5断点 |
dis 4 | 设置第4个断点无效 |
dis 6-7 | 设置6-7断点无效 |
ena 4 | 使第4断点生效 |
ena 6-7 | 使6-7断点生效 |
p i | 查看变量i |
p/d i | 以十进制查看变量i |
p/c | 以字符型查看变量i |
p/f | 以浮点数查看变量i |
ptype i | 查看变量i的类型 |
ptype array[i] | 查看array[i]的类型 |
ptype array | 查看array的类型 |
display i | 自动跟踪变量i |
display array[i] | 自动跟踪变量array[i] |
i display | 查看所有的自动跟踪 |
next | 单步调试 |
undisplay 1 | 取消跟踪编号为1的变量 |
disable display 3 | 设置编号为3的变量自动跟踪为无效 |
ena display 3 | 设置编号为3的变量自动跟踪为有效 |
单步调试:
run开始执行程序,一个函数执行的地方打了断点
step | 执行函数体内容 |
finish | 跳出函数体(里面不能有断点,不然跳不出来) |
next | 不执行这个函数体 |
until | 跳出循环体(里面不能有断点,要使它失效或删除) |
set var i=5 | 将变量i的值设为5,可用于for循环中,在for循环打断点,将i值改变 |
相关文章:

Linux-GCC、makefile、GDB
GCC gcc -E test.c -o test.i预处理(-o指定文件名) gcc -S test.i -o test.s编译gcc -c test.s -o test.o汇编gcc test.o -o test链接(生成一个可执行程序的软连接) gcc test.c -o test一条指令可以完成以上所有内容 gcc *.c -I(大写的i) include由于在main.c中找不到当前文件…...

[MySQL初阶]MySQL(7) 表的内外连接
标题:[MySQL初阶]MySQL(7)表的内外连接 水墨不写bug 文章目录 一. 内连接 (INNER JOIN)二. 外连接 (OUTER JOIN)关键区别总结 三、 如何选择 在 MySQL 中,连接(JOIN)用于根据两个或多个表之间的相关列组合行。内连接(I…...
Spring Boot中Excel处理完全指南:从基础到高级实践
Excel处理基础知识 1.1 为什么需要在应用中处理Excel文件? 在企业应用开发中,Excel文件处理是一个非常常见的需求,主要用于以下场景: 数据导入:允许用户通过Excel上传批量数据到系统 数据导出:将系统数据…...
Windows下NVM的安装与使用
本文将介绍windows下nvm相关知识。 在不同的项目中可能会使用不同版本的Node.js,例如A项目中需要node>18;B项目中需要node>20。这时候就需要使用NVM切换不同的node版本。进而可以在同一台设备上使用多个node版本。 一、NVM是什么? n…...
Ubuntu挂起和休眠
Ubuntu挂起和休眠 1. 挂起(Suspend)2. 休眠(Hibernate)3. 混合挂起(Hybrid-Sleep)注意事项图形界面操作 在 Ubuntu 系统中,挂起(Suspend)和休眠(Hibernate&am…...

【R语言编程绘图-mlbench】
mlbench库简介 mlbench是一个用于机器学习的R语言扩展包,主要用于提供经典的基准数据集和工具,常用于算法测试、教学演示或研究场景。该库包含多个知名数据集,涵盖分类、回归、聚类等任务。 包含的主要数据集 BostonHousing 波士顿房价数据…...
云服务器部署Gin+gorm 项目 demo
更多个人笔记见: (注意点击“继续”,而不是“发现新项目”) github个人笔记仓库 https://github.com/ZHLOVEYY/IT_note gitee 个人笔记仓库 https://gitee.com/harryhack/it_note 个人学习,学习过程中还会不断补充&…...
MySQL数据一致性守护者:pt-table-checksum原理与实战全解析
MySQL数据一致性守护者:pt-table-checksum原理与实战全解析 在MySQL主从复制环境中,数据一致性是DBA和运维人员最关心的问题之一。主从数据不一致可能导致业务逻辑错误、报表数据失真甚至系统故障。Percona Toolkit中的pt-table-checksum工具正是为解决这一痛点而生,它能够…...

检索器组件深入学习与使用技巧 BaseRetriever 检索器基类
1. BaseRetriever 检索器基类 在 LangChain 中,传递一段 query 并返回与这段文本相关联文档的组件被称为 检索器,并且 LangChain 为所有检索器设计了一个基类——BaseRetriever,该类继承了 RunnableSerializable,所以该类是一个 …...
Unity——QFramework工具 AciontKit时序动作执行系统
AciontKit 是一个时序动作执行系统。 游戏中,动画的播放、延时、资源的异步加载、网络请求等,这些全部都是时序任务,而 ActionKit,可以把这些任务全部整合在一起,使用统一的 API,来对他们的执行进行计划。…...

【Doris基础】Doris中的Replica详解:Replica原理、架构
目录 1 Replica基础概念 1.1 什么是Replica 1.2 Doris中的副本类型 2 Doris副本架构设计 2.1 副本分布机制 2.2 副本一致性模型 3 副本生命周期管理 3.1 副本创建流程 3.2 副本恢复机制 4 副本读写流程详解 4.1 写入流程与副本同步 4.2 查询流程与副本选择 5 副本…...

【中国·广州】第三届信号处理与智能计算国际学术会议 (SPIC2025) 即将开启
第三届信号处理与智能计算国际学术会议 (SPIC2025) 即将开启 在信息技术飞速发展的当下,信号处理与智能计算作为前沿科技领域,正深刻改变着我们的生活与产业格局。为汇聚全球顶尖智慧,推动该领域进一步突破,第三届信号处理与智能…...

Android12 Launcher3显示所有应用列表
Android12 Launcher3显示所有应用列表 1.前言: 最近在Android12Rom定制时需要显示所有桌面应用的图标,并且不能去掉抽屉,在手机上面抽屉和所有应该列表是两种不同模式,用户基可以自行选择,但是在自定义的launcher中这…...
24.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--单体转微服务--认证微服务
SP.IdentityService 项目为微服务架构中的核心认证中心,采用 OpenIddict 框架实现 OAuth2.0 和 OpenID Connect 协议,提供完整的身份认证和授权解决方案。项目集成了 ASP.NET Core Identity 框架,实现了用户管理、角色权限控制等基础功能&…...
基于React Native开发鸿蒙新闻类应用的实战开发笔记
以下为基于React Native开发鸿蒙新闻资讯类应用的实战开发笔记,结合架构特性与踩坑经验,重点记录关键实现方案和技术决策: 一、环境搭建与工程初始化(关键步骤复盘) Node.js版本锁定 必须使用Node 18&…...
[Java 基础]运算符,将盒子套起来
在 Java 中,运算符(Operator)用于执行特定的操作,例如数学计算、赋值、比较等。运算符是 Java 语言的重要组成部分,能够帮助我们高效地操作数据。 1. 算术运算符 运算符说明示例结果加法5 38-减法5 - 32*乘法5 * 31…...

智能快递地址解析接口如何用PHP调用?
一、什么是智能快递地址解析接口 随着互联网技术的普及和电子商务的迅猛发展,网购已成为现代人日常生活的重要组成部分。然而,在这个便捷的背后,一个看似不起眼却影响深远的问题正悄然浮现——用户填写的快递地址格式混乱、信息不全甚至错漏…...

华为OD机试真题——模拟消息队列(2025B卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
2025 B卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式! 2025华为OD真题目录+全流程解析/备考攻略/经验分享 华为OD机试真题《模拟消息队列》: 目录 题…...
c# 显示正在运行的线程数
在 C# 中,若想获取当前进程正在运行的线程数,可以使用 System.Diagnostics 命名空间中的 Process 类来实现。该方法适用于 Windows 平台,并能够获取当前进程的线程信息,包括线程总数和运行中的线程数量。 ✅ 方法一:使…...
MySQL 日志数据同步的详细教程
以下是 MySQL 日志数据同步的详细教程,主要介绍基于二进制日志(binlog)的主从复制和基于 GTID 的高级同步方案: 一、MySQL 二进制日志(binlog)同步基础 1. 二进制日志原理 binlog 是 MySQL 的事务性日志&am…...
2025 Java面试大全技术文章(面试题1)
数据类型与包装类 问题:Java中基本数据类型与包装类的区别是什么?自动装箱与拆箱的底层原理? 答案: 基本数据类型(如int、double)直接存储值,包装类(如Integer、Double)…...
docker 中 什么是「卷」?(Volume)
🗃️ 什么是「卷」?(Volume) 「卷」就是 Docker 里用来“保存数据”的一块空间,就像是一个外接硬盘,或者一个 USB 闪存。 容器本身是临时的,你一删它,它的数据也跟着没了。但卷是用…...
三维可视化和实时数据处理对前端性能要求以及优化渲染效率
在三维可视化(如 Three.js 场景)和实时数据处理(如每秒数百条设备状态更新)场景中,前端性能优化是确保用户体验的核心挑战。以下结合技术原理与行业实践,详细说明Web Workers和虚拟 DOM的优化机制ÿ…...

基于VU37P的高性能采集板卡
基于VU37P的高性能采集板卡是一款最大可提供20路ADC接收通道的高性能采集板卡。每路A/D通道支持1GS/s的采样率,分辨率为14bit,模拟输入带宽可达500MHz,交流耦合,输入阻抗50欧姆。 产品简介 可提供20路ADC接收通道的高性能采集板…...

2025-05-31 Python深度学习10——模型训练流程
文章目录 1 数据准备1.1 下载与预处理1.2 数据加载 2 模型构建2.1 自定义 CNN 模型2.2 GPU加速 3 训练配置3.1 损失函数3.2 优化器3.3 训练参数 4 训练循环4.1 训练模式 (model.train())4.2 评估模式 (model.eval()) 5 模型验证 本文环境: Pycharm 2025.1Python 3.1…...
卷积神经网络(CNN)、YOLO和人脸识别之间的关系
核心关系图解 TEXT 摄像头图像 → [YOLO:人脸检测] → 定位人脸位置 → [CNN:特征提取] → 人脸特征向量 → [人脸识别系统] → 身份匹配 通俗比喻 想象你在一个拥挤的火车站找人: YOLO 是你的"快速扫描眼": 一眼扫…...

K8S StatefulSet 快速开始
其实这篇文章的梗概已经写了很久了,中间我小孩出生了,从此人间多了一份牵挂。抽出一些时间去办理新生儿相关手续。初为人父确实艰辛,就像学技术一样,都需要有极大的耐心,付出很多的时间。 一、引子 1.1、独立的存储 …...
重新测试deepseek Jakarta EE 10编程能力
听说deepseek做了一个小更新,我重新测试了一下Jakarta EE 10编程能力;有点进步,遗漏的功能比以前少了。 采用Jakarta EE 10 编写员工信息表维护表,包括员工查询与搜索、员工列表、新增员工、删除员工,修改员工…...

nav2笔记-250603
合作背景: AMD与Open Navigation在过去几个月里进行了合作,旨在向ROS 2社区展示AMD强大的Ryzen AI、Embedded和Kria能力。 演示内容: 帖子提到,他们已经开始展示如何使用Ryzen AI为自主机器人产品提供动力,在各种现实世…...

指纹识别+精准化POC攻击
开发目的 解决漏洞扫描器的痛点 第一就是扫描量太大,对一个站点扫描了大量的无用 POC,浪费时间 指纹识别后还需要根据对应的指纹去进行 payload 扫描,非常的麻烦 开发思路 我们的思路分为大体分为指纹POC扫描 所以思路大概从这几个方面…...