随笔分类 - C/C++编程

摘要:malloc()是C语言中动态存储管理的一组标准库函数之一。其作用是在内存的动态存储区中分配一个长度为size的连续空间。其参数是一个无符号整形数,返回值是一个指向所分配的连续存储域的起始地址的指针malloc()工作机制malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块 阅读全文
posted @ 2012-10-18 10:28 Mr.Rico 阅读 (215) | 评论 (0) 编辑
摘要:这篇文章主要讲解G++编译器中虚继承的对象内存分布问题,从中也引出了dynamic_cast和static_cast本质区别、虚函数表的格式等一些大部分C++程序员都似是而非的概念。问题拿捏得十分到位,下面是我对原文的翻译,原文见这里(By Edsko de Vries, January 2006)。本文是介绍C++的技术文章,假定读者对于C++有比较深入的认识,同时也需要一些汇编知识。本文我们将阐释GCC编译器针对多重继承和虚拟继承下的对象内存布局。尽管在理想的使用环境中,一个C++程序员并不需要了解这些编译器内部实现细节,实际上,编译器针对多重继承(特别是虚拟继承)的各种实现细节对于我们编 阅读全文
posted @ 2012-10-18 08:09 Mr.Rico 阅读 (224) | 评论 (0) 编辑
摘要:大多数时候,我们研究的是如何阅读源代码。但在一些情况下,比如源代码不公开或得到源代码的代价很高的情况下,我们又不得不需要了解程序的行为,这 时阅读二进制文件就非常重要。假设现在有一个二进制可执行文件,我们木有源代码,但要了解它的实现,这里仅简单列出一些常用的工具。 阅读方式可分为两个方面:静态阅读和动态阅读。 静态阅读 首先,file命令可以查看可执行文件的大体信息。比如是哪种格式的,哪个体系结构的,有没有调试信息等。这些决定了需要用哪个版本的工具进行进一 步查看。比如如果是arm体系的可执行文件就可用arm toolchain里的工具,如arm-eabi-objdump,arm-eab... 阅读全文
posted @ 2012-08-27 23:10 Mr.Rico 阅读 (1455) | 评论 (0) 编辑
摘要:"该死系统存在内存泄漏问题",项目中由于各方面因素,总是有人抱怨存在内存泄漏,系统 长时间运行之后,可用内存越来越少,甚至导致了某些服务失败。内存泄漏是最难发现的常见错误之一,因为除非用完内存或调用malloc失败,否则都不会导 致任何问题。实际上,使用C/C++这类没有垃圾回收机制的语言时,你很多时间都花在处理如何正确释放内存上。如果程序运行时间足够长,如后台进程运行在 服务器上,只要服务器不宕机就一直运行,一个小小的失误也会对程序造成重大的影响,如造成某些关键服务失败。对于内存泄漏,本人深有体会!实习的时候,公司一个项目中就存在内存泄漏问题,项目的代码两非常大,后台进程 阅读全文
posted @ 2012-08-27 09:47 Mr.Rico 阅读 (269) | 评论 (0) 编辑
摘要:为什么需要知道C/C++的内存布局和在哪可以可以找到想要的数据?知道内存布局对调试程序非常有帮助,可以知道程序执行时,到底做了什么,有助于写出干净的代码。本文的主要内容如下:源文件转换为可执行文件可执行程序组成及内存布局数据存储类别一个实例总结源文件转换为可执行文件源文件经过以下几步生成可执行文件:1、预处理(preprocessor):对#include、#define、#ifdef/#endif、#ifndef/#endif等进行处理 2、编译(compiler):将源码编译为汇编代码 3、汇编(assembler):将汇编代码汇编为目标代码 4、链接(linker):将目标代码链接为可执 阅读全文
posted @ 2012-08-27 09:29 Mr.Rico 阅读 (267) | 评论 (0) 编辑
摘要:本文首先向读者讲解了Linux下进程地址空间的布局以及进程堆栈帧的结构,然后在此基础上介绍了Linux下缓冲区溢出攻击的原理及对策。 前言 从 逻辑上讲进程的堆栈是由多个堆栈帧构成的,其中每个堆栈帧都对应一个函数调用。当函数调用发生时,新的堆栈帧被压入堆栈;当函数返回时,相应的堆栈帧从堆 栈中弹出。尽管堆栈帧结构的引入为在高级语言中实现函数或过程这样的概念提供了直接的硬件支持,但是由于将函数返回地址这样的重要数据保存在程序员可见的 堆栈中,因此也给系统安全带来了极大的隐患。 历史上最著名的缓冲区溢出攻击可能要算是1988年11月2日的Morris Worm所携带的攻击代... 阅读全文
posted @ 2012-07-22 19:07 Mr.Rico 阅读 (2855) | 评论 (0) 编辑
摘要:每年的 09/28 於我都是一个特殊的日子 -- 不只是因为教师节。今年很特殊地没有普天同庆,那麽我就写篇文章自己庆祝一下好了。我於今年七月发表了一本着作《多型与虚拟》和一本译作《深度探索C++物件模型》,获得很大的回响。这些作品都不是针对 C++ 的完全初学者所写,但从初阶到高阶为数众多的 C++ guy,热情地表达了他们对这些主题的喜悦。在许多来信中,我看到一些有趣的现象,也感受到一些值得整理下来的想法。所以,根据我个人的学习过往、我的教学经验、以及周遭朋友的心得交流,写下这篇文章,或可为後学者戒。●《多型与虚拟》序言节录首先让我节录《多型与虚拟》一书序言:《多型与虚拟》序 节录(侯俊杰. 阅读全文
posted @ 2012-07-16 15:18 Mr.Rico 阅读 (278) | 评论 (0) 编辑
摘要:在31年前(1979年),一名刚获得博士学位的研究员,为了开发一个软件项目发明了一门新编程语言,该研究员名为Bjarne Stroustrup, 该门语言则命名为——C with classes,四年后改称为C++。C++是一门通用编程语言,支持多种编程范式,包括过程式、面向对象(object-oriented programming, OP)、泛型(generic programming, GP),后来为泛型而设计的模版,被发现及证明是图灵完备的,因此使C++亦可支持模版元编程范式(template metaprogramming, TMP)。C++继承了C的特色,既为高级语言,又含低级.. 阅读全文
posted @ 2012-07-16 14:55 Mr.Rico 阅读 (838) | 评论 (0) 编辑
摘要:缘起 在项目中发现某些情况下,对象的析构函数不被调用,比如程序调用exit(), 异常终止等。那么,析构函数什么情况下不会被调用呢? RAII RAII(资源获取即初始化RAII, Resource Acquisition Is Initialization)是C++编程中很重要的一项技术。其原理是在对象析构函数中释放该对象获取的资源,利用栈展开过程栈上对象的析构函数将被 自动调用的保证,从而正确地释放先前获取的资源。RAII只有在栈展开正常执行的前提下才能正常工作。函数调用和正常的C++异常处理流程(异常处于 try-catch块)都存在栈展开。 栈展开 最常见的栈展开就是正常的函数调用,. 阅读全文
posted @ 2012-07-10 10:57 Mr.Rico 阅读 (221) | 评论 (0) 编辑
摘要:C++的类型萃取技术 自从C++中引入了template后,以泛型技术为中心的设计得到了长足的进步。STL就是这个阶段杰出的产物。STL的目标就是要把数据和算法分开,分别对其进行设计,之后通过一种名为iterator的东西,把这二者再粘接到一起。设计模式中,关于iterator的描述为:一种能够顺序访问容器中每个元素的方法,使用该方法不能暴露容器内部的表达方式。可以说,类型萃取技术就是为了要解决和iterator有关的问题的,下面,我们就来看看整个故事。应该说,迭代器就是一种智能指针,因此,它也就拥有了一般指针的所有特点——能够对其进行*和->操作。但是在遍历容器的时候,不可... 阅读全文
posted @ 2012-07-01 12:48 Mr.Rico 阅读 (151) | 评论 (0) 编辑
摘要:读书不是目的,关键在于思考。 很早就在水木上看到有人推荐《The C Programming Language》这本书,一直都没看,开学一个月就专心拜读了一下,并认真做了课后习题。读来收获不少,主要有两点:一是加深了自己对一些基础知识的理 解和感悟;二是从中学到了一些不错的编程风格和设计思想,这些东西虽看起来不起眼但细细嚼来还是很值得学习的。下面就从四个方面做一个小总结,水平有限, 加之刚读第一遍,难免有疏漏和错误,非常欢迎批评补充。 ===读书感悟=== ===设计思想=== ===编程风格=== ===经典例程===... 阅读全文
posted @ 2012-06-27 22:10 Mr.Rico 阅读 (1845) | 评论 (0) 编辑
摘要:之前有篇文章讨论过C/C++中的内存存储问题:http://www.cnblogs.com/xkfz007/articles/2490175.html这一篇是主要介绍C++中堆和栈的区别。 C++作为一款C语言的升级版本,具有非常强大的功能。它不但能够支持各种程序设计风格,而且还具有C语言的所有功能。我们在这里为大家介绍的是其中一个比较重要的内容,C++内存区域的基本介绍。 C++内存区域分为5个区域。分别是堆,栈,自由存储区,全局/静态存储区和常量存储区。 栈:由编译器在需要的时候分配,在不需要的时候自动清除的变量存储区。里面通常是局部变量,函数参数等。 堆:由new分配的内存块,他们的释放 阅读全文
posted @ 2012-06-22 20:12 Mr.Rico 阅读 (210) | 评论 (0) 编辑
摘要:《C++ Templates》读书笔记(一):模板参数2009-08-17 12:48有三种模板参数(形参):(1)类型参数(这是使用得最多的)(2)非类型参数(3)模板的模板参数类型参数: 类型参数是通过关键字typename或者class引入。关键字后面必须是一个简单的标识符,后面用逗号来隔开下一个参数声明,等号代表接下来的是缺省模板实参,一个封闭的尖括号(>)表示参数化子句的结束。 在模板声明内部,类型参数的作用类似于typedef名称。例如,如果T是一个模板参数,就不能使用诸如class T等形式的修饰名称,即使T是一个要被class类型替换的参数也不可以。 template & 阅读全文
posted @ 2012-06-22 09:04 Mr.Rico 阅读 (341) | 评论 (0) 编辑
摘要:模板类中操作符重载问题("<<"和">>"重载)在模板类中输入流“>>”和输出流“<<”的重载,若使用友元在类内声明,在类外实现,那么连接时将会报错,但我们可以采用以下三种方式来实现输出流"<<"和"输入流>>"的重载。 一、将输出流"<<"和"输入流>>"重载的实现写在类中 #include"stdafx.h"#include<iostream>u 阅读全文
posted @ 2012-06-04 11:11 Mr.Rico 阅读 (7313) | 评论 (0) 编辑
摘要:什么是容器 首先,我们必须理解一下什么是容器,在C++ 中容器被定义为:在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对像的指针,这种对象类型就叫做容器。很简单,容器就是保存其它对象的对 象,当然这是一个朴素的理解,这种“对象”还包含了一系列处理“其它对象”的方法,因为这些方法在程序的设计上会经常被用到,所以容器也体现了一个好处, 就是“容器类是一种对特定代码重用问题的良好的解决方案”。 容器还有另一个特点是容器可以自行扩展。在解决问题时我们常常不知道我们需要存储多少个对象,也就是说我们不知道应该创建多大的内存空间来保存我们的对象。 显然,数组在这一方面也力不从心。容器的... 阅读全文
posted @ 2012-06-04 10:30 Mr.Rico 阅读 (10167) | 评论 (0) 编辑
摘要:如果用户熟悉Linux下的sed、awk、grep或vi,那么对正则表达式这一概念肯定不会陌生。由于它可以极大地简化处理字符串时的复杂度,因此现在已经在许多Linux实用工具中得到了应用。千万不要以为正则表达式只是Perl、Python、Bash等脚本语言的专利,作为C语言程序 员,用户同样可以在自己的程序中运用正则表达式。 标准的C和C++都不支持正则表达式,但有一些函数库可以辅助C/C++程序员完成这一功能,其中最著名的当数PhilipHazel的Perl-CompatibleRegularExpression库,许多Linux发行版本都带有这个函数库。 编译正则表达式 ... 阅读全文
posted @ 2012-05-20 11:16 Mr.Rico 阅读 (117) | 评论 (0) 编辑
摘要:最近在项目开发中,遇到一个异常,经过测试,发现是迭代器失效问题,于是稍微总结了一下。 vector迭代器失效测试: 测试程序: voidvectorTest(){vector<int>container;for(inti=0;i<10;i++){container.push_back(i);}vector<int>::iteratoriter;for(iter=container.begin();iter!=container.end();iter++){if(*iter>3)container.erase(iter);}for(iter=container 阅读全文
posted @ 2012-05-20 09:18 Mr.Rico 阅读 (7070) | 评论 (0) 编辑
摘要:了解各种不同意义的new 和 delete C++中关于new 的形态主要有三种:new operator, operator new, placement new 三者的用法有着不同,注意区别适用的条件: new operator: new 操作符,和C++语言其它操作符(如+, -, ->, ::....)一样,是由语言内建的,总是完成相同的事情,程序员不能改变其意义。如下为new的一种用法: string *ps = new string("hazirguo"); 它主要完成的任务包括三个方面: 分配足够的内存,用来放置某类型对象。上例中分配足够放置一个stri 阅读全文
posted @ 2012-05-17 13:19 Mr.Rico 阅读 (105) | 评论 (0) 编辑
摘要:了解临时对象的来源 什么是临时对象? C++真正的临时对象是不可见的匿名对象,不会出现在你的源码中,但是程序在运行时确实生成了这样的对象. 通常出现在以下两种情况: (1)为了使函数调用成功而进行隐式类型转换的时候。 传递某对象给一个函数,而其类型与函数的形参类型不同时,如果可以通过隐式转化的话可以使函数调用成功,那么此时会通过构造函数生成一个临时对象,当函数返回时临时对象即自动销毁。如下例: //计算字符ch在字符串str中出现的次数 int countChar (const string& str, char ch); char buffer[];... 阅读全文
posted @ 2012-05-17 12:46 Mr.Rico 阅读 (13405) | 评论 (10) 编辑
摘要:C语言可变参数实现 第一:什么是可变参数int printf(const char* format, ...);看到printf的定义大家就知道了,只有一个固定的const char*参数,后面的都是不定长的参数列表了。第二:自己写一个可变参数函数1.参数形参方式,跟printf类似,第一个为固定参数,后面的用...代替;2.包含stdarg.h头文件,因为需要用到几个里面定义的宏;void va_start(va_list arg_ptr, prev_param);type va_arg(va_list arg_ptr, type);void va_end(va_list arg_ptr). 阅读全文
posted @ 2012-05-15 15:48 Mr.Rico 阅读 (566) | 评论 (0) 编辑
摘要:有下面的一个简单的类: classCNullPointCall{public:staticvoidTest1();voidTest2();voidTest3(intiTest);voidTest4();private:staticintm_iStatic;intm_iTest;};intCNullPointCall::m_iStatic=0;voidCNullPointCall::Test1(){cout<<m_iStatic<<endl;}voidCNullPointCall::Test2(){cout<<"VeryCool!"< 阅读全文
posted @ 2012-05-14 13:24 Mr.Rico 阅读 (4589) | 评论 (0) 编辑
摘要:一个map就是一个(关键码(key),值(value))对偶的序列,它提供基于关键码的快速提取操作。也就是说,可以用下标运算符[]将关键码 作为下标去执行查找,并返回对应的值。因此可以把map的使用方法想象成有特殊下标的数组。在很多时候用下标运算符[]来对map中的元素进行存取是非常 方便和简单的;但是,如果map下标运算符[]运用不得当,也会造成意想不到的问题。 我们知道,C++是不检查下标越界的。用超出数组下标范围的下标去访问数组元素的错误会在运行期出现,很有可能将程序搞崩溃。对于map而言,也没有类似 的下标越界概念,但是却有作为下标的关键码(key)在map中不存在的现象。在这种情况. 阅读全文
posted @ 2012-05-14 12:55 Mr.Rico 阅读 (119) | 评论 (0) 编辑
摘要:字符,字节和编码 [原创文章,转载请保留或注明出处:http://www.regexlab.com/zh/encoding.htm] 级别:中级 摘要:本文介绍了字符与编码的发展过程,相关概念的正确理解。举例说明了一些实际应用中,编码的实现方法。然后,本文讲述了通常对字符与编码的几种误解,由于这些误解而导致乱码产生的原因,以及消除乱码的办法。本文的内容涵盖了“中文问题”,“乱码问题”。 掌握编码问题的关键是正确地理解相关概念,编码所涉及的技术其实是很简单的。因此,阅... 阅读全文
posted @ 2012-05-13 17:34 Mr.Rico 阅读 (123) | 评论 (0) 编辑
摘要:转自:http://www.cppblog.com/franksunny/archive/2007/08/03/29269.html 主 要用于多任务环境中,一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段代 码,而返回控制时不会出现什么错误;而不可重入的函数由于使用了一些系统资源,比如全局变量区,中断向量表等,所以它如果被中断的话,可能会出现问题,这 类函数是不能运行在多任务环境下的。 也 可以这样理解,重入即表示重复进入,首先它意味着这个函数可以被中断,其次意味着它除了使用自己栈上的变量以外不依赖于任何环境(包括sta 阅读全文
posted @ 2012-05-12 18:20 Mr.Rico 阅读 (77) | 评论 (0) 编辑
摘要:我一直回避程序的内存管理,因为爱之愈深,恨之愈烈。但是,还是由很多的朋友一直在体这方面的问题,所以就索性把它坦白了,也许对你我都是一件好事情。 首先,需要搞清楚:变量的类型和它的存储类别是两个概念。 数据类型和内存管理没有直接的关系。 一、由C/C++编译的程序占用的内存分为以下几个部分: 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方... 阅读全文
posted @ 2012-05-08 15:24 Mr.Rico 阅读 (160) | 评论 (1) 编辑
摘要:摘要: 本文简述了随机数的产生原理,并用C语言实现了迭代取中法,乘同余法等随机数产生方法,同时,还给出了在符合某种概率分布的随机变量的产生方法。 关键词: 伪随机数产生,概率分布 1前言: 在用计算机编制程序时,经常需要用到随机数,尤其在仿真等领域,更对随机数的产生提出了较高的要求,仅仅使用C语言类库中的随机函数已难以胜任相应的工作。本文简单的介绍随机数产生的原理及符合某种分布下的随机变量的产生,并用C语言加以了实现。当然,在这里用计算机基于数学原理生成的随机数都是伪随机数。 注:这里生成的随机数所处的分布为0-1区间上的均匀分布。我们需要的随机数序列应具有非退化性,周期长,相关系数... 阅读全文
posted @ 2012-05-07 15:40 Mr.Rico 阅读 (12724) | 评论 (0) 编辑
摘要:字符串字面量(string literal)是一段双引号括起来的多字节字符序列,C/C++将其实现为具有静态存储连续性的字符数组。初学者(包括不少书籍)常将其称为字符串常量,但这说法只在C++成立,C中不成立。C中的常量只包括下列四种: 6.4.4 Constants Syntax constant: integer-constant floating-constant enumeration-constant character-constant 分别是整数常量、浮点常量、枚举常量和字符常量,并不包括字符串字面量。但由于字符串字面量具有静态存储连续性数组类型,并且在表达式中它会根据数组到.. 阅读全文
posted @ 2012-05-01 20:32 Mr.Rico 阅读 (549) | 评论 (0) 编辑
摘要:const修饰普通变量和指针 const修饰变量,一般有两种写法: const TYPE value; TYPE const value; 这两种写法在本质上是一样的。它的含义是:const修饰的类型为TYPE的变量value是不可变的。对于一个非指针的类型TYPE,无论怎么写,都是一个含义,即value值不可变。 例如: const int nValue; //nValue是const int const nValue; //nValue是const 但是对于指针类型的TYPE,不同的写法会有不同情况: (1) 指针本身是常量不可变 (char*) const pConte... 阅读全文
posted @ 2012-03-27 14:40 Mr.Rico 阅读 (27173) | 评论 (2) 编辑
摘要:C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助。 Const 是C++中常用的类型修饰符,常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。 一、Const作用 如下表所示: No. 作用 说明 参考代码 1 可以定义const常量 const int Max = 100; 2 便于进行类型检查 const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,... 阅读全文
posted @ 2012-03-27 14:30 Mr.Rico 阅读 (7095) | 评论 (0) 编辑
摘要:在C/C++中,64为整型一直是一种没有确定规范的数据类型。现今主流的编译器中,对64为整型的支持也是标准不一,形态各异。一般来说,64位 整型的定义方式有long long和__int64两种(VC还支持_int64),而输出到标准输出方式有 printf(“%lld”,a),printf(“%I64d”,a),和cout << a三种方式。 本文讨论的是五种常用的C/C++编译器对64位整型的支持,这五种编译器分别是gcc(mingw32),g++(mingw32),gcc(linux i386),g++(linux i386),Microsoft Visual C++ 6.0 阅读全文
posted @ 2012-03-12 15:26 Mr.Rico 阅读 (5089) | 评论 (0) 编辑
摘要:1、http://codepad.org/推荐星级:★★★★是否需注册:否(注册的话也很快,几秒钟而已) 优点:网页界面简洁,一目了然,适合手机浏览器。且支持C,C++,D,PHP,PYTHON,Perl,Ruby等十几种编程语言,非常强大。查看执行结果时,高亮显示代码。缺点:有时点击提交按钮后,给出一个出错页面,需多次提交才给出结果。另外不具有交互性,且不提供编译后的可执行文件。 2、http://www.comeaucomputing.com/tryitout/ 推荐星级:★★ 是否注册:貌似不需要(网页上显示,注册后功能更多) 优点:编译器的版本多 缺点:页面文字较多,不适合手机浏览,. 阅读全文
posted @ 2012-03-05 16:46 Mr.Rico 阅读 (202) | 评论 (0) 编辑
摘要:本文介绍了GCC和C99标准中inline使用上的不同之处。inline属性在使用的时候,要注意以下两点:inline关键字在GCC参考文档中仅有对其使用在函数定义(Definition)上的描述,而没有提到其是否能用于函数声明(Declare)。 从 inline的作用来看,其放置于函数声明中应当也是毫无作用的:inline只会影响函数在translation unit(可以简单理解为C源码文件)内的编译行为,只要超出了这个范围inline属性就没有任何作用了。所以inline关键字不应该出现在函数声明 中,没有任何作用不说,有时还可能造成编译错误(在包含了sys/compiler.... 阅读全文
posted @ 2012-02-27 23:44 Mr.Rico 阅读 (20891) | 评论 (0) 编辑
摘要:C++中的inline是个容易被误解的关键字,即使是专家也常会犯错。不信?请打开《Thinking in C++ 2rd Edition Volumn 1》,找到Chapter 9 "Inline Function"的Exercise 6:“Prove that inline functions default to internal linkage."为什么我说这里作者犯错了呢?因为C++ 03标准中角标79处明确写到:“ The inline keyword has no effect on the linkage of a function.“ 看,标准明确 阅读全文
posted @ 2012-02-27 23:33 Mr.Rico 阅读 (340) | 评论 (0) 编辑
摘要:一、模板特化(specialization of template)模板特化(specialization of template)并不是说实例化一个模板,如template <class T>,class stack<T>;声明stack<int>,这是实例化一个模板类。类模板特化的意思是,对于某个特定的类型,需要对模板进行特殊化,即特殊的处理。例如,stack类模板针对bool类型有特化,因为实际上bool类型只需要一个二进制位,就可以对其进行存储,使用一个字或者一个字节都是浪费存储空间的.同样,函数模板特化也是针对某个特定类型的特殊处理,一个比较经典的 阅读全文
posted @ 2012-02-27 22:01 Mr.Rico 阅读 (106) | 评论 (0) 编辑
摘要:如何判断栈的增长方向?对于一个用惯了i386系列机器的人来说,这似乎是一个无聊的问题,因为栈就是从高地址向低地址增长。不过,显然这不是这个问题的目的,既然把这个问题拿出来,问的就不只是i386系列的机器,跨硬件平台是这个问题的首先要考虑到的因素。在一个物质极大丰富的年代,除非无路可退,否则我们坚决不会使用汇编去解决问题,而对于这种有系统编程味道的问题,C是一个不错的选择。那接下来的问题就是如何用C去解决这个问题。C在哪里会用到栈呢?稍微了解一点C的人都会立刻给出答案,没错,函数。我们知道,局部变量都存在于栈之中。似乎这个问题立刻就得到了解答,用一个函数声明两个局部变量,然后比较两个变量的地址, 阅读全文
posted @ 2012-02-27 10:56 Mr.Rico 阅读 (3383) | 评论 (0) 编辑
摘要:1. const变量声明中带有关键词const,意味着不能通过赋值,增量或减量来修改该变量的值,这是显而易见的一点。指针使用const则要稍微复杂点,因为不得不把让指针本身成为const和指针指向的值成为const区别开来、下面的声明表示pf指向的值必须是不变的constfloat *pf;而pf则是可变的,它可以指向另外一个const或非const值;相反,下面的声明说明pf是不能改变的,而pf所指向的值则是可以改变的:float* const pf;最后,当然可以有既不能改变指针的值也不能改变指针指向的值的值的声明方式:constfloat * const pf;需要注意的是,还有第三种放 阅读全文
posted @ 2012-02-27 10:23 Mr.Rico 阅读 (1089) | 评论 (0) 编辑
摘要:按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的. 静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间.这种分配策略要求程序 代码中不允许有可变数据结构(比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译程序无法计算准确的存储空间需求. 栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的.和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完 全未知的,只有到运行的时候才能够知道,但是规定在运行中进入一个程序模块时,必须知道该程序模块所... 阅读全文
posted @ 2012-02-26 15:53 Mr.Rico 阅读 (105) | 评论 (0) 编辑
摘要:多态性----vptr----vtable 多态性 (polymorphism) 是面向对象编程的基本特征之一。而在 C++ 中,多态性通过虚函数 (virtual function) 来实现。我们来看一段简单的代码: #include<iostream>usingnamespacestd;classBase{inta;public:virtualvoidfun1(){cout<<"Base::fun1()"<<endl;}virtualvoidfun2(){cout<<"Base::fun2()"< 阅读全文
posted @ 2012-02-16 11:18 Mr.Rico 阅读 (237) | 评论 (0) 编辑
摘要:math.h常用函数 int abs (int x); double acos (double x); double asin (double x); double atan (double x); double atan2 (double y, double x); double atof (const char *s); double ceil (double x); double cos (double x); double cosh (double x); double exp (double x); double fabs (double x); double floor (dou. 阅读全文
posted @ 2012-02-02 22:16 Mr.Rico 阅读 (2421) | 评论 (0) 编辑
摘要:C++语言风格流变史 文章来源:计算机世界网 作者:王咏刚 程序代码也有风格,这算不得什么新鲜事。早在20世纪80年代, C语言程序员就必须在K&R风格和ANSI风格之间择善而从。但平心而论,我确实没有见过哪一种语言能像C++这样,在代码风格方面表现得如此诡 谲和难以捉摸:谁也说不清C++代码究竟能衍生出多少种迥异的风格,但我知道,有许多C++初学者在面对不同风格的C++代码时,经常会误以为自己看到的 是好几种完全不同的编程语言——仅此一点就足以提醒我们,研究和廓清C++语言风格的演化和发展规律已是当务之急了。 和文体学家们研究历朝历代文体变迁的工作相仿,研究C++语言风格的流变史也没 阅读全文
posted @ 2011-04-17 15:41 Mr.Rico 阅读 (194) | 评论 (0) 编辑