C/C++每天积累一点点
文章平均质量分 65
池塘的蜗牛
这个作者很懒,什么都没留下…
展开
-
左移和右移运算符
在C语言中,左移和右移运算符在比较某些位置时特别有用,所以今天将其做一总结:左移运算符 左移运算符右移运算符 >> 是变量每一位向右移动,移出的低位丢失。如果为正数左边补0,如果为负数:1,高位补0为逻辑右移。2高位补1为为算术右移。不同编译器不同,vc下默认补1。当然对于上述内容大家都已经知晓,如果这么简单那这篇博客便没有任何意义,下面先看一个例子。#include原创 2013-09-29 22:29:48 · 900 阅读 · 0 评论 -
三种不同的错误处理方式
1,通常我们有三种方式把错误信息传递给调用者。第一种方式是通过返回值来告诉调用者是否出错。比如很多window 的API就是这个类型。linux内核代码中很多函数几乎都是以0表示调用成功,而返回不为0表示API调用过程中出错了。window中微软为不同的返回值定义了不同的返回值,调用者可以根据这些返回值判断出错的原因。这种方式最大的问题是使用不便,因为这种方式不能直接把计算结果返回给其它变量,同时原创 2013-10-23 18:33:11 · 344 阅读 · 0 评论 -
传说中的甲骨文面试题
下面的代码所分配的堆空间一样多吗?为什么?void f1(){ int* p = new int[100];}void f2(){ int* p[100]; for(int i=0; i<100; i++) p[i] = new int;}解答:这个题目其实隐含的考察了栈空间和堆空间的概念,如果你的答案是不一样多,原创 2013-10-23 21:22:24 · 1049 阅读 · 0 评论 -
三种不同的错误处理方式
1,通常我们有三种方式把错误信息传递给调用者。第一种方式是通过返回值来告诉调用者是否出错。比如很多window 的API就是这个类型。linux内核代码中很多函数几乎都是以0表示调用成功,而返回不为0表示API调用过程中出错了。window中微软为不同的返回值定义了不同的返回值,调用者可以根据这些返回值判断出错的原因。这种方式最大的问题是使用不便,因为这种方式不能直接把计算结果返回给其它变量,同时原创 2013-10-23 20:15:08 · 891 阅读 · 1 评论 -
再谈构造函数能不能为virtual
类中构造函数能不能为虚函数,我在我的另一个博客中已经做了一些解释,不过在遇到一些其他问题时总是不能做出很好的解释,所以这次我们再将其做一下讨论。前一篇博客中我已经解释过构造函数不能为虚函数:因为调用虚函数需要虚函数指针,而构造函数此时还没有被调用,还没有虚函数指针所以会出错。但是构造函数中能不能调用虚函数呢?答案是可以。但是我前面说过构造函数对对象进行初始化,因为构造函数还没有完成,所以仍原创 2013-11-10 16:38:03 · 1055 阅读 · 0 评论 -
C++的一大误区——深入解释直接初始化与复制初始化的区别
转载:http://blog.csdn.net/ljianhui/article/details/9245661不久前,在博客上发表了一篇文章——提高程序运行效率的10个简单方法,对于其中最后一点,多使用直接初始化,有很多读者向我提出了疑问,并写了一些测试程序,来说明直接初始化与复制初始化是同一件事。让我了解到大家对于直接初始化与复制初始化的区别的确是不太清楚,无可否认,那篇文章的例子用得转载 2013-12-17 22:02:14 · 583 阅读 · 0 评论 -
C++ explict与mutable
C++ explicit关键字的作用主要是用来修饰类的构造函数,表明该构造函数是显式的,禁止单参数构造函数的隐式转换。如果C++类的构造函数有一个参数,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象,如下面所示:class MyClass{public: MyClass(int num);}MyCla转载 2013-12-21 22:45:37 · 561 阅读 · 0 评论 -
深入浅出变长结构体
深入浅出变长结构体1、 问题的引出 项目中用到数据包的处理,但包的大小是不固定的,其长度由包头的2字节决定。比如如下的包头:88 0f 0a ob cd ef 23 00 。长度由头2个字节880f决定,考虑字节序,转为0f88,转为10进制3976个字节的包长度。 这个时候存储包的时候,一方面可以考虑设定包的大小固定:如4K=4*1024=40转载 2013-12-23 19:14:59 · 493 阅读 · 0 评论 -
C++的四种cast操作符的区别--类型转换
Q:什么是C风格转换?什么是static_cast, dynamic_cast 以及 reinterpret_cast?区别是什么?为什么要注意?A:转换的含义是通过改变一个变量的类型为别的类型从而改变该变量的表示方式。为了类型转换一个简单对象为另一个对象你会使 用传统的类型转换操作符。比如,为了转换一个类型为doubole的浮点数的指针到整型:代码:转载 2014-01-08 15:39:20 · 457 阅读 · 0 评论 -
如何开辟二维空间内存加强版
这篇帖子主要介绍二维空间内存,但是有些地方还不是很懂请大神指点。#include int ** Malloc( int m, int n){ int **p; p =(int **) malloc(sizeof(int*)*m); for(int i = 0; i< n; i++) { *(p+i) = (int*)malloc(sizeof(int *)*n); }原创 2013-10-24 17:40:13 · 591 阅读 · 0 评论 -
数据的存储位置
下一个题:问下面的程序输出什么,为什么?int main(){ char p[] = "hello,world"; char* p1 = "hello,world"; char* p2 = "hello,world"; printf("%d\n", p == p1); printf("%d\n", p2 == p1); print原创 2013-10-30 21:39:16 · 1004 阅读 · 1 评论 -
什么是copy-and-swap技术
What is the copy-and-swap idiom?注:红色括号为自己的注解,括号中没有翻译的是作者的注释比较简单直接引用,专有的词语直接引用。能力有限欢迎大家指正。原文地址:http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiomOverviewWhy do we need it?翻译 2014-02-24 19:53:55 · 1748 阅读 · 1 评论 -
c++内存中字节对齐问题详解
转载:http://www.cnblogs.com/nawind/articles/1339991.html一、什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排转载 2014-02-15 14:06:30 · 441 阅读 · 0 评论 -
C++应注意问题和经验体会二(String类的实现)
紧接着上一篇的 “第二点sizeof解释”这次从第三点开始3,C++中的赋值操作符参考:《剑指offer》《C++程序设计教程》注意点:1,返回值是否为该类型的引用,并在函数结束前返回实例自身引用(*this)。只有返回一个引用才可以允许连续赋值。否则如果函数的返回值是void,应用该赋值运算符将不可以连续赋值即:str1 = str2 = str3,这样将会编译不通过。2,是原创 2013-10-25 16:05:07 · 581 阅读 · 0 评论 -
解读:绝不重新定义继承而来的默认缺省参数
“绝不重新定义继承而来的默认缺省参数这句话来自于”《EffectiveC++》条款37。下面我们以一段代码开始我们的旅程.#include#include#includeclass Shap{public: virtual void print(int a = 1)=0; int c;};class Circle:public Shap{public:原创 2014-02-18 17:00:10 · 753 阅读 · 0 评论 -
malloc/free与new/delete的区别
相同点:都可用于申请动态内存和释放内存不同点:(1)操作对象有所不同。malloc与free是C++/C 语言的标准库函数,new/delete 是C++的运算符。对于非内部数据类的对象而言,光用maloc/free 无法满足动态对象的要求。对象在创建的同时要自动执行构造函数, 对象消亡之前要自动执行析构函数。由于malloc/free 是库函数而不是运算符,不在编译器控制权限之内转载 2014-01-11 22:17:08 · 533 阅读 · 0 评论 -
vector的内存扩展和释放
对于这道问题在每年的面试中都会提到,出现频率之高都已经到了令人发指的地步,所以在此做一总结。对于这部分知识据说《effective STL》中有详细介绍与代码实现。参考:《C++ primer》以及相关网络资源。1.vector容器的自增长vector中所有元素都是以连续的方式进行存储,原理就和数组一样每个元素相互紧挨着存储,但是当我们需要往其中insert元素时将会发生什么情况呢?原创 2014-03-18 10:58:11 · 1452 阅读 · 0 评论 -
C/C++变量在内存中的分布
转载:http://blog.csdn.net/morewindows/article/details/6851681C/C++变量在内存中的分布在笔试时经常考到,虽然简单,但也容易忘记,因此在这作个总结,以加深印象。先写一个测试程序:#include #include int g_i = 100; int g_j = 200; int g_k, g_h;转载 2013-10-27 13:05:35 · 394 阅读 · 0 评论 -
C/C++的声明和定义
变量的定义(definition):用于为变量分配存储空间,还可以为变量指定初始值。在一个程序中,变量有且仅有一个定义;变量的声明(declaration):用于向程序表明变量的类型和名字。定义也是声明:当定义变量时我们声明了它的类型和名字。可以通过使用extern关键字声明变量名而不定义它。有分配空间的叫定义,没分配空间的叫声明。 另外,“定义”的同时一定耦合转载 2013-10-26 13:31:33 · 535 阅读 · 0 评论 -
几个复杂指针的讨论
今天突然想到了这几指针的问题,其中正确的用法我已经给出,敬请各位大神指导讨论其深层次的含义,欢迎拍砖#includevoid main(){ int a[] = {1,2,3}; int *p2 = a; //正常情况 int *p1 = (int*)(&a +1); //将其强制转换为一维数组指向数组末尾,并不是最后一个元素 int (*p)[3] =&a; //和二维数原创 2013-09-23 15:10:44 · 131 阅读 · 0 评论 -
几个复杂指针的讨论
今天突然想到了这几指针的问题,其中正确的用法我已经给出,敬请各位大神指导讨论其深层次的含义,欢迎拍砖#includevoid main(){ int a[] = {1,2,3}; int *p2 = a; //正常情况 int *p1 = (int*)(&a +1); //将其强制转换为一维数组指向数组末尾 int (*p)[3] =&a; //和二维数组赋值类似 p原创 2013-09-23 15:17:45 · 130 阅读 · 0 评论 -
C与C++分别实现位图操作
位图操作在数据量很大时,标记某些数据出现与否很有用,能够很大程度上节俭内存所以用处很广。对于大部分人来说其概念已经很熟悉,所以在此不再多做解释。此篇博文主要是将位图操作的C与C++操作呈现给大家。C中位图没有自己定义的函数所以必须自己书写,但在C++中已经存在位图操作函数,所以我们在此只做介绍如何使用。#define MAX 1000000#define SHIFT 5原创 2013-09-22 23:13:11 · 769 阅读 · 0 评论 -
函数参数的压栈方式
函数参数的压栈方式:从左至右这个大家都知道可是怎么应用呢??先来看一个企鹅的面试题。#includevoid main(){ long long a = 1; long long b = 2; long long c = 3; printf("%d%d%d",a,b,c);}(小端模式)输出为1,0,2由与从左至右压栈一个框表示一个字节。先取下面四个字节为1,原创 2013-10-09 21:23:53 · 1108 阅读 · 0 评论 -
析构函数什么有时候一定需要为virtual型
1,虚函数什么时候需要为virtual型。我们先来看一个程序:#includeusing namespace std;class A{public: A(){ cout << "construct BASE"<<endl;} ~A() {cout << "Destruct BASE"<<endl;}};class B:public A{public: B(){c原创 2013-09-26 16:05:36 · 482 阅读 · 0 评论 -
C++内存管理
1.1 C++内存管理详解1.1.1 内存分配方式1.1.1.1 分配方式简介 在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。 栈,在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 堆,就是那些转载 2013-09-24 21:37:50 · 544 阅读 · 0 评论 -
静态成员函数与变量
当将类的某个数据成员声明为static时,该静态数据成员只能被定义一次,而且要被同类的所有对象共享。各个对象都拥有类中每一个普通数据成员的副本,但静态数据成员只有一个实例存在,与定义了多少类对象无关。静态方法就是与该类相关的,是类的一种行为,而不是与该类的实例对象相关。 静态数据成员的用途之一是统计有多少个对象实际存在。 静态数据成员不能在类中初始化,实际上类定义只是在转载 2013-09-24 20:34:57 · 503 阅读 · 0 评论 -
strcpy和memcpy的实现
进来很多面试题都会考到strcpy和memcpy的实现,所以在学习之余我将其做一整理:1,首先是memcpy:void* memcpy(void *dst, const void *src, size_t count) { //安全检查 assert( (dst != NULL) && (src != NULL) );原创 2013-09-25 22:49:32 · 632 阅读 · 0 评论 -
阿里巴巴北邮站一道面试题的解析
问题:设计一个最有算法来查找一个长度为n的数组的最大值和最小值,一知一种需要2n次比较的算法,请给出一个更优算法,请特别注意优化时间复杂度的常数。void find(int a[],int len){ int min = a[0]; int max = a[0]; for(int i = 1; i < len; i++) { if(a[i] >= max) {原创 2013-09-25 12:11:44 · 201 阅读 · 0 评论 -
二叉树的非递归调用
二叉树的非递归遍历 二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的。对于二叉树,有前序、中序以及后序三种遍历方法。因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁。而对于树的遍历若采用非递归的方法,就要采用栈去模拟实现。在三种遍历中,前序和中序遍历的非递归算法都很容易实现,非递归后序遍历实现起来相对转载 2013-09-26 16:25:50 · 537 阅读 · 0 评论 -
int main(int argc, char *argv[])解析
可能我的实践还不够,不知道老外写东西为什么总喜欢将main函数写成 int main(int argc, char *argv[]),再加上最近师弟问过我这个问题,所以今天将其学习后,呈现给大家。argc这个变量存储的是你函数输入的变量个数,argv是一个数组指针,argv[0]存储的是你可执行程序的名称,从argv[1]....往后就是输入的变量。#include#include原创 2013-09-28 11:00:06 · 538 阅读 · 0 评论 -
字符与数字之间的转换
字符和数字之间的转换非常常用,例如将字符串转换为整数或者将整数转换为字符串等。。。这些都需要字符与数字之间的装换。如果将数字转换为字符则只需给其加上‘0’,反之减去字符‘0’;这个很重要。很多人认为 ‘1’ 和 1一样其实不然。因为计算机种都已ASSCII码存在,两者之间的ASSCII并不相同所以需要一定的转换。#includevoid main(){ int a = 1; c原创 2013-10-15 17:06:23 · 1350 阅读 · 0 评论 -
C语言函数名与函数指针详解
转载:http://see.xidian.edu.cn/cpp/html/496.html 一个通常的函数调用的例子:/* 自行包含头文件 */void MyFun(int x); /* 此处的声明也可写成:void MyFun(int) */int main(int argc, char* argv[]){ MyFun(10); /* 这里是调用MyFun(10转载 2013-10-24 21:44:58 · 467 阅读 · 0 评论 -
条件编译详解
预处理过程扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器。可见预处理过程先于编译器对源代码进行处理。 在C 语言中,并没有任何内在的机制来完成如下一些功能:在编译时包含其他源文件、定义宏、根据条件决定编译时是否包含某些代码。要完成这些工作,就需要使用预处理程序。尽管在目前绝大多数编译器都包含了预处理程序,但通常认为它们是独立于编译器的。预处理过程读入源代码,检查包含预处理指令转载 2013-10-24 21:59:42 · 441 阅读 · 0 评论 -
C++应注意问题和经验体会一
本篇文章属于连载文章,每当我想到一个知识点或者有经验体会时就会将其添加进来,帮助自己学习。1.C++内部对象初始化顺序。C++内部对象初始化顺序是按照声明的次序而不是调用次序,并且静态成员只有只有一个副本且只会初始化一次。下面我们给出一个例子。 #includeusing namespace std;class A{public: int x; int y; A(原创 2013-10-16 10:47:34 · 591 阅读 · 0 评论 -
extern C的作用详解
extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般之包括函数名。 这个功能十分有转载 2014-05-09 10:46:42 · 374 阅读 · 0 评论