重拾C++经典笔试30题(21-30)
来源:互联网 发布:mac系统占用空间大 编辑:程序博客网 时间:2024/06/05 11:09
重拾C++经典笔试30题(21-30)
1. 为什么Delete会出错?
class CBase{public: CBase() { cout <<"CBase" << endl; } virtual ~CBase() { cout <<"~CBase" << endl;}}; classCDerived : public CBase{public: CDerived() { cout <<"CDerived" << endl; } ~CDerived() { cout <<"~CDerived" << endl; }}; int main(){ CBase base; CBase* pBase = new CBase; pBase = &base; delete pBase; //运行时报错!}
【分析如下】:
1.pBase指向了栈区内存,那是系统管理的空间,不能用delete释放的。
2.程序在堆区new的空间最后没有被释放,造成了内存泄露。
3.最好不要随便把申请到堆区空间的指针指向别处,至少也要有一个指针指向申请的空间。以便最后释放的是自己申请的那块内存。
【修正后做法】:
int main(){ CBase base; CBase* pBase = new CBase; CBase* pBase2 = pBase; //至少也要有一个指针指向申请的空间 pBase = &base; delete pBase2; //以便最后释放的是自己申请的那块内存。} //运行时不再报错!
【再深入点】:程序有两个问题:
1.内存泄露,new出来的没delete;
2.两次析构;base不是new出来,在生命周期结束(也就是你函数结束的时候)会自动释放,你主动调用delete将其析构,系统在函数结束时又会对其析构,所以才会报错。而且报错的地方应该是程序退出时。
2. 类中静态常成员变量的定义?
#include<iostream>usingnamespace std;//可以在类的声明中对常量的类变量进行赋值//VS2008可以,vc6.0不可以。和编译器有关。class myclass{public: static const int i=20; //只有类的静态常量数据成员才可以在类中初始化。};const int myclass::i = 10;int main(){ cout<<myclass::i<<endl; return 0;}
3. 重载和多态的关系?
不同点
重载overload
覆盖override
1.是否支持多态?
不支持
支持
2.存在形式?
可以在类中或在C++语言中都可以体现
存在于类中父类、子类之间。
3.参数列表、返回值
参数列表或返回值不同,或二者都不同。
参数列表、返回指标必须相同。
4. 输出格式:printf用!
%a(%A)
浮点数、十六进制数字和p-(P-)记数法(C99)
%c
字符
%d
有符号十进制整数
%f
浮点数(包括float和doulbe)
%e(%E)
浮点数指数输出[e-(E-)记数法]
%g(%G)
浮点数不显无意义的零"0"
%i
有符号十进制整数(与%d相同)
%u
无符号十进制整数
%o
八进制整数 e.g. 0123
%x(%X)
十六进制整数0f(0F) e.g. 0x1234
%p
指针
%s
字符串
5. 一个参数或指针可以既是const又是volatile)解读?
Volatile 以防止编译器将其优化成从寄存器中读取。一个定义为volatile的变量时说这个变量可能会被意想不到地改变,这样编译器就不会去假设这个变量的值。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。
一个参数可以既是const又是volatile,const是不让程序修改,volatile是意想不到的改变,不是程序修改。一个指针也可以是volatile,中断服务子程序修改一个指向buffer的指针。
6. Little Endian低字节序(由低字节—>高字节存储);计算机默认的为低字节序。
High Endian高字节序(由高字节—>低字节存储);
typedef struct bitstruct{ int b1:5; int b2:2; int b3:2;}bitstruct; int main(){ bitstruct b; memcpy(&b,"EMCEXAMINATION",sizeof(b)); cout << sizeof(b) << endl; printf("%d,%d\n",b.b1,b.b2);//5,-2 return 0;}
[解读]:1.sizeof(b)=4;即4个字节的大小。
2.memcpy将”EMC …”存入b中。
3.实质b中只有5+2+2,9位。即对应字符也只有”EM”.E的ASCII码为0X45,M的ASCII码为0X4D。
满足高字节—>低字节存储0X4D0X45,对应二进制位:01001101 0100 0101。
4.对应的b1,满足(低字节存放于低位)取得后低地址的5位0 0101,首位为0代表正数,大小为5。
对应的b2,取10,首位为1代表负数,取补码后得到b2=-2。
27.输出结果?
int main(){ int a[5][2] = {0,1,2,3,4,5,6,7,8,9}; int *p = a[0]; int (*p2)[2] = &a[1]; ++p; ++p2; printf("%d\n",*p); //1 p 是整型指针,初始指向元素0,加1指向1 printf("%d\n",**p2); //4 p2是含2个元素的数组指针,初始指向元素2,该指针加1是向后移动2个数据,所以指向4 printf("%d \n",p2[1][2]); //如何解读? 见下解读。 return 0;}
0
1
0
0 (p)
1(++p后)
1
2 (P2指向)
3
2
4 (++p2后)
5
3
6 (p2+1后)
7
4
8 (p2[1][2])
9
解读:p2是一个指针,是一个指向包含两个元素数组的指针变量。和普通的指针不同的地方时它指向的长度为2。(*p2)[2]和a是等价的。
对于p2[1][2],此时p2指向4,前一个下标1就是p2指针再加1指向6,后一个下标加2移动2个元素,指向了8。
28.拷贝构造输出结果?
class A{ static int objectCount;public: A() { objectCount++; cout << "A():" <<objectCount << endl; } A(const A& r) { objectCount++; cout << "A(const A&r):" << objectCount << endl; } ~A() { objectCount--; cout << "~A():"<< objectCount << endl; }}; intA::objectCount = 0; A f(A x) { cout << endl << "Begin: f(A x)" << endl; return x; //【临时对象】调用默认拷贝构造函数A(const A& r):3} //~A():2 int main(){ A h; //A():1 A h2 = f(h); //调用默认拷贝构造函数A(constA& r):2 cout << endl <<"End(main): f(A x)" << endl << endl; return 0; } //~A():1 析构h2 //~A():0 构函h
29.四类强制类型转换
类型
示意
举例
static_cast
1.类型转换,编译器隐式执行的任何类型都可由static_cast显示完成;2.使用类型信息执行转换,在转换执行必要的检测(越界检测、类型检查),操作相对安全;
int—>double
int ival;
double result = static_cast<double> ival
const_cast
转换掉对象的const属性
下举例
dynamic_cast
运行时类型检查,用于继承体制下的由上到下的转换downcast。
下举例
reinterpret_cast
1.仅仅重新编译了给定对象的比特模型,而没有进行二进制转换;2.为操作数提供低层次的重新解释。
下举例
举例:
//const_cast 实例.class B{public: int m_num;}; int main(){ B b0; b0.m_num = 100; const B b1 = b0; cout << b0.m_num<< " " << b1.m_num << endl;// 以下修改const对象的值是错误的。// b1.m_num = 355;// cout << b1.m_num <<endl; // error C2166: l-value specifiesconst object //以下使用const_cast是正解. const_cast<B&>(b1).m_num =355; cout<< b1.m_num << endl; return 0;} //reinterpret_cast实例int main(){ int n = 9; double dval =reinterpret_cast<double& >(n); double dval_new =static_cast<double>(n); //成功. //[仅仅复制了n的比特位到d,没有进行必要的分析] cout << dval << endl;//2.64214e-308 cout << dval_new << endl;//9 return 0;}//dynamic_cast实例class B{public: B() { cout << "B()"<< endl; } ~B() { cout << "~B()"<< endl; }};class C :public B{public: C() { cout << "C()"<< endl; } ~C() { cout << "~C()"<< endl; }};class D :public C{public: D(){ cout << "D()"<< endl; } ~D(){ cout << "~D()"<< endl; }}; void f(D* pd){ C* pc =dynamic_cast<C*>(pd); // ok: C isa direct base class // pc points to C subobject of pd B* pb =dynamic_cast<B*>(pd); // ok: B isan indirect base class // pb points to B subobject of pd } int main(){ D objd; f(&objd); return 0;}
30. 持续更新中......
30. 如何在C/C++中显示当前程序所在的文件名及行号。
——这个当时没答上来,见过没记住。今天查了下MSDN如下:
__FILE__, //用于显示文件名的宏 %s, 格式如【F:\NeuSoftDemo\NeuSoftDemo.cpp】;__LINE__, //用于显示行号的宏 %d,格式如【12】;
扩展》》__DATE__, //用于显示当前日期,格式如【Sep 18 2012】 %s; __TIME__, //用于显示当前时间,格式如【09:45:01】 %s;
__TIMESTAMP__,//用于显示当前日期和时间,格式如【Tue Sep 18 09:48:07 2012】 %s。
31. 程序纠错题:
- int main(int argc,char* argv[])
- {
- char str[5][] = {"First","Second","Thrid","Four","Five"};
- char* p[] = {str[4],str[3],str[2],str[1],str[0]};
- for(int i = 0; i < 5; i++)
- {
- printf("%c\n",*(p+i));
- }
- return 0;
- }
错误1: char str[5][] 定义出错,需要指定第一维的个数,改为char str[][5]吗?但后面的字符串如"Second"6个字符,还有'\0'。改为:char* str[5]比较稳妥;
错误2: printf("%c\n",*(p+i)); 显然*(p+i) 等价于p[i]存储的是字符串,所以%c应该改为%s。(%c打印的是单个字符,%s打印的是字符串)。
修正后如下:
- int main(int argc,char* argv[])
- {
- char *str[5] = {"First","Second","Thrid","Four","Five"};
- char* p[] = {str[4],str[3],str[2],str[1],str[0]};
- for(int i = 0; i < 5; i++)
- {
- printf("%s\n",*(p+i));
- }
- return 0;
- }
33. 递归与非递归实现二分查找。
//非递归实现-
- void binarySearchUncycle(int nArr[],int nSize,int nSearchVal)
- {
- int nLow = 0;
- int nHigh = nSize-1;
- int nMid = 0;
- bool bFound = false;
- while(nLow <= nHigh)
- {
- nMid = (nLow + nHigh)/2;
- cout << "nMid =" << nMid << endl;
- if(nArr[nMid] == nSearchVal)
- {
- bFound = true;
- break;
- }
- else if(nArr[nMid] > nSearchVal)
- {
- nHigh = nMid-1;
- }
- else
- {
- nLow = nMid+1;
- }
- }//end while
- if(bFound)
- {
- cout << "The Elem " << nSearchVal << " is Exist in the array!" << endl;
- }
- else
- {
- cout << "The Elem " << nSearchVal << " is Not Exist in the array!" << endl;
- }
- }
- //递归实现二分查找
- void binarySearchCycle(int nArr[],int low,int high, int nSearchVal)
- {
- int nLow = low;
- int nHigh = high;
- int nMid = 0;
- bool bFound = false;
- nMid = (nLow + nHigh)/2;
- if(nArr[nMid] == nSearchVal)
- {
- bFound = true;
- cout << "The Elem " << nSearchVal << " is Exist in the array!" << endl;
- return;
- }
- else if(nArr[nMid] > nSearchVal)
- {
- nHigh = nMid-1;
- binarySearchCycle(nArr,nLow,nHigh,nSearchVal);
- }
- else
- {
- nLow = nMid+1;
- binarySearchCycle(nArr,nLow,nHigh,nSearchVal);
- }
- }
- 重拾C++经典笔试30题(21-30)
- 重拾C++经典笔试30题(21-30)
- 重拾C++经典笔试30题(1-10)
- 重拾C++经典笔试30题(11-20)
- 重拾C++经典笔试30题(11-20)
- C/C++经典笔试题(之一)
- C语言经典笔试题(一)
- C语言经典笔试题(一)
- C语言经典笔试题(二)
- C/C++经典笔试题
- 经典c语言笔试题
- 经典嵌入式C笔试题
- C/C++经典笔试题
- C/C++经典笔试题
- C / C++ 经典笔试题剖析(一)
- 嵌入式程序员C语言笔试经典题
- C经典笔试题之2
- c/c++经典笔试题大全
- C++学习笔记之继承层次中的函数调用。
- Eclipse 3.6 中安装WindowBuilder Pro及使用SWT Designer
- 题目:Easier Done Than Said?
- 你的梦想,是复制别人吗
- 美媒称中日副外长将会晤预示两国寻求缓解对抗-钓鱼岛-反日示威-反日
- 重拾C++经典笔试30题(21-30)
- Eclipse 插件开发遇到问题心得总结
- AxmlParserPY对framework-res.apk反编译失败的修正
- 平均要取多少个(0,1)中的随机数才能让和超过1
- javascript的Frame学习
- Error: Cannot create Windows service for MySql. Error: 0解决方案
- 25个最佳最闪亮的Eclipse开发项目
- 我国前三季度自然灾害已致1263人死亡-自然灾害-受灾-死亡
- sql中经常遗忘的知识点