赞
踩
1、静态成员特点
1)对于非静态成员,每个类对象都有自己的复制品。被static修饰的成员变量和成员方法独立于该类的任何对象,只有一份复制品。也就是说,它不依赖类特定的实例,被类的所有实例共享。
2)静态数据成员存储在全局数据区,在定义时要分配空间,故不能在类声明中定义。由于静态数据成员属于本类的所有对象共享,所以,它不属于特定的类对象,在没有产生类对象时其作用域就可见,即在没有产生类的实例时,程序员也可以使用它。
3)静态数据成员和普通数据成员 一样遵循从public、protected、private 访问规则。static变量前有private修饰,表示这个变量可以在类的静态代码块中,或者类的其他静态成员方法中使用(当然也可以在非静态成员方法中使用),但是不能在其他类中通过类名来直接引用。实际上你需要搞明白,private是访问权限限定,static表示不要实例化就可以使用,这样就容易理解多了。static前面加上其它访问权限关键字的效果也以此类推。
4)static 成员变量的初始化在类外,此时不能再带上static 关键字。
5)普通的成员函数隐含了一个this指针,指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。静态成员函数由于不是与任何的对象相联系,因此它不具有this指针。它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。
2、static变量的作用:
1)在函数体内,静态变量具有”记忆功能“,即一个被声明为静态的变量在这一函数被调用的过程中其值维持不变。(也就是只经过一次初始化,之后其值就不会进行改变。)
2)在模块内(但在函数体外),它的作用范围是有限制的,即如果一个变量被声明为静态的,那么该变量可以被模块内所有函数访问,但不能被模块外的其他函数访问。它是一个本地全局变量。
在模块内,如果一个函数被声明为静态的,那么该函数与普通函数作用域不同,其作用域仅在本文件中,它只可被这一模块内的其他函数调用,不能被模块外的其他函数调用,也就是说这个函数被限制在声明它的模块的本地范围内使用。
3、与普通全局变量的区别:
1)static 全局变量只初始化一次,这样做的目的是为了防止在其他文件单元中被引用。
2)static 全局变量只初始化一次,下一次的运算依据是上一次计算的结果值。
3)作用域不一样,static修饰的函数只在一个源文件中有效,不能被其他源文件使用。
4、与全局变量相比,使用静态数据成员有两个优势:
1)静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性。
2)可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能。
常类型也成为 const 类型,是指使用类型修饰符const 说明的类型。
1)在C语言中,它主要用于定义变量为常类型以及修饰函数参数与返回值。
2)在C++中还可以修饰函数的定义,定义类的成员函数。常类型的变量或对象的值是不能被更新的。
1、作用:
1)定义const 常量,具有不可变性。
2)进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。
3)避免意义模糊的数字出现,同样可以很方便的进行参数的调整和修改。如只需最初定义的时候设置const int a=期望值即可。
4)保护被修饰的东西,防止被意外的修改,增强了程序的健壮性。
5)为函数的重载提供参考。如我们可以分别定义const和非const函数。
6)节省空间,避免不必要的内存分配。然而每一次宏替换却伴随着内存分配。const定义的常量在程序运行过程中只有一份复制品,而#define定义的常量在内存中有若干复制品(宏定义不分配内存,替换的时候要分配内存;const 定义不分配内存,第一次分配后,以后不分配内存)
7)提高了程序的效率。编译器不为const常量分配存储空间,而是保存在符号表。免去了存储和读内存的操作,效率更高。
2、常引用
也称const引用。引入目的是为了避免在使用变量的引用时,在毫不知情的情况下改变了变量的值,从而引起程序错误。如果既要提高程序效率,又要保护传递给函数的数据不被改变,就应使用常引用。const引用的意思是指向const对象的引用。
// 注意区分一般引用和常引用,const T&和T&
int val = 2012;
int& valr = val; // ok
const int& valr1 = val; // ok
int& valr = 2012; // error,一般引用T&的初始化表达式必须是左值,
//2012不是左值,所以不行
const int& valr1 = 2012;//ok,这里通过int temp =int(2012);构
//建一个temp,然后再通过temp初始化const int&,这个temp
//一直存在,直到程序块结束
// 常引用的另一个例子
int val = 2012;
int& valr = val+1;//error,同样val+1不是一个左值,不能初始化int&
const int& valr1 = val+1; // ok,也是通过中间的临时变量处理
需要。一旦通过switch语句确定了入口点,程序从入口点的case语句开始一直往下执行,除非遇到break,否则也会执行满足这个case之后的其他case语句(包括default)!!!直到switch结束或遇到break为止。
注:switch(c)中的c不能是float类型。
volatile 是一个类型修饰符,它用来修饰被不同线程访问和修改的变量。被volatile 类型定义的变量,系统每次用到它的时候都是直接从对应的内存当中提取,而不会利用Cache中原有的数值,以适应它的未知合适会发生的变化,系统对这种变量的处理不会做优化。
一个定义为volatile的变量是指这个变量可能会被意想不到的改变,这样编译器就不会去假设这个变量的值。准确的说,优化器在用到这个变量时必须每次都小心的从内存中读取他的值,而不是使用保存在寄存器里的备份。
所以,volatile 一般用于修饰多线程间被多个任务共享的变量和并行设备硬件寄存器等。
ASSERT()一般被称为断言,它是一个调试程序时经常使用的宏。通常用于判断程序中是否出现了非法的数据,在程序运行时它计算括号内的表达式的值:如果表达式的值为false(0),报告错误,终止运行。如果不为0,则继续执行后边的。
ASSERT()捕获的是非法情况而不是错误情况。
在枚举中,某个变量的值默认为前一个变量的值加1 ,而如果第一个枚举变量没有被赋值,则其默认值为0。如果中间出现某个变量被赋值,则重新以该值为起点,将后边未赋值的依次加1。
str1和str2两者都是字符数组,每个都有自己的存储区(在栈空间),它们的值是各存储区的首地址。
如果换成字符指针,则相等(str1=str2),因为字符指针并不分配存储区,其后的”abc“以常量形式存在于常量区,str1和str2都是指向它的首地址。但是&str1 != &str2,也就是指针自己的地址是不相等的。
在C99标准中,运行main()函数没有参数或者有两个参数。
int main(int argc, char *argv[])
其中第一个参数argc 表示命令行参数的数目,它是int 型的;第二个参数argv 是一个指向字符串的指针数组。
不是。对于C++程序而言,静态变量,全局变量、全局对象的分配早在main()函数之前就已经完成。
*p++ 与 (*)p++ 等价吗?为什么?
不等价。前者先完成取值操作,再对指针地址执行++操作;后者首先执行取值操作,再对取出的值进行++操作。
以++ 操作为例,对于变量a:
++a 表示取a的地址,增加它的内容,然后把值放在寄存器中;
a++ 表示把它的值装入寄存器,然后增加内存中a的值。
一般推荐使用前置自增,因为比后置效率更高。
1)左值:出现在表达式左边的值,可以被改变,它是存储数据值的那块内存的地址,也称为变量的地址。
2)右值:是指存储在某内存地址中的数据,也称为变量的数据。
3)左值可以作为右值,但右值不能作为左值。
本题不合法,a++不能当作左值使用,它表示取a的地址,把它的值装入寄存器,然后对内存中a的值执行加1操作;
++a 可以当左值使用,它表示取a 的地址,对它的内容进行加1操作,然后把值放在寄存器中。
1)int 类型:if(n==0)或者if(n !=0)
2)float类型:浮点型变量在内存中的存储导致他不是一个精确的数,不可以直接用==或者!=,应该转化为>=或者<=。例如:
const float EPSINON = 0.00001;
if((x >= -EPSINON)&&(x <= EPSINON))
3)bool 类型:if(flag) if(!flag)
4)指针类型:if(p==NULL) if(p!=NULL)
在C++中,申请动态内存与释放动态内存,用new/delete 与 malloc/free 都可以,申请的内存都位于堆中。对于一般数据类型,他们的效果是一样的。
new/delete 与 malloc/free 的区别:
1)new 能够自动计算需要分配的内存空间,而malloc 需要手工计算字节数。
2)new 与delete 直接带具体类型的指针,malloc 与free 返回void 类型的指针。
3)new 是类型安全的(执行类型安全检查),而malloc 不是。
4)new操作符(new operator)完成的功能分两部分:
(1)分配足够的内存以便容纳所需类型的对象(调用operator new)。
(2)调用构造函数初始化内存中的对象(调用constructor)。
new操作符总是做这两件事,我们不能以任何方式改变它的行为。分配内存这部分功能对应于malloc,但malloc不能调用构造函数。
同理,delete也对应两部分操作(释放内存和析构),而free只用于释放内存。
5)malloc/free 需要库文件stdlib.h支持,而new/delete 则不需要库文件的支持。
引用作为函数返回值类型的格式:
类型标识符 &函数名(形参列表及类型说明){//函数体}
将引用作为返回值的优点是在内存中不产生被返回值的副本,从而大大提高了程序的安全性与效率。
引用作为函数返回值类型格式需要注意:
1)不能返回局部变量的引用。局部变量存储在栈区,函数返回后被销毁,导致返回的引用”无所指“,引起错误。
2)不能返回函数内部new分配的内存的引用。避免内存泄露。
3)可以返回类成员的引用,但最好是常引用类型。
4)流操作符<<和>>。
不合法,要以字母或者下划线开头。
不一定。当x为整型值的最小值时不成立。越位溢出,得到的数大于0.
在C语言标准中,它们是等价的。但是如果在退出的时候需要使用main()函数的局部数据,那么从main()函数中使用return()就不行了。
exit()函数可以返回不同的数字。exit()在调用处强行退出程序,运行一次程序就结束。exit(n)则表示程序结束时返回n给系统,而无论参数是几,效果都是相同的,不同之处在于可以用不同数字区别退出的原因。
略。
export 是C++新增的关键字,它的作用是实现模板函数的外部调用,类似于extern 关键字。
关键字explicit,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生。声明为explicit的构造函数不能在隐式转换中使用。
explicit关键字用来修饰类的构造函数,表明构造函数是显示的,相对的是implicit关键字。
首先这个关键字只能用在类内部的构造函数声明上,而不能用在类外部的函数定义上,它的作用是不能进行隐式转换。
C++异常处理使用的关键字有try、catch、throw。
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
使用回调函数实际上就是在调用某个函数(通常是API函数)时,将自己的一个函数(这个函数为回调函数)的地址作为参数传递给那个被调用函数。而该被调用函数在需要的时候,利用传递的地址调用回调函数。
回调函数,就是由你自己写的,你需要调用另外一个函数,而这个函数的其中一个参数,就是你的这个回调函数名。这样,系统在必要的时候,就会调用你写的回调函数,这样你就可以在回调函数里完成你要做的事。
要定义和实现一个类的成员函数为回调函数需要做三件事:
a.声明;
b.定义;
c.设置触发条件,就是在你的函数中把你的回调函数名作为一个参数,以便系统
调用
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。