




已阅读5页,还剩15页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1程序的内存分配1、栈区(stack) 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。2、堆区(heap) 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。3、全局区(静态区)(static),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 4、文字常量区常量字符串就是放在这里的。 程序结束后由系统释放5、程序代码区存放函数体的二进制代码。二、例子程序 这是一个前辈写的,非常详细 /main.cpp int a = 0; 全局初始化区 char *p1; 全局未初始化区 main() int b; 栈 char s = abc; 栈 char *p2; 栈 char *p3 = 123456; 1234560在常量区,p3在栈上。 static int c =0; 全局(静态)初始化区 p1 = (char *)malloc(10); p2 = (char *)malloc(20); 分配得来得10和20字节的区域就在堆区。 strcpy(p1, 123456); 1234560放在常量区,编译器可能会将它与p3所指向的123456优化成一个地方。 2、Const和static区别对于C/C+语言来讲,const就是只读的意思,只在声明中使用;static一般有2个作用,规定作用域和存储方式.对于局部变量,static规定其为静态存储方式,每次调用的初始值为上一次调用的值,调用结束后存储空间不释放;对于全局变量,如果以文件划分作用域的话,此变量只在当前文件可见;对于static函数也是在当前模块内函数可见.static const 应该就是上面两者的合集.下面分别说明:全局:const,只读的全局变量,其值不可修改.static,规定此全局变量只在当前模块(文件)中可见.static const,既是只读的,又是只在当前模块中可见的.文件:文件指针可当作一个变量来看,与上面所说类似.函数:const,返回只读变量的函数.static,规定此函数只在当前模块可见.类:const,一般不修饰类,(在VC6.0中试了一下,修饰类没啥作用)static,C+中似乎没有静态类这个说法,一般还是拿类当特殊的变量来看.C#中有静态类的详细说明,且用法与普通类大不相同. 3new delete 和malloc free的区别malloc与free是C+/C语言的标准库函数,new/delete是C+的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。 因此C+语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。4main() int x=10,y=10,i; for (i=0;x8;y=+i) printf(%d %d ,x-,y); 在循环语句for(表达式1;表达式2;表达式3)中,先执行表达式一,再执行表达式二,如果表达式二成立,就进入循环,第一次循环执行完后(本程序共两次循环),才执行表达式三(这是表达式三第一次被执行),然后再执行表达式二,看其是否成立,如果成立,就进行第二次循环。如此循环,表达式一只在第一次循环时执行,以后不再执行,表达式三在第一次循环不执行,以后的每次循环都执行。如果你要这是为什么,我只能说这是规定,别的就不知道了。 5什么是静态成员变量 在C+类的成员变量被声明为static(称为静态成员变量),意味着它为该类的所有实例所共享,也就是说当某个类的实例修改了该静态成员变量,其修改值为该类的其它所有实例所见。 比如在某个类A中声明一个static int number;初始化为0。这个number就能被所有A的实例共用。在A的构造函数里加上number+,在A的析构函数里加上number-。那么每生成一个A的实例,number就加一,每销毁一个A的实例,number就减一,这样,number就可以记录程序中共生成了多少个A的实例。 这只是静态成员的一种用法而已。6静态数据成员和静态成员函数在程序中是如何声明和定义的class Foopublic: static int a; stataic void func();静态数据成员和函数都是在声明前加static静态成员必须要在类外初始化,无法在构造函数内初始化。新标准的C+也允许在生命静态数据成员的是后直接加等于号进行初始化,但是大部分编译器不支持。所以最保险的办法就是在类定义的外面再写:int Foo:a = 0;注意,这时候不需要再static了。函数则很普通成员函数的声明以及实现没区别,唯一要注意的是,静态函数是没有this指针的,因此不能访问任何非静态的其他成员函数或成员变量,如果要访问需要传递this指针进去,比如class Foopublic: int a; static void func(Foo* ptrFoo) a = 0; / 错误!a不是静态变量,无法访问! ptrFoo-a= 0; /正确。 void test() / 非静态成员函数调用静态成员函数可以传递this指针,让静态成员函数通过他来访问 / 其他成员函数和成员变量。 Foo:func(this); 7虚函数和纯虚函数区别虚函数和纯虚函数在面向对象的C+语言中,虚函数(virtualfunction)是一个非常重要的概念。因为它充分体现了面向对象思想中的继承和多态性这两大特性,在C+语言里应用极广。比如在微软的MFC类库中,你会发现很多函数都有virtual关键字,也就是说,它们都是虚函数。难怪有人甚至称虚函数是C+语言的精髓。那么,什么是虚函数呢,我们先来看看微软的解释:虚函数是指一个类中你希望重载的成员函数,当你用一个基类指针或引用指向一个继承类对象的时候,你调用一个虚函数,实际调用的是继承类的版本。摘自MSDN这个定义说得不是很明白。MSDN中还给出了一个例子,但是它的例子也并不能很好的说明问题。我们自己编写这样一个例子:includestdio.hincludeconio.hclassParentpublic: chardata20; voidFunction1(); virtualvoidFunction2();/这里声明Function2是虚函数parent;voidParent:Function1() printf(Thisisparent,function1n);voidParent:Function2() printf(Thisisparent,function2n);classChild: publicParent voidFunction1(); voidFunction2();child;voidChild:Function1() printf(Thisischild,function1n);voidChild:Function2()printf(Thisischild,function2n);intmain(intargc,char*argv) Parent*p;/定义一个基类指针 if ( _getch()=c )/如果输入一个小写字母c p=&child;/指向继承类对象 else p=&parent;/否则指向基类对象 p-Function1();/这里在编译时会直接给出Parent:Function1()的入口地址。 p-Function2();/注意这里,执行的是哪一个Function2? return0;用任意版本的VisualC+或BorlandC+编译并运行,输入一个小写字母c,得到下面的结果:Thisisparent,function1Thisischild,function2为什么会有第一行的结果呢?因为我们是用一个Parent类的指针调用函数Fuction1(),虽然实际上这个指针指向的是Child类的对象,但编译器无法知道这一事实(直到运行的时候,程序才可以根据用户的输入判断出指针指向的对象),它只能按照调用Parent类的函数来理解并编译,所以我们看到了第一行的结果。那么第二行的结果又是怎么回事呢?我们注意到,Function2()函数在基类中被virtual关键字修饰,也就是说,它是一个虚函数。虚函数最关键的特点是“动态联编”,它可以在运行时判断指针指向的对象,并自动调用相应的函数。如果我们在运行上面的程序时任意输入一个非c的字符,结果如下:Thisisparent,function1Thisisparent,function2请注意看第二行,它的结果出现了变化。程序中仅仅调用了一个Function2()函数,却可以根据用户的输入自动决定到底调用基类中的Function2 还是继承类中的Function2,这就是虚函数的作用。我们知道,在MFC中,很多类都是需要你继承的,它们的成员函数很多都要重载,比如编写MFC应用程序最常用的CView:OnDraw(CDC*)函数,就必须重载使用。把它定义为虚函数(实际上,在MFC中OnDraw不仅是虚函数,还是纯虚函数),可以保证时刻调用的是用户自己编写的OnDraw。虚函数的重要用途在这里可见一斑。再看下面的-上一篇:为何析构函数中的cout不起作用下一篇:菱形虚拟继承后,派生类的大小问题C+中虚函数和纯虚函数的概念,差别和分别存在的原因摘自:C+中虚函数和纯虚函数的概念,差别和分别存在的原因首先:强调一个概念定义一个函数为虚函数,不代表函数为不被实现的函数定义他为虚函数是为了允许用基类的指针来调用子类的这个函数定义一个函数为纯虚函数,才代表函数没有被实现定义他是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。8请教C+深拷贝与浅拷贝区别并详细说一下如何应用浅拷贝就是对象的数据成员之间的简单赋值,如你设计了一个没有类而没有提供它的复制构造函数,当用该类的一个对象去给令一个对象赋值时所执行的过程就是浅拷贝,如:class Apublic:A(int _data) : data(_data)A()private:int data;int main()A a(5), b = a; / 仅仅是数据成员之间的赋值这一句b = a;就是浅拷贝,执行完这句后b.data = 5;如果对象中没有其他的资源(如:堆,文件,系统资源等),则深拷贝和浅拷贝没有什么区别,但当对象中有这些资源时,例子:class Apublic:A(int _size) : size(_size)data = new intsize; / 假如其中有一段动态分配的内存A();A()delete data; / 析构时释放资源private:int* data;int size;int main()A a(5), b = a; / 注意这一句这里的b = a会造成未定义行为,因为类A中的复制构造函数是编译器生成的,所以b = a执行的是一个浅拷贝过程。我说过浅拷贝是对象数据之间的简单赋值,比如:b.size = a.size;b.data = a.data; / Oops!这里b的指针data和a的指针指向了堆上的同一块内存,a和b析构时,b先把其data指向的动态分配的内存释放了一次,而后a析构时又将这块已经被释放过的内存再释放一次。对同一块动态内存执行2次以上释放的结果是未定义的,所以这将导致内存泄露或程序崩溃。所以这里就需要深拷贝来解决这个问题,深拷贝指的就是当拷贝对象中有对其他资源(如堆、文件、系统等)的引用时(引用可以是指针或引用)时,对象的另开辟一块新的资源,而不再对拷贝对象中有对其他资源的引用的指针或引用进行单纯的赋值。如:class Apublic:A(int _size) : size(_size)data = new intsize; / 假如其中有一段动态分配的内存A();A(const A& _A) : size(_A.size)data = new intsize; / 深拷贝A()delete data; / 析构时释放资源private:int* data;int size;int main()A a(5), b = a; / 这次就没问题了总结:深拷贝和浅拷贝的区别是在对象状态中包含其它对象的引用的时候,当拷贝一个对象时,如果需要拷贝这个对象引用的对象,则是深拷贝,否则是浅拷贝嵌入式篇1结构体位制,内存对齐 05 #include 06 07 typedef struct _A08 09 unsigned a:4;/位段成员的类型仅能够为unsigned或者int10 unsigned b:4;11 unsigned c:2;12 unsigned d:6;13 unsigned E:1;14 unsigned D:2;15 unsigned T:3;16 unsigned A:9;17 unsigned h:4; /前面已经为31,故4+3132已超过一个存储单元,所以4在一个新的存储单元存放18 unsigned y:29;/由于前面的4在一个新的存储单元的开头存放,且29+432, 故在另一个新的存储单元存放19 A; /所以最后求出的A的大小是4 + 4 + 4 =1220 21 /*对上面的具体解释: 一个位段必须存储在同一个存储单元中,不能跨两个单元.如果某存储单元空间中不能容纳下一个位段,则改空间不用,而从下一个存储单元起存放该位段. 结构体A中的h和y就是这种情况.在gcc环境下,测试后,一个存储单元为4个字节.24 */25 26 typedef struct _S27 28 unsigned a:4;29 unsigned b:4;30 unsigned c:22;31 unsigned q:1;32 unsigned h:1;33 /unsigned i:33; / 错误:i 的宽度超过它自身的类型34 /unsigned i:1;当多出此行时,该结构体大小由4变为8,因为此行之前正好为32位35 S;36 37 typedef struct _T38 /当没有占满一个存储单元时,结构体的大小对齐为一个存储单元的大小39 unsigned a:2;40 unsigned b:2;41 unsigned j:1;42 unsigned : 1;/可以定义无名位段,此例中该无名位段占用1位的空间,该空间将不被使用43 T;44 45 typedef struct _V46 47 unsigned a:1;48 unsigned b:4;49 unsigned :0; /定义长度为0的位段时不能指定名字,否则编译不过50 unsigned d:1; /定义了0字段后,紧接着的下一个成员从下一个存储单元开始存放;51 V;2语言auto定义变量#includestdio.hvoid mian() int i,num; num=2; for(i=0;i3;i+) printf(The num equal %dn,num); num+; auto int num=1; printf(The internal block num equal %dn,num); num+; 执行结构为:The num equal 2The internal block num equal 1The num equal 3The internal block num equal 1The num equal 4The internal block num equal 1请问结果为什么是那样啊在函数内部定义的变量成为局部变量。在某些C语言教材中,局部变量称为自动变量,这就与使用可选关键字a u t o定义局部变量这一作法保持一致。局部变量仅由其被定义的模块内部的语句所访问。换言之,局部变量在自己的代码模块之外是不可知的。切记:模块以左花括号开始,以右花括号结束。对于局部变量,要了解的最重要的东西是:它们仅存在于被定义的当前执行代码块中,即局部变量在进入模块时生成,在退出模块时消亡。定义局部变量的最常见的代码块是函数。 auto int num=1;num=1 printf(The internal block num equal %dn,num);num=1输出The internal block num equal 1 num+;num=2 这个区域又是一个模块,里面num的对外部num的不影响二叉树的操作 #include typedef struct BiTNodechar data;int bit;struct BiTNode *lchild,*rchild,*parent;BiTNode;void InitBT(BiTNode *&t)/1、初始化,不带头结点t=NULL;/*void InitBT(BiTNode *t)/初始化,带头结点t=new BiTNode;t-lchild=t-rchild=t-parent=NULL;*/int EmptyBT(BiTNode *t)/判断队空if(t=0)return 1;elsereturn 0;BiTNode *creatBT(BiTNode *t,int b)/2、创建二叉树BiTNode *p;char ch;cinch;if(ch=#)return 0;elsep=new BiTNode;p-data=ch;p-parent=t;p-bit=b;t=p;t-lchild=creatBT(t,0);t-rchild=creatBT(t,1);return t;void preorder(BiTNode *t)/3、先序遍历if(!EmptyBT(t)coutdata;preorder(t-lchild);preorder(t-rchild);void inorder(BiTNode *t)/中序遍历if(!EmptyBT(t)inorder(t-lchild);coutdata;inorder(t-rchild);void postorder(BiTNode *t)/后序遍历if(!EmptyBT(t)postorder(t-lchild);postorder(t-rchild);coutdata;void coutBT(BiTNode *t,int &m,int &n,int &i)/4、计算二叉树中叶子结点、度为2的结点和度为1的结点的个数if(!EmptyBT(t)if(t-lchild=0) & (t-rchild=0)m+;/叶子结点else if(t-lchild!=0) & (t-rchild!=0)i+;/度为2的结点elsen+;/度为1的结点coutBT(t-lchild,m,n,i);coutBT(t-rchild,m,n,i);void coutNode(BiTNode *t,int &k)/5、求二叉树中结点个数if(!EmptyBT(t)k+;coutNode(t-lchild,k);coutNode(t-rchild,k);int BTdepth(BiTNode *t)/6、求二叉树的深度int i,j;if(EmptyBT(t)return 0;elsei=BTdepth(t-lchild);j=BTdepth(t-rchild);return (ij?i:j)+1;int Xdepth(BiTNode *t,char x)/7、查找x的层数int num1,num2,n;if(t=NULL)return 0;elseif(t-data=x)return 1;num1=Xdepth(t-lchild,x);num2=Xdepth(t-rchild,x);n=num1+num2;if(num1!=0|num2!=0)n+;return n;static int flag;void SearchChild(BiTNode *t,int k)/8、查找第k个结点的左右孩子if(!EmptyBT(t)if(k=0)cout位置不能为0!lchild=0)cout无左孩子! ;elsecout左孩子为:lchild-data)rchild=0)cout无右孩子!endl;elsecout右孩子为:rchild-data)lchild,k);SearchChild(t-rchild,k);int Xancestor(BiTNode *t,char x)/9、查找x结点祖先int n,num1,num2;if(t=NULL)return 0;elseif(t-data=x)return 1;num1=Xancestor(t-lchild,x);num2=Xancestor(t-rchild,x);n=num1+num2;if(n!=0)n+;coutdata lchild=0) & (t-rchild=0)coutdataparent)coutdata;coutlchild);BTNodePath(t-rchild);void BTNodebit(BiTNode *t)/11、输出所有叶子结点编码if(!EmptyBT(t)if(t-lchild=0) & (t-rchild=0)coutdataparent!=0;p=p-parent)coutbit;coutlchild);BTNodebit(t-rchild);void main()BiTNode *t;int m,n,i,d,q,k;char x;cout1、初始化.endl;InitBT(t);cout2、创建二叉树.endl;t=creatBT(t,0); cout3.1、先序遍历.endl;preorder(t);coutendl;cout3.2、中序遍历.endl;inorder(t);coutendl;cout3.3、后序遍历.endl;postorder(t);coutendl;m=n=i=0;cout4、计算叶子结点,度为1的结点和度为2的结点的个数.endl;coutBT(t,m,n,i);cout叶子结点个数为:mendl;cout度为1的结点个数为:nendl;cout度为2的结点个数为:iendl;q=0;cout5、计算结点个数.endl;coutNode(t,q);cout结点个数为:qendl;d=0;cout6、计算深度.endl;d=BTdepth(t);cout深度为:dendl;cout7、求x的层数.endl;coutx;if(Xdepth(t,x)=0)coutx不存在!endl;elsecoutXdepth(t,x)endl;coutk;SearchChild(t,k);if(kflag)cout位置超出长度!endl;coutx;int num;num=Xancestor(t,x);if(num=0)cout结点不存在!endl;if(num=1)cout根结点无祖先!endl; cout10、输出所有叶子结点路径(叶根):endl;BTNodePath(t);cout11、输出所有叶子结点编码
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 服装定制上门服务创新创业项目商业计划书
- 自动驾驶车辆车队管理系统创新创业项目商业计划书
- 淡水蛙养殖基地创新创业项目商业计划书
- 老年应用关怀站创新创业项目商业计划书
- 2025年昆明润城学校秋季学期教育人才招聘(11人)备考考试题库附答案解析
- 2025-2030肉牛养殖智能化转型趋势及商业模式创新与融资渠道研究
- 2025天津新金融投资有限责任公司及所属企业招聘工作人员备考考试试题及答案解析
- 2025-2030羊肉行业信用体系建设与供应链金融创新及风险控制报告
- 2025-2030羊肉品质检测技术升级与溯源体系建设前景报告
- 2026届安徽省宣城市宣州区狸桥中学九年级化学第一学期期末达标检测试题含解析
- 2022-2023学年六年级数学上册第一单元分数乘法拓展卷(含答案)
- 血站服务礼仪培训课件
- 2025年iptv技术考试题库
- 科室医院感染管理制度
- 检验科科室管理制度
- 学科交叉教学中存在的问题及改进措施
- 山东中专学籍管理办法
- 老年营养健康宣教
- 2025-2026年部编版语文六年级上册教学工作计划(含进度表)
- 胰腺炎超声诊断表现
- 精神科专科监护技能课件
评论
0/150
提交评论