gcc想必大家都听过吧,gcc是一个编译器,进行C语言编译的编译器
但是有的时候代码会发现编不过,有可能是因为标准太低,不支持某些写法
这个时候就可以
gcc test.c -std=c99
有个选项是-o,这样可以给它重命名:
gcc test.c -o newfilename
C++中文件的后缀一般有三种:.c,.cpp(c++特有),.cc(c++特有)
gcc不能用来编译C++代码(gcc不认识C嘎嘎的某些流),c嘎嘎在编译的时候就用g++啦
g++ test.cc -std=c++11
还有一种后缀是cxx
查看g++版本:
g++ --version
没有g++就安装一下g++:
yum install -y gcc-c++
预处理阶段完成操作:宏替换,去注释,头文件展开,条件编译
gcc -E test.c -o test.i
形成临时文件不生成可执行程序
-E:从现在开始进行程序的编译,预处理完成就停下
打开看看
多出来的来自
预处理之后头文件就没用叻
ls /usr/include/
vim /usr/include/stdio.h
分屏瞅瞅
vs test.i //底行模式
我们知道有很多软件(比如VS比如Xshell)有很多版本,社区版,企业版,专业版...在企业版或者专业版中往往有更多的功能,但需要收费
那在公司里维护代码需要维护几份呢?
首先从维护代码的成本来分析:当需要维护两份代码时,将bug解决需要实时同步,且测试两次,成本过高,所以一般只需维护一份代码即可
可是怎么维护一份代码呢?
条件编译可以对代码实现动态裁剪
看我的代码:
- #include
- int main()
- {
- #ifdef v1
- printf("功能1\n");
- #elif v2
- printf("功能1\n");
- printf("功能2\n");
- #else
- printf("功能1\n");
- printf("功能2\n");
- printf("功能3\n");
- printf("功能4\n");
- printf("功能5\n");
- #endif
- return 0;
- }
维护一份代码,实施动态裁剪,这就是条件编译
- #include
- #define v2 1
- int main()
- {
- #ifdef v1
- printf("功能1\n");
- #elif v2
- printf("功能1\n");
- printf("功能2\n");
- #else
- printf("功能1\n");
- printf("功能2\n");
- printf("功能3\n");
- printf("功能4\n");
- printf("功能5\n");
- #endif
- return 0;
- }
命令行式宏定义:
gcc -Dv1=1 proj.c
使用命令行式宏定义能更方便的进行代码裁剪 ,gcc能裁剪代码哦(去注释,宏定义这些)
-S:从现在开始进行程序的编译,编译结束就停下
编译的工作是做语法检查,将C变成汇编语言
gcc -S test.i -o test.s
从现在开始进行程序的翻译,汇编完成就停下来
汇编过程的工作是汇编语言编译成为二进制目标文件(.obj)
gcc -c test.s -o test.o
(文件后缀是.obj,可重定位目标文件,还不是可执行程序)
它不可执行:
不是权限的问题,它就算加上权限本身也不可执行 :
文件可以被执行,即要有可执行权限,也要文件本身是可执行文件
链接形成可执行程序(程序和库结合的过程)
gcc test.o -o my.exe
是不是很连贯:看看ESc(令人震惊的巧合)
后缀:iso(学ios的有福啦,我所以)
有个问题:为什么要搞这么复杂?
听个故事:
过去在没有C的时候,大部分人用的都是二进制编程,当时是用那种打孔纸带(参见叶文洁,没看过三体的看一眼,,,)
能透过去的就是1,透不过去的就是0
二进制编程使用01序列识别
但是这个确实是麻烦,于是人们就设计出了汇编语言(里面的符号叫助记符,从汇编开始有编译器的哦)
再后面就是C语言,支持各种语法(宏定义啦,注释啦,,,)
语言发展要有编译器,编译器非常不好写,介于语言发展的过程趋势,显然发明汇编语言转C的编译器更简单可行(你总能从二进制开始搓C吧,你站在巨人的肩膀上)
编译就是在回溯历史,这样效率更高啊
混沌初开,到底先有语言还是先有编译器
那肯定先有语言啊,有语言才有给这门语言写编译器的冲动(怒发冲冠为语言)
在语言发展到汇编阶段的时候,汇编的编译器是用二进制写出来的(只有二进制编程方案)
然后还有个事:编译器是软件吗?
肯定是啊,既然是软件,那就需要维护,将我们写出的汇编代码交给用二进制编写的汇编编译器,由编译器帮助我们生成可执行程序,但是由于二进制写的编译器太挫了(维护起来效果好差),所以可以用汇编语言写一个新的编译器,这样就站在前人的肩膀上形成了新的编译器(这个更新迭代的过程叫做编译器的自举:自己编排自己)
至于链接本质上是程序和库结合的过程,当语言被发明时,一方面要有自己的语法,再一方面语言需要有自己的标准库(C88,C89,C99...)链接的时候是在调用,库里实现了很多东西
这样可以查看链接的动态库:
ldd my.exe
系统下的一个二进制库承装了很多方法:
ls /lib64/libc.so.6 -l
库真正的名字是去掉前缀,去掉尾
所以这个库的真实名字(掐头去尾)是:C
这里的libc-2.17.so被称为C标准库(一个超大公共图书馆)
安装开发环境需要安装编译器、C标准库、C头文件
在Linux库中,大致分为两种:
1.动态库:.so
2.静态库:.a
Windows也有动静态库之分:
1.动态库:.dll
2.静态库:.lib
报错可能是库被误删了
在链接时,存在两种链接方式:动态链接、静态链接
还是一个小故事:想必网吧大家都听过,在以前其实还有一个东西叫话吧(搞很多座机在那里)
墨墨酱是一名中学生,现就读于逆天寒中学(市里最好的一所中学),墨墨酱以市第一的成绩考入了逆天寒中学(也有很多墨墨酱的初中同学也考去了那里),墨墨酱没什么别的爱好,就是喜欢上网(爱启动steam的小姐姐一枚吖~)但是悲从中来,逆天寒中学实施封闭化管理,不允许学生带手机电脑肯定也不行啦,除非有特殊情况(比如你爹是校长之类的),墨墨酱很苦恼,墨墨酱去问高三老油条学长:学长学长,学校不让带电脑不让带手机,我想上网怎么办,学长如是说:你别害怕,学校一千多号人呢,学校不让你上网,那这附近还没个小网吧了?!你从东门出,向北走,就能看到有家小蚂蚁网吧,去那整几个小时,买不了吃亏,买不了上当,学长还和墨墨酱说,虽然咱们学校封闭式管理,但是每周日会允许你出去采购,墨墨酱开心的上起了学
在老师分配完宿舍,上了几天b课,终于来到了愉快的周末,但是周末有作业不快乐,墨墨酱不想赶ddl,于是墨墨酱开始规划(现实中的墨墨酱也是j人小女孩一枚呀)她计划早晨八点起,吃完早饭把语文作文一写,把物理大题一做,把数学那小题证明一下,十二点次幻,次完幻去睡会觉,两点半起来去上网,然后五点回,把化学方程式一搞,生物知识点一背,墨墨酱甚至规划出了一份待办清单(一想到能打游戏就开心的墨墨酱)于是墨墨酱撸起袖子加油干,世界人民都点赞,开始翻身下床实施她的计划,做完了一系列事情,墨墨酱直奔网吧,跟网吧老板说,给我开个靠窗机子,机子开好了,墨墨酱愉快的走向了她的⑨号机子开始欢乐steam,美好的时光总是过的匆匆,墨墨酱打完游戏回去洗洗睡感觉恍如隔世,随着墨墨酱的成长,认识的朋友也越来越多,于是开始组队排位,哦~我的朋友~原来你也在这里~
在这个故事里,学长起到一个编译器的作用,逆天寒中学相当于内存,学长告诉墨墨酱网吧地址(目标库地址)是在帮助她找寻目标库,这个过程被称作动态链接,小蚂蚁网吧相当于动态库,⑨号机子相当于库中特定的方法(printf、scanf、malloc...),墨墨酱写出来的清单相当于代码,墨墨酱去网吧打游戏相当于跳转到相应库执行,这整体的过程就是在动态运行,动态链接的过程在编译时就已经做了(学长告诉墨墨酱网吧地址)
故事仍在继续,盛唐绮梦,不负相逢
不止有墨墨酱在上学,所有学校里如墨墨酱一般的少年都去一家网吧开机子,但毕竟林子大了什么鸟都有,墨墨酱的班长很看不惯墨墨酱的这种行为,认为这是违规违纪,自己不好好学习还要拉上别人(你给我放尊重点,老墨可是市状元!!!),行吧,班长要举报墨墨酱了,他向附近的一个派出所举报墨墨酱,于是警察叔叔就出动了,前去小蚂蚁网吧核实情况,他们问网吧老板:你有营业执照吗?
老板一脸懵逼:营业执照是嘛玩意
民警看老板这个样子,就和老板说,接到民众举报,我们要对你的店实行管控,最后的结果就是网吧被查封叻,过了一段时间,老板通过走关系把自己的设备保留了下来,没多大损失,最终给网吧老板的结果就是:资产可以还,但是不准在逆天寒中学旁边开了(苦了孩子们,最惨的是嗷嗷待哺的人民群众)这个过程叫做动态链接共享动态库,但是一旦动态库缺失,所有的动态链接这个库的程序都无法执行了(动态链接很依赖共享动态库)
乏味的一学期过去了,墨墨酱向家人讲述了这件悲伤的事情,由于墨墨酱是市状元,学习嘎嘎棒,所以在墨墨酱爹地和学校校长有着一定关系的基础上,墨墨酱居然成功在宿舍get电脑一台(甚至是墨墨酱爹地从上一家老板那购入的墨墨酱最喜欢的⑨号机),可以,墨墨酱舍友要羡慕死了,建议给墨墨酱顺便安排个单间+上床下桌羡慕死他们(什么爽文女主剧本),后来逆天寒中学旁边又开了一家小猫猫网吧,可墨墨酱再也不去了,在小猫猫网吧开起来之后,宿舍人手一台机子勒(都说服了自己家长,机子是从网吧扛过来的,九九成稀罕物)由于人手一机,网吧就不再被需要勒,每个人把电脑拷贝到自己的可执行程序的过程叫做静态链接(笑死我了,网吧老板爆改卖电脑的,在这里,网吧老板起到一个静态库的作用)
在编译的时候,将库中的方法拷贝到自己的可执行程序中的过程叫做静态链接(不再关心任何库)
这个命令也可以帮助我们查询:
file my.exe
这是在动态链接使用共享库:
动态库优缺点
1.不能丢失
2.节省资源(静态链接重复率很高)
静态库优缺点
1.一旦形成,和库无关
2.浪费资源
在Linux上,一般静态库是默认没有安装的
安装静态库:
yum install -y glibc-static libstdc++-static
静态链接应用场景:把需要的库拷贝到可执行程序(不依赖库),具有跨平台性