linux下的c编程
vi编译器简介
vi的三种模式,分别为命令行模式,插入模式以及底行模式,这里游客去看,这里提供好几个小技巧:G表示移动到文件末尾nG表示移动到第几行
gcc优化选项
gcc可以对代码进行优化,他可以通过编译选项“-On”来控制优化代码的生成,其实你是一个代表优化级别的整数,对于不同的版本的gcc来讲,n的取值范围以及对应的优化效果可能并不完全相同,比较典型的是从0到2或者3
不同的优化级别对应不同的优化处理工作,如使用优化选项-O 主要进行线程跳转和延迟退栈,使用优化选项-O2除了完成所有的-O1级别的优化之外,同时还进行一些额外的调整工作,比如优化处理器指令调度,选项“-O3”则还包括循环展开和其他一些与处理器相关的优化工作
虽然优化选项可以加速代码的运行速度,但是,对于调试而言将会是一个很大的挑战,因为代码在进行优化之后,原先在源程序中声明和使用的变量很有可能不在使用,控制流也可能突然跳转到意外的地方,循环语句也有可能因为循环的展开而变得到处都有,所有的这些优化对调试来讲都将是一场噩梦,所以笔者建议在调试的时候最好不适用任何优化选项,只有当程序在最终发行时才考虑对其进行优化
在gdb中的命令都可以使用缩略形式的命令《保存退出前使用gcc编译要加上 -g这个参数》
l 代表list
b 代表breakpoint
p代表print
设置断点 b 6 //在第六行设置断点,查看断点 info b
程序调试的大致7步
1:查看文件 (l)2:设置断点(b)3:查看断点情况(info b)4:运行代码(r)5:查看变量的值 (p 变量)
6:单步运行(n 和s)7:恢复程序运行(c)
小技巧1:在设置完断点之后,运行程序,当程序运行到断点处时用户可以键入backrace ,或者是(bt)可以查找到调用函数(堆栈)的情况,这个功能在程序调试之中使用非常广泛,经常用于排除错误或者监视调用堆栈的情况
小技巧2:gdb在显示变量时都会在对应值之前加上“$N”标记,他是当前变量值得应用标记,所以以后若想再次引用此变量就可以直接写作“$N",而无需写冗长的变量名
小知识:在gdb中,程序的运行状态有 运行 暂停 和停止 其中 暂停 状态为程序遇到断点或者观察点之类的,函数暂时停止运行,此时函数的地址,函数参数,函数内的局部变量都会被压入“栈”中。故在这种状态下可以查看函数的变量值等各种属性,但是函数处于停止状态之后,栈就会自动撤销,他就无法查看各种信息了。
make 工程管理器
所谓工程管理器,顾名思义,是用于管理较多的文件,读者可以试想一下,有成百上千个文件构成的项目,如果其中只有一个或者少数几个文件进行了修改,按照之前所学的gcc编译工具,就不得不把这些文件重新编译一遍,因为编译器并不知道那些文件是最近更新的,而只知道需要包含这些文件才能把源代码编译成可执行文件,于是,程序员就不得不重新输入数目如此庞大的文件名已完成最后的编译工作
编译过程分为编译 汇编 连接阶段,其中编译阶段仅仅是检查语法错误以及函数与变量是否被正确的声明了,在链接阶段这主要是完成函数链接和全局变量的链接,因此,那些没有改动的源代码根本不需要重新编译,而只是要把他们重新链接进去就可以了,所以,人们就希望有一个工程管理器能够自动的识别更新了的文件代码,而不需要重复输入冗长的命令行,这样make工程管理器就用运而生了
实际上,make 工程管理器也是个 自动编译管理器 这里的自动是指他能够 根据文件时间戳自动发现更新过的文件而减少编译的工作量,同时 他通过读入makefile 文件的内容来执行大量的编译工作,用户只需要编写一次简单的编译语句就可以了,他大大提高了实际项目的工作效率,而几乎所有linux下的项目编程均会涉及它
makefile基本结构
makefile是make读入的唯一配置文件,因此要讲一下makefile的编写规则,在一个makefile文件中通常包括如下内容:
1:需要由make 工具创建的目标体,通常是目标文件或者是可执行文件
2:要创建目标体所依赖的文件
3:创建每个目标体需要运行的命令,这一行必须以制表符(tab键开头)
他的格式为
target:denpdency_files
command: /*该行必须以tab键开头*/
例如:有两个文件分别为hello.c和hello.h ,创建的目标体为hello.c,执行的命令为gcc编译指令 gcc -c hello.c,那么对应的makefile就可以写为:
hello.o:hello.c hello.h
gcc -c hello.c -o hello.o
接下来就可以只用make了,使用make的格式为make target 这样make就会自动读入
makefile,并执行target中的command 语句,并未找到相应的依赖文件
makefile变量
上面示例的makefile在实际中是几乎不存在的,因为他过于简单,仅仅包含两个文件和一个命令,在这种情况完全不需要写makefile,而只需在shell中直接输入即可,在实际中使用的makefile往往是包含很多的文件和命令的,这也是makefile出现的原因
下面是一个例子
这个makefile中有3个目标体(target),分别是david kang.o yu.o 其中第一个目标体的依赖文件就是后面两个目标体,如果用户使用命令make david ,则make管理器就是找到david目标体开始执行。这时make会自动检查相关文件的时间戳,首先,在检查kang.o,yul.o和david 3 个文件的时间戳之前,他会向下查找那些把kang.o或yul.o作为目标文件的时间戳,比如kang.o依赖文件为kang.c kang.h head.h 如果这些文件中任何一个的时间戳比kang.o新,则命令gcc -Wall -O -g -c kang.c -o kang.o就会执行,从而更新kang.o,在更新完kang.o或yul.o之后,make会检查最初的kang.o yul.o和david 3个文件,只要文件kang.o或者yul.o中的至少有一个文件的时间戳比david新,则第二行命令就会被执行,这样,make就完成了自动检查时间戳的工作,开始执行编译工作,这也是make工作的基本流程
为了进一步简化编辑和维护makefile ,make允许在makefile中创建和使用变量,变量是在makefile中定义的名字,用来代替一个文本字符串,该文本字符串成为该变量的值,在具体要求下,这些值可以代替目标体,依赖文件,命令以及makefile文件中的其他部分
makefile中的变量的定义有两种,一种是递归展开方式,另一种是简单方式,
递归展开方式定义的变量是在引用该变量是进行替换,即如果该变量包含了对其他变量的引用,则在引用变量时一次性将内嵌的变量全部展开,虽然这种类型的变量能够很好地完成用户的指令,但是他也有严重的缺点,如 不能在变量后追加内容(因为语句:CRLAGS = $(CFLAGS) -O 在变量扩展过程中可能袋子无穷循环
为了避免上述问题,简单扩展型变量的值在定义处展开,并且只展开一次,因此他不包含任何变来那个对其他变量的引用,从而消除变量的嵌套引用。
递归展开方式的定义格式为:VAR = var
简单扩展方式的定义格式为:VAR:=var
make中的变量均使用的格式为:$(VAR) //注意变量名是大小写敏感的,例如变量名foo FOO Foo代表不同的变量,推荐在makefile内部使用小写字母作为变量名,预留大写字母作为控制隐含规则参数或用户重载命令选项参数的变量名
下面给出了上例中用变量替换修改的makefile 这里用OBJS 代替kang.o和yul.o 用CC代替gcc 用CRLAGS 代替-Wall -O -g 这样在以后修改时,就可以只修改变量定义,而不需要修改下面的定义实体,从而大大简化了makefile的维护工作量
下文待续~~~
版权所有,转载请标明链接地址http://www.cnblogs.com/fengdashen