随笔分类 -  c/c++

c++ 指针与引用的区别
摘要:指针与引用看上去完全不同(指针用操作符“*”和“->”,引用使用操作符“.”),但是它们似乎有相同的功能。指针与引用都是让你间接引用其他对象。你如何决定在什么时候使用指针,在什么时候使用引用呢?首先,要认识到在任何情况下都不能使用指向空值的引用。一个引用必须总是指向某些对象。因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量。相反,如果变量肯定指向一个对象,例如你的设计不允许变量为空,这时你就可以把变量声明为引用。“但是,请等一下”,你怀疑地问,“这样的代码会产生什么样的后果?”char *pc = 阅读全文

posted @ 2013-01-31 12:26 zhuyf87 阅读(228) 评论(0) 推荐(0)

c++ const 引用
摘要:const引用是指向const对象的引用。const int i = 10;const int &ref = i;可以读取ref,但不能修改。这样做是有意义的,因为i本身就不可修改,当然也不能通过ref来修改了。所以也就有将const变量赋值给非const引用是非法的。int &ref1 = i; // error: nonconst reference to a const object非const引用是指向非const类型变量的引用。const引用可以初始化为不同类型的对象或者右值(如字面值常量),但非const引用不可以。// legal for const refere 阅读全文

posted @ 2013-01-30 21:30 zhuyf87 阅读(1223) 评论(0) 推荐(0)

尾递归(Tail recursion / Tail call)
摘要:递归与尾递归关于递归操作,简单地说,一个函数直接或间接地调用自身,是为直接或间接递归。例如,可以使用递归来计算一个单向链表的长度:public static int GetLengthRecursively(Node head){ if (head == null) return 0; return GetLengthRecursively(head.Next) + 1;}在调用时,GetLengthRecursively方法会不断调用自身,直至满足递归出口。对递归有些了解的朋友一定猜得到,如果单向链表十分长,那么上面这个方法就可能会遇到栈溢出,也就是抛出StackOverflow... 阅读全文

posted @ 2013-01-30 17:04 zhuyf87 阅读(3394) 评论(1) 推荐(0)

有关c++ 变量的一些关键概念
摘要:c++是静态类型语言,在编译时会做类型检查,变量的类型决定了它的使用方式。静态类型检查有助于更早的发现程序错误。左值和右值:左值可以出现在赋值语句的左边或右边;右值只能出现在赋值语句的右边。变量是左值,字面值常量是右值。变量名以字母或下划线开头,由字母、数字、下划线组成,并且区分大小写。变量的声明和定义:定义用于为变量分配存储空间,可以指定初始值。声明仅用于表明变量的类型和名字。声明需要在类型前加extern关键字。int i; // 定义extern int i; // 声明extern double pi = 3.14; // 定义(声明不允许初始化,如果声明带初值,则被当做定义)变量的初 阅读全文

posted @ 2013-01-29 17:02 zhuyf87 阅读(277) 评论(0) 推荐(0)

c++ 字面值常量
摘要:字面值常量(literal constant),“字面值”是指只能用它的值称呼它,“常量”是指其值不能修改。每个字面值都有相应的类型,3.14是double型,2是int型。只有内置类型存在字面值。1. 整形字面值规则整形字面值常量可以用十进制、八进制、十六进制表示。20 // dec024 // oct(以0开头)0x14 // hex(以0x或0X开头)整形字面值常量的类型默认为int或long,其值适合int就是int类型,比int大就是long类型。在数值后加L或l(小写字母l容易与数字1混淆,建议用L)可以指定为long,加U或u指定为unsigned类型,加UL或LU定义为unsi 阅读全文

posted @ 2013-01-22 17:21 zhuyf87 阅读(7182) 评论(0) 推荐(0)

c++ 基本内置类型
摘要:c++定义了一组表示整数、浮点数、单个字符和布尔值的算术类型(arithmetic type)。另外还有一种特殊类型void,一般用作函数返回类型,或者void指针(void *:无类型指针,可以指向任意类型的数据。可用任意数据类型的指针对void指针赋值,因此常用void指针来作为函数形参,这样函数就可以接受任意数据类型的指针作为参数。)c++只规定每个算术类型的最小存储空间,并不阻止编译器使用更大的存储空间。比如int类型,编译器通常使用32 bit来存储。bool布尔型-char字符型8 bitwchar_t宽字符型16 bitshort短整型16 bitint整形16 bitlong长 阅读全文

posted @ 2013-01-18 17:56 zhuyf87 阅读(7008) 评论(0) 推荐(1)

简要记录浮点型数据的二进制存储格式
摘要:浮点数包括float和double两种类型,float占32位,double占64位。其二进制存储格式遵循IEEE754标准。以float为例:符号位:正数为0,负数为1。以float型数据123.456为例,分析其二进制存储格式。首先将十进制数123.456转换为二进制数为:1111011. 01110100101111001(其中0.456如何转换为二进制?不断乘以2…)。1111011. 01110100101111001即1. 11101101110100101111001乘以2的6次方。首先这是一个正数,则符号位为0。阶码为6,不过要转换成移码,6的移码为10000101。尾数则为1 阅读全文

posted @ 2013-01-18 17:38 zhuyf87 阅读(904) 评论(0) 推荐(0)

单例模式 c++实现
摘要:singleton.h:#ifndef _SINGLETON_H_#define _SINGLETON_H_// Singleton 模式#include "sync.h"// #define NULL ((void *)0)template <typename T>class Singleton{private: Singleton() {}; // ctor hidden Singleton (Singleton const&); // copy ctor hidden Singlet... 阅读全文

posted @ 2013-01-02 22:42 zhuyf87 阅读(256) 评论(0) 推荐(0)

【面试题】 类的赋值运算符函数
摘要:题目:CMyString类型声明如下,请为其添加“赋值运算符”函数。class CMyString{public: CMyString(char* pData = NULL); CMyString(const CMyString& str); ~CMyString(void); private: char* m_pData;};对于此类问题,面试官通常关注以下几点:1. 返回值类型是否为引用,函数结束时是否“return *this;”。只有这样,才能允许CMyString类型对象的连续赋值。2. 参数类型是否为常量引用。如果传入参数非引用而是实例,则从形参到... 阅读全文

posted @ 2013-01-02 13:45 zhuyf87 阅读(800) 评论(0) 推荐(0)

Boost下载安装编译配置使用指南
摘要:原文地址:http://www.cnblogs.com/wondering/archive/2009/05/21/boost_setup.html——更新于2011/7/19,目前我已对boost的安装和使用有了新的认识,因此也会对两年前写的这篇文章做大幅修改,网上转载版本泛滥,请以本文为准。理论上,本文适用于boost的各个版本,尤其是最新版本1.47.0;适用于各种C++编译器,如VC6.0(部分库不支持),VS2003,VS2005,VS2008,VS2010,gcc,C++ Builder等。先总结一下Windows系统。一、下载首先从boost官方主页http://www.boost 阅读全文

posted @ 2013-01-01 19:19 zhuyf87 阅读(263) 评论(0) 推荐(0)

【面试题】 c++ sizeof
摘要:在c++面试中,sizeof是经常被问到的概念。问:定义一个空类型,里面没有任何成员变量和成员函数,对该类型求sizeof,结果是多少?答:结果是1。问:为什么不是0?答:空类型的实例中不包含任何信息,本来求sizeof应该是0,但是当声明该类型的实例时,它必须在内存中占有一定的空间,否则无法使用这些实例。至于占用多少内存,由编译器决定。Visual Studio中每个空类型的实例占1个字节的空间。问:如果在该类型中添加一个构造函数和析构函数,再对该类型求sizeof,结果是多少?答:仍然是1。调用构造函数和析构函数只需要知道函数地址即可,而这些函数的地址只与类型相关,与类型的实例无关,编译器 阅读全文

posted @ 2013-01-01 08:58 zhuyf87 阅读(479) 评论(0) 推荐(0)

c++ 从标准异常类别(Exception Classes)派生新类别
摘要:(1)直接派生自exception,自己实现what()函数。namespace MyLib { /* user-defined exception class * derived from a standard class for exceptions */ class MyProblem : public std::exception { public: … MyProblem(…) { // special constructor } virtual const char* what() const throw() { // what() function... 阅读全文

posted @ 2012-12-30 14:18 zhuyf87 阅读(503) 评论(0) 推荐(0)

c++ 抛出标准异常
摘要:可以在自己的程序中抛出某些标准异常。抛出标准异常时,只需生成一个描述该异常的字符串,交给异常对象,它将成为what()返回的描述字符串。std::string s;…throw std::out_of_range(s);throw std::out_of_range(“out_of_range (somewhere, somehow)”);提供这种功能的标准异常有:logic_error及其派生类别、runtime_error及其派生类别、ios_base::failure。不能抛出exception,也不能抛出任何用以支持语言核心性质的异常(bad_alloc、bad_cast、bad_ty 阅读全文

posted @ 2012-12-30 13:37 zhuyf87 阅读(459) 评论(0) 推荐(0)

c++ 异常类别(Exception Classes)的成员
摘要:为了在catch子句中处理异常,需要知道异常提供哪些接口。所有标准异常只提供一个可用的接口函数:what(),用以获取异常“型别之外的附加信息”。namespace std { class exception { public: virtual const char* what() const throw(); … };}what()返回的字符串,很大程度决定了帮助的级别和信息的详细度。该字符串是以null结尾的“multibyte”字符串,也可以轻松转换为wstring并显示出来。what()返回的C-string在其所属的异常对象销毁后,就不再有效(标准没有强制)。除了w... 阅读全文

posted @ 2012-12-30 09:00 zhuyf87 阅读(1817) 评论(0) 推荐(0)

c++标准异常类别
摘要:语言本身或标准程序库所抛出的所有异常,都派生自基类exception。所有这些标准异常可分为三组:(1)语言本身支持的异常;(2)c++标准程序库发出的异常;(3)程序作用域(scope of a program)之外发生的异常。1. 语言本身支持的异常此类异常用以支撑某些语言特性。(1)new操作失败,会抛出bad_alloc异常(new的nothrow版本另当别论)。(2)执行期间,当一个作用于reference身上的“动态型别转换操作”失败时,dynamic_cast会抛出bad_cast异常。(3)执行期型别辨识(RTTI)过程中,如果交给typeid的参数为零或空指针,typeid操 阅读全文

posted @ 2012-12-29 22:38 zhuyf87 阅读(5154) 评论(0) 推荐(0)

c++ 捕获所有异常
摘要:捕获所有异常(catch-all)的catch子句的形式为“catch(…)”。// matches any exception that might be throwncatch(…) { // place our code here}“catch(…)”经常与重新抛出异常的“throw;”语句结合使用。catch完成可做的所有局部工作之后,重新抛出异常。try { // actions that cause an exception to be thrown}catch(…) { // work to partially handle the exception throw;}需要... 阅读全文

posted @ 2012-12-28 07:36 zhuyf87 阅读(12377) 评论(0) 推荐(1)

c++重新抛出异常
摘要:有可能单个catch不能完全处理一个异常,此时在进行了一些处理工作之后,需要将异常重新抛出,由函数调用链中更上层的函数来处理。重新抛出由“throw;”语句实现,throw后不跟表达式或类型。“throw;”将重新抛出异常对象,它只能出现在catch或catch调用的函数中,如果出现在其它地方,会导致调用terminate函数。被重新抛出的异常是原来的异常对象,不是catch形参。该异常类型取决于异常对象的动态类型,而不是catch形参的静态类型。比如来自基类类型形参catch的重新抛出,可能实际抛出的是一个派生类对象。只有当异常说明符是引用时,在catch中对形参的改变,才会传播到重新抛出的 阅读全文

posted @ 2012-12-27 10:46 zhuyf87 阅读(2838) 评论(0) 推荐(0)

c++捕获异常
摘要:catch子句(catch clause)中的异常说明符(exception specifier)决定了处理代码能够捕获的异常种类。1. 查找匹配的处理代码在查找匹配的catch期间,找到的是第一个可以处理该异常的catch。异常的类型与catch说明符的类型必须完全匹配,仅仅存在下面几种可能的区别。(1)非const对象的throw可以与指定接受const引用的catch匹配。(2)派生类对象的throw可以与指定其基类类型的catch匹配。(3)throw的数组会转换为指向其首元素的指针,函数会转换为函数指针。2. 异常说明符如果异常说明符不是引用,就将异常对象复制到catch形参中,ca 阅读全文

posted @ 2012-12-24 18:32 zhuyf87 阅读(1103) 评论(0) 推荐(0)

抛出异常与栈展开(stack unwinding)
摘要:抛出异常时,将暂停当前函数的执行,开始查找匹配的catch子句。首先检查throw本身是否在try块内部,如果是,检查与该try相关的catch子句,看是否可以处理该异常。如果不能处理,就退出当前函数,并且释放当前函数的内存并销毁局部对象,继续到上层的调用函数中查找,直到找到一个可以处理该异常的catch。这个过程称为栈展开(stack unwinding)。当处理该异常的catch结束之后,紧接着该catch之后的点继续执行。1. 为局部对象调用析构函数如上所述,在栈展开的过程中,会释放局部对象所占用的内存并运行类类型局部对象的析构函数。但需要注意的是,如果一个块通过new动态分配内存,并且 阅读全文

posted @ 2012-12-23 09:37 zhuyf87 阅读(8029) 评论(0) 推荐(4)

抛出类类型的异常
摘要:异常抛出后,被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那个。如果抛出的异常对象是一个数组,将转换为指向数组首元素的指针;如果抛出的是一个函数,则转换为指向该函数的指针。抛出throw之后,跟在throw后面的语句不会继续执行。控制将从throw转移到匹配的catch。该catch可以是同一函数中局部的catch,也可以在直接或间接调用发生异常的函数的另一个函数中。因为在处理异常的时候会释放局部存储,所以被抛出的对象就不能再局部存储,而是用throw表达式初始化一个称为异常对象(exception object)的特殊对象。异常对象由编译器管理,而且保证驻留在可能被激活的任 阅读全文

posted @ 2012-12-20 17:54 zhuyf87 阅读(1325) 评论(0) 推荐(0)

导航