随笔分类 -  C/C++

1
摘要:资料 偶然发现了google的测试框架gtest,马上试了下,效果挺不错,特别是对于写c++的人来说,方便很多。以前自己写c++的模块,通常是写好了模块后再另外定义些函数,然后在函数里面写测试用例来测试模块,如果测试点比较多,光是定义测试函数都要花费不少时间。gtest相当于大大节省了这个过程,用起 阅读全文
posted @ 2017-02-23 20:01 在于思考 阅读(2059) 评论(0) 推荐(1) 编辑
摘要:虽然python开发效率很高,但作为脚本语言,其性能不高,所以为了兼顾开发效率和性能,通常把性能要求高的模块用c或c++来实现或者在c或c++中运行python脚本来处理逻辑,前者通常是python中一些模块的实现方式,后者服务端程序(实现业务扩展或是Plugin功能)和游戏开发(脚本只处理逻辑)中 阅读全文
posted @ 2016-04-15 19:51 在于思考 阅读(30789) 评论(1) 推荐(3) 编辑
摘要:1.前言 在前一篇文章自己实现简单的string类中提到在实现+操作符重载函数时,为了防止返回时生成的临时对象调用拷贝构造函数动态申请内存空间,使用了一个叫move的函数,它是C++0x新增的特性。既然是C++0x新增的特性,那么在以前没有这个特性的情况下,对于临时对象动态申请内存空间的问题是不是可 阅读全文
posted @ 2013-08-05 16:37 在于思考 阅读(3240) 评论(0) 推荐(0) 编辑
摘要:1.前言 最近看了下《C++Primer》,觉得受益匪浅。不过纸上得来终觉浅,觉知此事须躬行。今天看了类类型,书中简单实现了String类,自己以前也学过C++,不过说来惭愧,以前都是用C来写程序,学的C++基本都忘记了,也说明自己以前对C++的理解不够深入。基于这些,觉得有必要动手来写写C++的一 阅读全文
posted @ 2013-08-02 20:23 在于思考 阅读(5337) 评论(2) 推荐(1) 编辑
摘要:一、静态库与动态库的区别 目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库”)。 静态库是一个或者多个obj文件的打包,所以有人干脆把从obj文件生成 阅读全文
posted @ 2013-08-01 16:01 在于思考 阅读(4284) 评论(0) 推荐(0) 编辑
摘要:图像编码题目描述: 有这样一副图,它有黑白像素,黑像素的坐标在1~10之间。有很多种方法来编码这个图。例如下面的图:一种表示方法是只描述黑像素,并按x坐标的增序描述,如果x相同,则按y的增序描述,每个像素占一行。按这种编码方式的到的上面图像的编码为:62 32 43 33 44 24 3另一种表示方法是第一行包含最左边的黑像素的坐标,然后下一行是第一个黑像素的相邻黑像素,再下一行是第一个黑像素的第一个相邻黑像素的相邻黑像素(有点绕口,其实就是按bfs的方向描述),再下一行是第一个黑像素的第二个相邻黑像素的相邻黑像素,依次类推,直到描述完所有的黑像素。相邻像素的描述从右边开始,按逆时针方向,分. 阅读全文
posted @ 2013-06-30 18:33 在于思考 阅读(664) 评论(0) 推荐(0) 编辑
摘要:在编写简单的c运行库(二)中主要实现了对有关文件操作函数的实现,接下来主要实现有关字符串的函数,如itoa,strcmp,strcpy,strlen函数,这些函数并没有用到系统调用,所以也就不用向实现文件操作的函数那样使用内嵌汇编,这些函数的定义都放在string.h中。实现了字符串函数之后,就大概实现了一个小型的c运行库,虽然很简略,但对于理解c库函数运行原理、所用的关键技术有了比较深刻的认识。最后用这个小的c运行库来编译运行一个简单的测试程序,用以测试我们的库能否正常的工作。1 字符串函数 字符串函数中主要是实现itoa函数有点难度,其它的都还比较的简单,所以这里主要讲下itoa函数... 阅读全文
posted @ 2013-06-07 22:19 在于思考 阅读(1441) 评论(0) 推荐(2) 编辑
摘要:在前面编写简单的c运行库(一)中主要实现了调用main函数前的初始化、获取参数和环境变量、退出程序等工作。接下来我们真正实现c标准库中的一些函数(主要是文件操作、字符串操作函数)。不过我们对这些函数的实现力争简单,对于效率方面考虑的不是很多,因为目的主要还是学习神秘的库是怎么实现的。1 文件操作 c中的标准I/O库都是带有缓存的,我们在这里为了实现的简单,将缓存省略了,直接包装了有关文件操作的系统调用。现在我们直接看文件打开的函数: 1 static int open(const char *pathname, int flags, int mode) 2 { 3 int ret... 阅读全文
posted @ 2013-06-07 08:56 在于思考 阅读(1394) 评论(0) 推荐(0) 编辑
摘要:看了《程序员自我修养》这本书后,对目标文件、可执行文件的结构有了比较清晰的了解,对目标文件链接成可执行文件的过程和程序运行库有了大致的认识。不过正如“纸上得来终觉浅,绝知此事需恭行”,很多东西看似容易,但实践的时候却往往不是这样,在实践中往往能发现很多的问题。《程序员自我修养》这本书我觉得是理论与实践很好的结合了,它在最后一章给出了一个c和c++运行库的简单版的实现,通过实现这个可以更为深刻地理解可执行文件的结构、程序的执行、运行库的实现。参考这边书,我在linux下实现的一个简单的c运行库,这个运行库主要实现了文件操作、字符串操作、动态内存分配三个方面。1 程序的入口函数实现 当被问到... 阅读全文
posted @ 2013-06-05 21:10 在于思考 阅读(1487) 评论(2) 推荐(2) 编辑
摘要:在c语言中使用变长参数最常见的就是下面两个函数了:int printf(const char *format, ...);int scanf(const char *format, ...); 那他们是怎样实现支持变成参数的呢?在使用变长参数的函数(这里假设是func)实现部分其实用到了std... 阅读全文
posted @ 2013-05-30 21:10 在于思考 阅读(4642) 评论(4) 推荐(3) 编辑
摘要:1 输入参数传递数组或地址测试代码: 1 #include <stdio.h> 2 3 void foo(char *a) 4 { 5 fprintf(stdout, "%x %x %x\n", &a, a, a[0]); 6 } 7 8 int main ( int argc, char *argv[] ) 9 {10 char a[20] = {'a', 'b', 'c'};11 12 fprintf(stdout, "%x %x %x\n", &a, a, a[0]);13 阅读全文
posted @ 2013-05-30 17:30 在于思考 阅读(1279) 评论(0) 推荐(0) 编辑
摘要:1 程序的地址空间布局 一个程序在内存中运行,它靠四个东西:代码、栈、堆、数据段。代码段主要存放的就是可执行文件中的代码;数据段存放的就是程序中全局变量和静态变量;堆中是程序的动态内存区域,当程序使用malloc或new得到的内存是来自堆的;栈中维护的是函数调用的上下文,离开了栈就不可能实现函数的调用。在linux中它们的地址空间分布如下: 其中最让我迷惑的还是栈,它是怎么保存程序执行的上下文的?我对它的理解还是保留在数据结构学的栈,什么先进先出,只对栈顶进行操作,对于它的具体应用还真是不太了解。以前写代码就很好奇,当调用一个程序时,栈中到底保留了些什么东西?今天终于有了点理解。2 堆栈帧.. 阅读全文
posted @ 2013-05-28 21:49 在于思考 阅读(5115) 评论(0) 推荐(1) 编辑
摘要:调用惯例(Calling Convention):函数的调用方和被调用方对于函数如何调用需要有一个明确的约定,只有双方都遵守同样的约定,函数才能被正确的调用。 调用惯例一般会涉及到一下三个方面:1 函数参数传递的顺序与方式 函数传递参数的方式有很多中,可以通过寄存器、栈和内存区域传递,不过最常见的是通过栈传递。函数的调用方先将参数压入栈中,函数自己再从栈中取出参数。对于有多个参数的函数,调用惯例要规定调用方将函数压入栈的顺序:是从左到右,还是从右到左。有些惯例还允许通过寄存器传递参数,以提高性能。2 栈的维护方式 在函数压入栈之后,函数体会被调用,此后需要将被压入栈中的参数全部弹出,以使... 阅读全文
posted @ 2013-05-28 16:51 在于思考 阅读(2485) 评论(0) 推荐(0) 编辑
摘要:最近有个项目需要生成静态编译的可执行文件,以便在其它linux的机器中运行,开始以为非常简单,直接在编译中加个-static选项不就是了,结果却和我想的太不一样了,下面说下我遇到的问题以及解决的方法。 开始按照设想应该只要在编译中加个-static选项就可以了,不过却报下面的错误: cc -g -s 阅读全文
posted @ 2013-05-11 18:23 在于思考 阅读(11040) 评论(0) 推荐(0) 编辑
摘要:平衡负载 Du熊正在负责一个大型的项目,目前有K台服务器,有N个任务需要用这K台服务器来完成,所以要把这些任务分成K个部分来完成,在同上台服务器上执行的任务必须是连续的任务,每个任务有各自需要的执行时间。 例如N=5,K=2,每个任务需要时间分别为5,3,1,4,7分钟,那么我们可以分成(5)(3 1 4 7)两部分,这样第一台服务器所花时间就是5分钟,而第二台机器需要花15分钟,当然,所有任务完成的时间是按最迟完成的那台服务器的时间,即这样划分的话完成所有任务所需要的时间就是15分钟。而另外一种划分方法是(5 3 1)(4 7),这种划分方案完成所有任务的时间就是11分钟,也是最优的一种.. 阅读全文
posted @ 2013-04-16 09:13 在于思考 阅读(1476) 评论(6) 推荐(0) 编辑
摘要:我实现的文件监控主要是对某个文件夹里所有的文件检测是否修改、是否有新建文件、是否有文件被删除,并把这些改变记录到文件中。开始想用链表存储文件信息,毕竟链表删除方便,但链表的查找效率不高,所以打算用红黑树实现,因为红黑树查找和删除的操作都是比较快的。 基本思路是这样的:对于指定的文件夹,首先调用一个扫描函数,扫描指定文件夹里的所有文件和文件夹,当遇到一个文件或文件夹时,用文件名作为关键字在红黑树中查找该文件,如果不存在,就把文件名作为关键字,将文件路径,文件修改时间,标记等信息存入一个结点插入到红黑树中,将标记设置为新插入,如果存在,由于找到的结点会有多个(同名文件),所以要比较所有找到结... 阅读全文
posted @ 2013-04-10 09:42 在于思考 阅读(1771) 评论(3) 推荐(1) 编辑
摘要:红黑树的定义和插入在红黑树的实现(一)中已经描述和实现了,下面说一下红黑树的删除。 红黑树的删除也包括两个步骤: 1.删除结点 2.调整树满足红黑树的定义 首先是删除一个结点,同样可以按二叉排序树的删除结点来删除。删除结点又分为4中情况: (1)删除结点没有左孩子,有右孩子 (2)删除结点没有右孩子,有左孩子 (3)删除结点为叶子结点 (4)删除结点既有左孩子又有右孩子 对于情况(1),可以直接用右孩子代替删除的结点,并且由于删除结点有右孩子,所以删除结点必定为黑色,右孩子必定为红色(假设删除结点为红色,右孩子必定为黑色,这样是违反红黑树定义4的,所以删除结点必定为黑色,... 阅读全文
posted @ 2013-04-09 20:20 在于思考 阅读(1194) 评论(0) 推荐(1) 编辑
摘要:由于看个东西,发现要用到红黑树,所以拿算法导论看了下红黑树的定义和实现,第一遍看发现红黑树挺复杂的,第二遍再看发现好了点,第三遍又好点。。。n遍之后终于有点理解了。最后打算自己实现这个红黑树,也能更好的理解它。1 红黑色定义 首先红黑树的定义是非常重要的,它的定义如下: 1.一个结点要么是黑色,要么是红色,只能是其中的一种。 2.树的根结点一定是黑色。 3.如果一个结点为红色,那么它的孩子结点必定为黑色。 4.从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。 正是有了这个定义,使得红黑树保持了良好的性质,如树的高度不会超过2lgn,所以对某个关键字的查找时间为o(... 阅读全文
posted @ 2013-04-09 17:00 在于思考 阅读(1647) 评论(4) 推荐(1) 编辑
摘要:1 静态变量1.1 全局静态变量 在全局变量之前加上关键字static,全局变量就被定义成为一个全局静态变量。 (1)内存中的位置:静态存储区(静态存储区在整个程序运行期间都存在) (2)初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非他被显示初始化) (3)作用域:全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾。 好处: 定义全局静态变量的好处: <1>不会被其他文件所访问,修改 <2>其他文件中可以使用相同名字的变量,不会发生冲突。1.2 局部静态变量 在局部变量之前加上关键字static,局部变量就被定 阅读全文
posted @ 2013-04-05 11:17 在于思考 阅读(658) 评论(1) 推荐(0) 编辑
摘要:内联函数是代码被插入到调用者代码处的函数。如同 #define 宏,内联函数通过避免被调用的开销来提高执行效率,尤其是它能够通过调用(“过程化集成”)被编译器优化。 宏定义不检查函数参数,返回值什么的,只是展开,相对来说,内联函数会检查参数类型,所以更安全。 内联函数和宏很类似,而区别在于,宏是由预 阅读全文
posted @ 2013-04-04 21:11 在于思考 阅读(13012) 评论(0) 推荐(1) 编辑

1