您好,欢迎访问三七文档
编程规范—第二讲变量与类型软件工程系变量和类型是程序的基础,也是编程中容易忽视的地方。本节将学习变量和类型的相关概念和编程陷阱。实用经验5:计算机是怎么存储变量的?实用经验6:确保每个对象在使用前已被初始化。实用经验7:掌握局部变量和全局变量的区别实用经验8:掌握变量定义的位置与时机。实用经验9:合理使用引用实用经验13:typedef使用的陷阱实用经验16:提防隐式转换带来的麻烦实用经验17:深刻理解void和void*实用经验18:如何判定变量是否相等?5:计算机如何存储变量•数据在内存中放置考虑两个问题:−放在哪里:数据存储区域−以什么格式存放:数据放置的格式。思考:什么情形应该用到全局变量和静态变量,两者有什么区别什么时候应该用到new/delte?•数据存储区域可分为:−只读/静态存储区:存储常量和恒值;−全局静态存储区:全局变量和静态变量−自由存储区:CRT(C运行时库)通过malloc\free函数管理的内存。与堆区同一种管理方式,统称为堆区。−栈区:数据由编译器自动分配释放,主要存放函数的参数值、局部变量等。−堆区:存放new分配的内存块,编译器不负责他们的释放。堆区分配数据节省空间,使用方便。堆区分配和释放内存会造成内存空间的不连续,形成大量的碎片。程序效率降低。分配的数据如果没有释放,很容易造成内存泄露。5:计算机如何存储变量intg_init_var=100;intg_uninit_var;voidFunc(inti){coutiendl;}intmain(){staticintstatic_var=101;staticintstatic_var2;intnNumber=1;intnMumberB;intnMumberC;Func(static_var+static_var2+nNumber+nMumberB);char*pszstrLG=liuguang;char*pszStr2=newchar;deletepszStr2;int*pnMumber=static_castint*(malloc(sizeof(int)));int*pnMumber2=static_castint*(malloc(100));free(pnMumber);cout&g_init_var&g_uninit_varendl;cout&static_var&static_var2endl;cout&nNumber&nMumberB&nMumberCendl;cout(void*)pszstrLG(void*)pszStr2pnMumberpnMumber2endl;return0;}5:计算机如何存储变量#includeiostreamusingnamespacestd;intmain(){longfac(intn);intn;longy;coutinputanintegernumber:;cinn;y=fac(n);coutn!=yendl;return0;}longfac(intn){intcount=0;count++;cout递归次数:count&countendl;longf;if(n0)coutn0,dataerror!;elseif(n==0||n==1)f=1;elsef=fac(n-1)*n;return(f);}Count定义为局部变量结论:count定义为局部变量不能累计出递归次数因为局部变量存放在栈区,生存期从变量定义开始,到变量所在函数结束即释放空间。结果分析:调用f(3)count值从0累计至1,函数f(3)结束地址被释放调用f(2)count重新声明空间count值仍从0累计至1,函数f(2)结束地址被释放调用f(1)count重新声明空间count值仍从0累计至1,函数f(1)结束地址被释放5:计算机如何存储变量#includeiostreamusingnamespacestd;intmain(){longfac(intn);intn;longy;coutinputanintegernumber:;cinn;y=fac(n);coutn!=yendl;return0;}longfac(intn){staticintcount=0;count++;cout递归次数:count&countendl;longf;if(n0)coutn0,dataerror!;elseif(n==0||n==1)f=1;elsef=fac(n-1)*n;return(f);}Count定义为静态局部变量结论:count定义为静态局部变量可以累计出递归次数。因为静态局部变量存放在全局区,生存期从变量定义开始,到程序结束释放空间。结果分析:调用f(3)count值从0累计至1,函数f(3)结束,地址不释放值1保留调用f(2)count值从1累计至2,函数f(2)结束,地址不释放值2保留调用f(1)count值仍从2累计至3,函数f(1)结束5:计算机如何存储变量#includeiostreamusingnamespacestd;staticintcount=0;//静态全局变量intmain(){longfac(intn);intn;longy;coutinputanintegernumber:;cinn;y=fac(n);coutn!=yendl;coutcount=count&countendl;return0;}longfac(intn){count++;longf;if(n0)coutn0,dataerror!;elseif(n==0||n==1)f=1;elsef=fac(n-1)*n;return(f);}结论:count定义为静态全局部变量可以累计出递归次数。因为静态全局变量存放在全局区,生存期从变量定义开始,到程序结束释放空间。静态局部变量静态全局变量相同:生存期都比较长不同:静态局部变量作用域比较小,只能在fac(intn)内使用静态全局变量作用域稍大,能在定义该变量的文件内使用Count定义为静态全局变量5:计算机如何存储变量•//f.h#includeiostream#includeiomanipusingnamespacestd;longfac(intn);•//f.cpp#includef.hintcount=0;//全局变量定义,定义//全局变量说明longfac(intn){count++;longf;if(n0)coutn0,dataerror!;elseif(n==0||n==1)f=1;elsef=fac(n-1)*n;return(f);}#includef.hexternintcount;//全局变量说明intmain(){longfac(intn);intn;longy;coutinputanintegernumber:;cinn;y=fac(n);coutn!=yendl;coutcount=count&countendl;return0;}•//main.cpp静态全局变量与全局变量比较相同:生存期都比较长不同:静态全局变量作用域比较大,能在定义该变量的文件内使用。全局变量作用域更大,能在定义该变量的应用程序的所有文件中使用(但使用需要说明)5:计算机如何存储变量总结:静态局部变量;静态全局变量;全局变量都能累计递归次数局部变量;不能累计递归次数原因分析:静态局部变量;静态全局变量;全局变量都存放在静态/全局存储区,存放在存储区的变量生存期比较长,能长期占用内存的同一块地址,存放累计结果:0-1-2-3-4……局部变量存放在栈区某存放在该区域的变量生存期都比较短,不能长期占用内存的同一块地址存放累结果:0-1释放0-1释放0-1……5:计算机如何存储变量•数据放置的格式:−整型值−整数,int\short\long类型都表示整型值,不同之处是存储变量所占的内存空间大小不同,计算机按位序列存储数据,8位一个字节,一个字节和一个称为地址的数关联起来,并且需要知道存在该地址的值的类型。−字符型char基本字符集;wchar_t扩展字符集−布尔值算术类型。Bool类型表示true(非0)和false(0)。−浮点型−单精度(32:1+8+23−双精度(64:1+11+52)两类三部分符号位、指数位、尾数部分浮点计算,三部分必须是二进制形式。5计算机如何存储变量A.变量在不同语境下,其分配内存区域是不同:−静态变量和全局变量一般分布在全局/静态存储区−函数的参数和变量一般分配在栈中−new和malloc申请的数据一般分配在堆中。B.变量使用时注意:−变量在定义和初始化时,一定要注意其取值范围;(以防出现数据截断异常现象)−数据在使用过程中应禁止降级强制转换;(以防种降低数据的精度)Tips:6:确保每个对象在使用前已被初始化•对象在使用前是否会被初始化是无法确定的如:Pt的成员变量有时会被初始化为0,有时不会•最佳的处理方式就是:永远在变量被使用之前将它初始化−内置数据类型,必须手动完成初始化。如:int=5;char*pszString=“acstring”−内置类型以外的其他成员,对象的构造函数完成初始化classCPoint{public:intm_iX;intm_iY;};intmain(){CPointpt;coutpt.m_iXendl;return0;}读取未初始化的对象会导致不确定的行为6确保每个对象在使用前已被初始化•最佳的处理方式就是:永远在变量被使用之前将它初始化−内置类型以外的其他成员,对象的构造函数完成初始化typedefenumtagsex{MALE_SEX=0,FEMALE_SEX=1,}Sex;classCPerson{public:stringm_strName;Sexm_sex;CPerson(stringstrName,Sexsex);};CPerson::CPerson(stringstrName,Sexsex){m_strName=strName;m_sex=sex;}intmain(){CPersonc1(lucy,MALE_SEX);coutc1.m_strNamec1.m_sexendl;return0;}typedefenumtagsex{MALE_SEX=0,FEMALE_SEX=1,}Sex;classCPerson{public:stringm_strName;Sexm_sex;CPerson(stringstrName,Sexsex);};CPerson::CPerson(stringstrName,Sexsex):m_strName(strName),m_sex(sex){}intmain(){CPersonc1(lucy,MALE_SEX);coutc1.m_strNamec1.m_sexendl;return0;}复制初始化:之前需调用默认构造函数,效率低列表初始化:无需调用默认构造函数,效率高,且常成员只能用列表初始化声明次序决定初始化新婚许列表次序应与声明次序一致6确保每个对象在使用前已被初始化•Tips:•为内置类型对象进行手动初始化,因为C++不保证初始化它们。•构造函数最好使用成员初始化列表,而不是在构造函数本体内使用赋值操作。初值列表列出的成员变量,其排列顺序应和它们在class中的声明次序相同。7局部变量和全局变量的差别变量一般包括4种:全局变量,静态全局变量,静态局部变量,和局部变量。按照存储区域分:全局变量,静态全局变量,静态局部变量都存放在内存的静态存储区,局部变量存放在内存的栈区。按照作用域分:–全局变量在整个工程文件内都
本文标题:第2讲变量与数据.
链接地址:https://www.777doc.com/doc-2155339 .html