2013年12月7日

gcc编译器局部变量在栈中的内存分配

摘要: 内存分配,根据系统与编译器的不同,差别很大。 之前曾经发现在ubuntu12.04系统gcc 4.63版本编译器,先定义的局部变量在栈中地址低,而后定义的局部变量在栈中地址高,与认知有差别。试了多个系统与编译器,最后发现与linux发行版关系不大,而与gcc的版本有关。在gcc4.4.7版本和4.8.0版本中,栈中的内存地址分配“正常”。 今天又因为一个问题,对这个问题进行了进一步的探索。 试验之后,得到如下的大致结论。 gcc4.47ubuntu12.04环境中,在栈中定义多个变量时: 同类型的,单元素数组按单元素算。从高到低,从元素到数组(数组在低地址)。 不同类型... 阅读全文

posted @ 2013-12-07 23:52 4IT 阅读(1195) 评论(0) 推荐(0)

2013年11月28日

算法复习(7)有序二叉树

摘要: 二叉树,每个节点至多有两个子树。第n层节点总数不超过2^(n-1)。 有序二叉树,左子树中的数据比节点的数据小,右子树中的数据比节点不小。 二叉树的结构,可以方便的进行递归,将问题的规模减小。 对于有序二叉树,查找某个数据,与节点的值想比较,判断下次比较进入哪个子树,每次规模缩减一半。与二分查找有共通之处。 递归,函数自己调用自己。形象地说就是“将要做的事,就是正在做的事”。内联函数不能递归。 阅读全文

posted @ 2013-11-28 23:50 4IT 阅读(251) 评论(0) 推荐(0)

2013年11月27日

算法复习(6)链表实现的队列

摘要: 使用链表实现的队列,先进先初,压入弹出判空。 1 // 基于链表的队列 2 #include 3 using namespace std; 4 template 5 class Queue 6 { 7 public: 8 //在构造过程中初始化为空队列 9 Queue(void) : m_rear (NULL), m_front (NULL) {} 10 //在析构过程中销毁剩余节点 11 ~Queue(void) 12 { 13 for (Node* next; m_front; m_front = ne... 阅读全文

posted @ 2013-11-27 23:33 4IT 阅读(204) 评论(0) 推荐(0)

2013年11月26日

向上

摘要: 因为工作的事情去了一家合作场所。拆除设备,并帮助场所的人搬家。 在帮忙干活的时候,告诉场所的女老板不久要离职了。她立刻说“到我这里工作吧,我觉得你这小伙不错”。也许她只是客套,但让我感觉很好。我说因为个人原因,考虑离家近一些,不准备在哈尔滨发展了。回想一年多前开始接触的时候,那种状态,真是不胜唏嘘。因为之遗留问题,我刚接手工作,与她接触时,那种不信任。在当时,一次次的跑动,终于继续合同,但是在合同签署之前,她甚至提出要我押身份证。一年多时间,一次次言出必行,一次次为她的利益考虑。最后对我认可,对合作认可,对公司认可。谈及后续合作的问题,我说合作不要因为我离开而产生问题,公司肯定会挑选合适... 阅读全文

posted @ 2013-11-26 23:27 4IT 阅读(107) 评论(0) 推荐(0)

2013年11月25日

算法复习(5)链表实现的堆栈

摘要: 复习算法的时候,实然想用链表实现堆栈。就着手去写,顺便复习一下STL的内容。C++涉及的内容太多,折腾完VC及MFC,再回头,好像又不会了。今天是第一次贴完整的代码呢,不知道会不会有大神看到给指正指正。 1 //基于链式表的堆栈 2 #include 3 using namespace std; 4 class Student 5 { 6 public: 7 int m_no; 8 string m_name; 9 int m_age; 10 11 Student(int no, const string& name, int a... 阅读全文

posted @ 2013-11-25 23:51 4IT 阅读(186) 评论(0) 推荐(0)

2013年11月24日

算法复习(4)向量与列表

摘要: 向量是由一组元素封装而成的线性序列。向量是数组的抽象与泛化,元素类型可以灵活选取。向量使用连续的内存存储元素。一旦容量需要扩充,在紧临的后方再开辟一块内存(通常是倍增)。如果后方的内存不足,则寻找一块足够大的内存,开辟倍增的内存,再将原来的向量复制过来。 向量是连续内存,所以循秩访问非常方便,通过指针计算,可以一步到位。同时,也由于必须是连续内存,在其中插入与删除元素,需要对后续的元素全部进行移动,操作复杂。 列表采用动态储存策略。其中的元素称为节点。每个节点至少包含三个成员,数据、前指针和后指针。各节点通过指针相互联接,在逻辑上是一个线性结构。 与向量中紧密的内存排布不同,列表的内... 阅读全文

posted @ 2013-11-24 23:54 4IT 阅读(325) 评论(0) 推荐(0)

2013年11月23日

C与C++的错误处理

摘要: 通过函数的返回值表示错误,之前已经大量使用过这种方法。这种方法因为有return,函数的右括号会被执行,对象可以正确地被析构。但是这种方法需要层层判断返回值,流程非常繁琐。在UnixC的源代码中,经常是返回值判断的代码比运行的代码还要多。 通过setjmp/longjmp远程跳转。C中的函数,一般是调用一次返回一次,而setjmp比较特殊,是调用一次,返回两次。longjmp也比较特别,是从一个函数是调用,而从另一个函数里返回。这两个函数相互配合,构成远程跳转,实现C中的错误集中处理。第一次调用setjmp时,会将进入函数时的环境信息,包括系统堆栈保存到一个jmp_buf缓冲区中,并返回... 阅读全文

posted @ 2013-11-23 23:55 4IT 阅读(172) 评论(0) 推荐(0)

2013年11月22日

c++几种类型转换在派生类中的应用

摘要: dynamic_cast 应用于具有多态性(或具有虚函数)的类之间。会对要转换的指针进行检查,如果指针指向的目标对象类型与所要转的类型一致,则转换成功。如果不一致,或完全是无关类型,则得到一个空指针。所以使用dynamic_cast时,对返回值进行判断。因为引用不存在空引用,dynamic_cast会在执行时抛出异常(std::bad_cast)。 static_cast 可以接受基类与子类的类型转换。对于基类与基类子类的子类之间的类型转换也能接受,但是这样的转换是有风险的。static_cast会在无关类型之间转换时报错。 reinterpret_cast 重解释类型的转换,在... 阅读全文

posted @ 2013-11-22 23:58 4IT 阅读(117) 评论(0) 推荐(0)

2013年11月21日

c++虚函数

摘要: 为了实现由一个基类派生出的多个子类,对于其中的某个功能,各个子类实现不同的操作,需要用到虚函数。 如果将基类中的一个成员函数声明为虚函数(virtual),子类中的同名函数也成为虚函数,并且对基类版本形成覆盖。隐藏只需要是同名的标识符即可构成隐藏,而覆盖的条件非常严格。函数名、形参表、const必须一致,返回值也要一致(基本类型)或相符(类类型的指针或引用)。 编译器遇到通过指向子类对象的基类指针调用基类中的虚函数时,与普通函数的处理不同,不会立刻生成调用代码,而会生成若干条指令,待程序运行时被执行。 运行时执行如下动作: 1. 根据基类指针指向的对象类型,找到目标对象中的虚函数表... 阅读全文

posted @ 2013-11-21 23:58 4IT 阅读(133) 评论(0) 推荐(0)

2013年11月20日

算法复习(3)二分查找

摘要: 二分查找是减而治之的典型。 将一个规模较大的问题,划分为规模较小的两个问题来解决。 第一次方法:将问题平分,遇到比中点小或比中点大继续递归,遇到等于中点直接返回。因为两个分支的比较次数不同,这种等分其实是不平衡的。 第二种方法:将问题按照斐波那契数进行分割,使需要比较次数少的分支子问题的规模比比较次数多的大。这样实质上对二分查找进行了平衡。 第三种方法:将问题严格平分,将中点划入一个分支中。这样使两个分支的比较次数相同,实现平衡。这种方法的缺点是遇到中点需要继续比较划分下去,直到最后。并且这种方法需要在规模非常庞大的时候才能看出效果。 阅读全文

posted @ 2013-11-20 23:25 4IT 阅读(149) 评论(0) 推荐(0)

导航