一:C语言中的顺序结构
1:最浅显的顺序结构理解:三种结构之一
(1)代码执行的时候没有遇到判断跳转或者循环,默认是顺序执行的。执行完上一句则开始执行下一句。
(2)顺序结构说明cpu的工作状态,就是以时间轴来顺序执行所有的代码语句直到停止。
2:选择和循环结构的内部的顺序结构
(1)譬如if()在 {}内部是if的代码段,在代码段内部还是按照顺序结构来执行的
(2)switch case内部也是一样,也是按照顺序结构来执行的
(3)while for 内部也是按照顺序结构来执行的
3:编译过程中的顺序结构
(1)一个c程序有多个.c文件组成,编译的时候多个.c文件是独立分开编译的。每个c文件编译的时候,编译器是按照从前到后的顺序逐行进行编译的。
(2)编译器编程时的顺序编译会导致函数/变量必须先定义/声明才能够被调用,这也是C语言中函数/变量声明的来源
(3)链接过程中:链接过程连接器实际上是按照链接脚本指导下完成的。所以链接时的.o文件的顺序是由链接脚本指定的。如果链接脚本中明确指定了顺序则会 优先考虑这个规则按照这个指定的顺序排布,如果链接脚本中没有指定具体的顺序则链接器会自动的排布
4:思考:为什么本质上都是顺序结构
(1)顺序结构本质上符合cpu的设计原理,cpu是人设计的,cpu也就符合人的思考原理
二:程序调试的debug宏
1:程序调试的常见方案:单步调试、打印信息、log文件
(1)利用调试器进行单步调试(譬如IDE中,jlink)适用于新手,最大的好处就是直观,能够帮助找到问题。缺点就是限制大速度慢
(2)裸机使用LED、蜂鸣器等硬件测试,适合单片机裸机程序
(3)printf函数打印调试,比较常用,作为程序员必须学会使用打印信息调试。好处是具备普遍性,几乎在所以情况下都能使用。
(4)log文件(日志文件)是系统运行过程中在特定时候会打印一些调试信息,日志文件记录下来这些调试信息以供后续查找问题。适合于系统级或者大型程序的调试
2:打印信息不能太多也不能太少
(1)调试信息太少会找不到问题所在
(2)调试信息太多会有大量无用的信息淹没有用的信息,导致有用的信息无法被看见,等于没有
3:调试(DEBUG)版本和发行(RELEASE)版本的区别
(1)DEBUG版本就是包含了调试信息的版本,在程序测试中会发布debug版本,这种版本的程序运行时会打印出来调试信息/log文件,这些信息可以辅助测试人员判断程序的问题所在
(2)DEBUG版本的坏处是占用了系统的资源,拖慢了系统运行速度。因此DEBUG版本性能低于RELEASE版本
(3)RELEASE版本就是最终的发布版本,相较于DEBUG版本的功能代码是一样的,但是去掉了所有的调试信息。适合最终 测试通过要发布的程序,因为去掉了调试信息所以程序的运行效率更高
(4)DEBUG和RELEASE其实是一套源代码。源代码中其实是有很多打印调试信息的语句的,程序员是通过宏来完成条件编译的
4:debug宏的实现原理
(1)DEBUG的大概原理是:
#ifdef DEBUG
#define dbg() printf()
#else
#define dbg()
#endif
(2)工作方式是 :如果需要输出DEBUG版本则在条件编译之前加上 #define DEBUG即可,这样程序中的调试语句dbg就会被替换成printf从而输出;如果要输出RELEASE版本则去掉#define DEBUG,则dbg() 就会被替换成空,则程序中所有的dbg()语句就蒸发了,这样的程序编译就会生成没有任何调试信息的代码
5:debug宏的使用方法
//示例程序代码
#include <stdio.h>
#define DEBUG
#ifdef DEBUG
#define DBG(...) fprintf(stderr," DBG(%s,%s(),%d): ",_FILE_,_FUNCTION_,LINE_);
fprintf(stderr, _VA_ARGS__)
#else
#define DBG(...)
#endif
int main(void)
{
DBG("tiaoshi.\n");
return 0;
}
有定义#define DEBUG程序运行结果:
无定义#define DEBUG程序运行结果: 无调试信息输出
6:分析几个debug宏
(1)应用程序中的DEBUG宏
#ifdef DEBUG
#define DBG(...) fprintf(stderr," DBG(%s,%s(),%d): ",_FILE_,_FUNCTION_,LINE_);
fprintf(stderr, _VA_ARGS__)
#else
#define DBG(...)
#endif
注:_FILE_ 是C语言中的预定义宏,是C语言自己定义的这些宏具有特殊含义,譬如_FILE_就代表当前正在编译的c源文件名
(2)内核中的debug
#ifdef DEBUG_S3C_MEM
#define DEBUG(fmt, args...) printk(fmt, ##args)
#else
#define DEBUG(fmt, args...) do {} while (0)
#endif