目录
缓冲区
倒计时程序
对出现swp文件报错的补充:
进度条程序
将tab键设置为四个空格
调试器-gdb
对比测试
实际应用
缓冲区
前言:\n会产生换行和回车两个动作:
- 回车:回到下一行行首
- 换行:移动到当前所在位置的下一行的对应位置
只想回车用\r,回车+换行用\r\n,\r和\n结合时\n只起换行作用
问题一:程序先执行printf后执行sleep,但是在执行完printf后并不会打印该字符串而是休眠3秒后才会在屏幕上打印字符串,那么sleep期间printf打印的字符串在哪里?
答:缓冲区,缓冲区是内存空间中的一块区域,在执行printf函数时,里面的字符串会被放入缓冲区中,这些存放在缓冲区中的数据在经历一次“刷新”后就可以在显示屏上显示了(程序结束时以及缓冲区满了时都会“刷新”缓冲区)
强制刷新的两种方式:
- 如果不想等到程序结束时“刷新”缓冲区,可以用\n,此时包含\n在内的缓冲区中的字符串都会被“刷新”显示在显示屏上(如果是hello bit \n hello world...,那么hello bit会直接显示在显示屏上,后面的hello world在经历三秒休息后才会显示)
- 在程序执行时,c语言提供了三个标准输入输出流extern FILE *stdin(标准输入流) / * stdout(标准输出流)/ *stderr(标准错误流)(显示器键盘等设备都被视为文件),所以可以利用强制“刷新”缓冲区指令fflush(stdout)将之前缓冲区中的内容直接输出(hello... fflush(stdout)后直接将字符串打印后等待三秒后文件结束)
补充内容:查看当前用户下的进程指令是ps -u,杀死进程的指令是kill PID
倒计时程序
原理:大量静态画面在高速运动中看起来就像是动态的
以下代码执行的结果是:什么都显示不出来,然后等待十秒程序结束
原因:%d\r在缓冲区写一个字符就将光标回到最左侧,一直覆盖
改良写法:
对出现swp文件报错的补充:
kill进程仍显示同样的错误可以进入该目录下“/home/yyf/.local/share/nvim/swap/”,删除该路径下的文件,然后返回所有原目录就再次编写该文件而不报错:
进度条程序
基础版本:为添加实际应用场景
- sleep的单位是:秒
- usleep的单位是: 微秒
- 1,000,000 微秒 = 1秒
进阶版本:下载文件时的下载进度
Processbar.h文件:
Processbar.c文件:
makefile文件:
main.c文件:
最终效果:
将tab键设置为四个空格
指令:cd(进入主目录)+ vim .vimrc(进入vim的配置文件)
操作:将文件中的2改为4
调试器-gdb
基本概念:程序有两种发布方式:debug模式(调试)和release模式(发布前测试),Linux 编译出的程序,默认是release模式(不可被调试),要使用gdb进行调试,在gcc / g++后加-g
makefile文件:
myprocess.c文件:
对比测试
问题:debug模式下可以调试是因为编译器形成可执行程序时会给可执行程序添加调试信息吗?
解决问题需要的结果:debug后生成的可执行程序比release模式后生成的可执行程序多了些内容
结论1:release模式的8848<debug模式的9704,所以debug模式下的可执行程序增加了一些信息
结论2:这些新增的信息的确是调试信息
与调试相关的信息(如符号表等)会被存储在专门的节中,并且往往以
.debug
开头
结论3:故给用户的是release版本,否则debug版本用户不仅不能调试还会多一些没用的调试信息
实际应用
(精确位置)进入gdb指令:gdb debug版本下的可执行程序名
(精确位置)退出gdb指令:quit 或 q
(精确位置)查看指定文件的某个函数或某行:list / l 文件名:函数名/行号(l 行号/函数名 也可)
(精确位置)直接运行程序指令:r(类似于f5)
(精确位置)对指定文件打断点指令:b 文件名:函数名/行号(b 行号/函数名 也可)
(精确位置)显示断点信息指令:info b(i b也可)
(精确位置)删除断点指令:d 断点编号
(精确位置)打开或关闭断点指令:enable / disable 断点编号
(精确位置)逐过程调试指令(前提要运行文件r):next / n(F10),
(精确位置)逐语句调试指令(前提是要运行文件r):step / s(F11)
(精确位置)查看变量的内容和地址指令:p 变量名 / &变量名
(精确位置)常显示变量的内容和地址指令:display 变量名 / &变量名
(精确位置)删除常显示指令: undisplay 常显示编号
(范围定位)运行至下一个断点处指令(便于确定问题所在范围):continue / c
(范围定位)当前函数运行后就停下指令(查看问题是否是出在当前函数中):finish
(范围定位)跳转至指定行(之前的所有代码都以运行)指令:until 行号
查看当前栈帧局部变量的值指令:local 变量名
修改变量的值(检查判断条件为什么不执行)指令:set var 变量 = 值
查看函数调用指令:bt
运用时结合vs中的调式可以加深理解
注意事项:
1、gdb默认记录上一次指令信息,即上一次要求打印文件首行(gdb默认打印十行)再次执行gdb(回车)可以继续打印下十行
2、gdb会显示指定部分的上下文
3、一次只能打一个断点,不能连续打多个
4、断点编号的本质是不断增长的计数器,删除断点编号为1的断点后新增断点的编号为2不为1
5、为空行打断点没效果
~over~