189 8069 5689

C++/C语言深度剖析(1)-创新互联

C/C++语言其实刚学起来难度不大,学着学着就发现这也不对那也不对。碰上高手的代码,有时候都看不懂。一大堆的宏定义,一大堆的指针,一连串的继承、重载、多态覆盖。看得头昏脑胀。实在是非常痛苦。再加上如果开发MFC/ATL程序,这些程序是MS在WINAPI上的封装,通过VISUAL STUDIO工具一阵自动生成。最后你发现,C/C++在哪都不知道,你只知道某个API,某个类了。语言不见了。出现这种情况,有些人说好,说明你已经达到一个境界了。可是你自己会清楚,C/C++,这个语言,你究竟在哪?别人让你举几个C/C++基本特征,心中也说不清楚。看到C/C++语言写的代码,你也是心里似懂不懂的,有时候,心里想,何必究根呢?只要程序运行没错就行。真要程序Coredump了,再去GDB调试吧。我相信工作中的人想法80%都是这样想的。没有多少人愿意花时间去深究C/C++的内部机制的。一个因为时间不允许,工作任务紧,另一个确实来说,参考资料也很少。这里C++/C语言深度剖析,是自己的一个学习记录。那么首先从C/C++源码开始说起。

创新互联公司是创新、创意、研发型一体的综合型网站建设公司,自成立以来公司不断探索创新,始终坚持为客户提供满意周到的服务,在本地打下了良好的口碑,在过去的10年时间我们累计服务了上千家以及全国政企客户,如石牌坊等企业单位,完善的项目管理流程,严格把控项目进度与质量监控加上过硬的技术实力获得客户的一致称扬。

【1】版本和功能声明,说到这里,不得不提编程规范,也就是通常意义意上的Code specific。这里所说的编程规范,我相信几乎每家公司都有,可是一拿到代码库上的代码一看,还是乱七八糟的。这不能怪Review的人,也不能怪写Code的人。首先我们要理解,写程序和管程序的都是人。人都是弹性,不像机器,设定一个规则,就一定按照这个规则执行。人是这个世界上最奇怪的一种机器,他是不按常理出牌的。因此,要严格的要求一个人去遵守某种规则基本上是不可能的。那为什么还是每家公司都搞这些写在墙上没人看的规范,干嘛呢?也许是领导自我安慰,也许是QA部门的一种成绩。反正我理解写在纸上的规范通常都不是规范。只有落实到行动中的才是规范。那么我这里提规范干嘛呢?那我这里写这个规范是从解决自己的痛苦来说。我们通常很痛苦的就是拿到别人代码,一个目录,不知道从哪看起,不停的找main函数。找到main函数然后一个一个的找来找去,猜来猜去。显然一个清晰的目录结构对别人对自己都是一种享受。C/C++中有一个默认的命名规则就是  头文件 include目录  源码文件 src目录或者source目录。库文件 lib目录.编译后执行文件 bin目录。第二个痛苦的就是拿到一个CPP文件中,函数一大堆,不知道干嘛?那么必要的简短注释通常是非常有用的。那这里有一个问题,就是你说这注释是写在头文件中好还是源文件中好呢?这也是一个纠结的问题?两边都写就显得傻,写哪一边比较好呢?我们知道不管是SVN、git还是Clearcase它都是以文件作为管理单位的。因此,对每个文件来说,都是公司或个人的私有财产。因此,从这点来说,每个文件都需要进行版本声明、作者声明。那么功能说明从某种意义上说还是以头文件为主。通常来说头文件说明主要功能。源文件中说明实现细节。下面是一个推荐范本。

C++/C语言深度剖析(1)

这个范本实际也是比较死的。实际上有些公司是CR/SR号来标识版本修改记录的。下面是一个参考例子。

C++/C语言深度剖析(1)

【2】预处理写法。我们知道编译器在预处理过程中通常都是针对#开头的符号进行简单替换处理。这里有三个问题,我们分别解决。

1)第一个问题,就是同一个源码文件,如果包含头文件过程,出现重复。应该怎么处理。从语法上来说有时候肯定没错,当然有时候也会出现错误,因为相同的代码拷贝了两份。但是从生成文件的效率来说,肯定不好。如下所示:

file1.h 含有extern int size

file2.h 含有#include “file1.h” f

ile3.h 含有#include “file1.h”

这时如果file.c含有 #include “file2.h” 和#include “file3.h”。 这时经过预处理编译生成的file.i中就会含有两个extern int size。造成声明失败。因此,我们这可以采用如下两种解决方法:一种是使用ifndef/define/endif,

#ifndef FILE1

#define FILE1 “file1.h”

#include FILE1

#endif

另一种是使用#pragma once。这一种在VC中比较常见,但是不是所有编译器支持。它是针对单个文件在物理上只被编译一次,如果相同的文件有多份拷贝,也就是说内容相同,但文件名不一样。这种方法是行不通的。所以最好的方法还是第一种。因此,在写C++头文件时,一般在开头都要如下进行声明。

C++/C语言深度剖析(1)

2)第二问题就是include 关于系统路径头文件和当前用户定义路径搜索的写法,我们都知道其中系统路径用#include,用户路径用#include “file.h”。当然这里在编译时,我们是需要不管是GCC还VC的CL都是需要指定-I参数路径。VC是在IDE中进行配置。GCC是通过-I参数设置。但是通常我们开发时C++对标准库写法的建议是#,这又是为什么呢?我们知道C++与C不同,有几点是C完全没有的:命名空间和.hpp尾的头文件。首先讲第一点,可能最容易接受的就是可移植性,C++新标准为了不受.h的牵制,并且实际上它也不建议了。就使用不带后缀的系统库。第二点,接着前面来说,你没有后缀,那编译器到底搜索的是哪个文件呢?这一点是有点让人接受不了,但实际上标准并没有明确区分,比喻说,,前者可以肯定的是在命名空间std中,并且支持宽符,std标准组件中搜索到就不一定是iostream.h文件,并且里面的函数都是有命名空间的,也不是全局函数。可能看到这里更迷惑了。这还要从C++引入命名空间讲起。理论上讲引入命名空间导致了C++不再有绝对意义上的全局函数,也就避免了大规模开发时需要避免全局变量和全局函数同名的问题。因此,C++标准库都是建立在std命名空间范围内。但是我们知道C都是全局函数,C++是C的超集。如何兼容C的函数呢?C++使用了一个蠢办法,就是同名重写到std空间中去,比喻说iostream对应就是iostream.h。但是为了避免混淆,使用std命名空间的,就不带h。

3)第三个问题也比较重要,就是C和C++代码混合编译时,该如何处理。我相信大部分C++程序中都或多或少中含有纯C的代码,C++因为一些特性与C不完全兼容,因此,混和编译C++和C程序时时候会产生一些问题,具体什么问题呢?我们以函数来做比较,比喻函数void foo(int x,int y)在C++编译器生成时是_foo_int_int函数名,而在C中因为没有重载特性,所以生成的函数名是_foo,这时如果在编译时恰好这个函数是在C库中,那么用C++生成的这个函数就无法在链接时查到正确的C库。同理反过来也是这样,如果一段C程序使用到C++生成的函数,也会出现同样的问题,因此,处理这此问题就需要如下使用extern “C”来定义头文件。

C++/C语言深度剖析(1)

另一个问题是如果C中使用C++生成的函数,怎么使用呢?显然C中是不能使用extern “C”标识的。那么该如何处理呢?可以在C++中声明这个函数为extern “C”,但在C中使用extern来引用。

C++/C语言深度剖析(1)

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


文章题目:C++/C语言深度剖析(1)-创新互联
网页路径:http://cdxtjz.cn/article/egphd.html

其他资讯