<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="white-space:pre"> </span>Linux下的C开发,可能与win平台的C有点不太一样,但可能不太多,遇到再说吧,我们今天要说的就是GCC的使用技巧(初级的),完全菜鸟级的!!</span>
很多人的感觉,特别是离开win平台,到Linux平台写C代码的时候,熟练VIM编辑器之后,最初写代码的感觉可能是。。。。没啥不一样。或者感觉也没有传说中那么神秘,没错,我当初也是这个感觉,其实那是因为会的东西太少。。就拿GCC这个来说,有多少菜鸟用的很熟练?用熟练了,就不会用上面所说的感觉了,只会说同一个字:爽
直接上例子,具体代码不想写太多,因为我也是从别人的代码中拿来的。。。自己做一个总结而已
例如,我们写一个main方法,要实现比较两个整数的大小,分别有两个方法供调用,分别是max(int a,int b)和min(int a,int b),最初的模式,我们一般是把这几个方法写到同一个.c文件中,这个没错,但是如果我们有上千万个这种方法让你调用,你都要自己写到一个文件中?肯定不合适,最好的方法就是这么多的方法,是来自各个不同人写的,放在不同的文件中,可能是一个方法一个文件,这样单列的,那么我们怎样才能通过gcc调用这些方法呢?
例如,有min.c,max.c和一个主方法文件hello.c 首先。。 gcc -c max.c gcc -c min.c 或者:gcc -c max.c min.c 没有错误的话,会产生: max.o,min.o这两个文件 然后: gcc max.o min.o hello.c -o hello.out 产生hello.out文件(没错误的前提下) 最后:./hello.out 输出结果
把这个情景脑补成有几万个方法文件。。。光编译也会烦死,弄不好出错了,再重来。。。那么问题来了,怎么办?那就是make工具,这个工具很强大,强大到我只会用一部分功能,还没有达到哪里不爽改哪里的境界。。好吧,怎么用呢?那就是先定义规则,再make,规则在哪里定义?在Makefile文件中,怎么写规则呢?
很简单,目标:依赖,下一行TAB缩进之后加命令
#this is makefile hello.out:max.o min.o hello.c <TAB>gcc max.o min.o hello.c -o hello.out max.o:max.c <TAB>gcc -c max.c min.o:min.c <TAB>gcc -c min.c
这就是Makefile文件的内容,然后我们直接shell中执行make命令即可,就可以按照这个规则执行了,那么在第三行中,可能有个问题,就是如果还是有几万个文件让你写上去,岂不是很麻烦?当然有简单的办法。。。Linux就是为懒人设计的。。。改成
#this is makefile hello.out:max.o min.o hello.c <TAB>gcc $^ -o [email protected] max.o:max.c <TAB>gcc -c max.c min.o:min.c <TAB>gcc -c min.c
注意到变化了吗?$^表示所有依赖,就是指的各种.o文件,[email protected]就是指的目标文件,就那么一个,就是上面的hello.out,最会也是make执行即可,这里的好处是简化了用户输入的复杂性,还有个好处,就是每次更改一个文件的时候,只要.o文件存在,就不会重复编译,从而提高了效率。
顺便提一下Linux的管道,我们知道Linux的IPC(进程间通信)机制主要有:信号,管道,IO重定向,share内存和套接字等,我们经常使用的就是管道和IO重定向,管道就是“|”,这个竖杠就是管道,重定向就是“>,<,>>,<<”这些符号,“>”和">>"的区别是,一个是覆盖的,另一个是追加到文件后面的,还是说管道,我们写程序的时候,会碰到一种情况,就是上一个函数的输出就是下个函数的输入,这种情况如果还要重新编程的话,时间效率不高,管道就提供了个很好的方法,但是一定要注意输入和输出啊,起码要保证类型和数量是一致的才能用,例如,一个avg方法统计平均数(需要输入总和与个数),一个sum方法会根据输入统计出总和和个数,但是这两个方法是来自两个不同文件的,也就是说最后产生的可执行文件是:avg.out和sum.out(也可以自己定义其他名字,这里只是举例说明),我们想要把sum中的输出直接放到avg的输入中,怎么办?管道来办,具体方法是命令行输入:./sum.out
| ./avg.out,ok执行(这俩文件要放到一个目录里。),就这么简单。。想当初我也不会。。。我傻傻的人工输入。。。后来聪明了,写了个脚本,采集输出然后按照格式解析出来,再传到目标函数中,尼玛都是不会用管道惹的祸。
后面还要实践gdb和ddd等工具的使用,慢慢学吧,一起加油。