C/C++面试题精选
来源:互联网 发布:苹果免费打电话软件 编辑:程序博客网 时间:2024/06/06 00:18
题目(七):运行下列C++代码,输出什么?
class A
{
public:
A()
{
Print();
}
virtualvoid Print()
{
printf("A is constructed./n");
}
};
class B:public A
{
public:
B()
{
Print();
}
virtualvoid Print()
{
printf("B is constructed./n");
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A* pA =new B();
delete pA;
return 0;
}
答案:先后打印出两行:A is constructed. B is constructed.调用B的构造函数时,先会调用B的基类及A的构造函数。然后在A的构造函数里调用Print。由于此时实例的类型B的部分还没有构造好,本质上它只是A的一个实例,他的虚函数表指针指向的是类型A的虚函数表。因此此时调用的Print是A::Print,而不是B::Print。接着调用类型B的构造函数,并调用Print。此时已经开始构造B,因此此时调用的Print是B::Print。
题目(12):运行下图中的C++代码,输出是什么?
#include<iostream>
class A
{
private:
int n1;
int n2;
public:
A(): n2(0), n1(n2 + 2)
{
}
void Print()
{
std::cout << "n1: " << n1 <<", n2: " << n2 << std::endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
a.Print();
return 0;
}
答案:输出n1是一个随机的数字,n2为0。在C++中,成员变量的初始化顺序与变量在类型中的申明顺序相同,而与它们在构造函数的初始化列表中的顺序无关。因此在这道题中,会首先初始化n1,而初始n1的参数n2还没有初始化,是一个随机值,因此n1就是一个随机值。初始化n2时,根据参数0对其初始化,故n2=0。
题目(14):运行下图中的C++代码,输出是什么?
int SizeOf(char pString[])
{
return sizeof(pString);
}
int _tmain(int argc, _TCHAR* argv[])
{
char* pString1 = "google";
int size1 = sizeof(pString1);
int size2 = sizeof(*pString1);
char pString2[100] = "google";
int size3 = sizeof(pString2);
int size4 = SizeOf(pString2);
printf("%d, %d, %d, %d", size1, size2, size3, size4);
return 0;
}
答案:4, 1, 100, 4。pString1是一个指针。在32位机器上,任意指针都占4个字节的空间。*pString1是字符串pString1的第一个字符。一个字符占一个字节。pString2是一个数组,sizeof(pString2)是求数组的大小。这个数组包含100个字符,因此大小是100个字节。而在函数SizeOf中,虽然传入的参数是一个字符数组,当数组作为函数的参数进行传递时,数组就自动退化为同类型的指针。
题目(15):运行下图中代码,输出的结果是什么?这段代码有什么问题?
#include<iostream>
class A
{
public:
A()
{ std::cout << "A is created." << std::endl; }
~A()
{ std::cout << "A is deleted." << std::endl; }
};
class B :public A
{
public:
B()
{ std::cout << "B is created." << std::endl; }
~B()
{ std::cout << "B is deleted." << std::endl; }
};
int _tmain(int argc, _TCHAR* argv[])
{
A* pA = new B();
delete pA;
return 0;
}
答案:输出三行,分别是:A is created. B is created. A is deleted。用new创建B时,回调用B的构造函数。在调用B的构造函数的时候,会先调用A的构造函数。因此先输出A is created. B is created.
接下来运行delete语句时,会调用析构函数。由于pA被声明成类型A的指针,同时基类A的析构函数没有标上virtual,因此只有A的析构函数被调用到,而不会调用B的析构函数。
由于pA实际上是指向一个B的实例的指针,但在析构的时候只调用了基类A的析构函数,却没有调用B的析构函数。这就是一个问题。如果在类型B中创建了一些资源,比如文件句柄、内存等,在这种情况下都得不到释放,从而导致资源泄漏。
问题(16):运行如下的C++代码,输出是什么?
class A
{
public:
virtualvoid Fun(int number = 10)
{
std::cout <<"A::Fun with number " << number;
}
};
class B:public A
{
public:
virtualvoid Fun(int number = 20)
{
std::cout <<"B::Fun with number " << number;
}
};
int main()
{
B b;
A &a = b;
a.Fun();
}
答案:输出B::Fun with number 10。由于a是一个指向B实例的引用,因此在运行的时候会调用B::Fun。但缺省参数是在编译期决定的。在编译的时候,编译器只知道a是一个类型a的引用,具体指向什么类型在编译期是不能确定的,因此会按照A::Fun的声明把缺省参数number设为10。
这一题的关键在于理解确定缺省参数的值是在编译的时候,但确定引用、指针的虚函数调用哪个类型的函数是在运行的时候。
问题(17):运行如下的C代码,输出是什么?
char* GetString1()
{
char p[] ="Hello World";
return p;
}
char* GetString2()
{
char *p ="Hello World";
return p;
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("GetString1 returns: %s. /n", GetString1());
printf("GetString2 returns: %s. /n", GetString2());
return 0;
}
答案:输出两行,第一行GetString1 returns:后面跟的是一串随机的内容,而第二行GetString2 returns: Hello World.两个函数的区别在于GetString1中是一个数组,而GetString2中是一个指针。
当运行到GetString1时,p是一个数组,会开辟一块内存,并拷贝"Hello World"初始化该数组。接着返回数组的首地址并退出该函数。由于p是GetString1内的一个局部变量,当运行到这个函数外面的时候,这个数组的内存会被释放掉。因此在_tmain函数里再去访问这个数组的内容时,结果是随机的。
当运行到GetString2时,p是一个指针,它指向的是字符串常量区的一个常量字符串。该常量字符串是一个全局的,并不会因为退出函数GetString2而被释放掉。因此在_tmain中仍然根据GetString2返回的地址得到字符串"Hello World"。
问题(19):运行下图中C代码,输出的结果是什么?
int _tmain(int argc, _TCHAR* argv[])
{
char str1[] ="hello world";
char str2[] ="hello world";
char* str3 ="hello world";
char* str4 ="hello world";
if(str1 == str2)
printf("str1 and str2 are same./n");
else
printf("str1 and str2 are not same./n");
if(str3 == str4)
printf("str3 and str4 are same./n");
else
printf("str3 and str4 are not same./n");
return 0;
}
答案:输出两行。第一行是str1 and str2 are not same,第二行是str3 and str4 are same。
str1和str2是两个字符串数组。我们会为它们分配两个长度为12个字节的空间,并把"hello world"的内容分别拷贝到数组中去。这是两个初始地址不同的数组,因此比较str1和str2的值,会不相同。str3和str4是两个指针,我们无需为它们分配内存以存储字符串的内容,而只需要把它们指向"hello world“在内存中的地址就可以了。由于"hello world”是常量字符串,它在内存中只有一个拷贝,因此str3和str4指向的是同一个地址。因此比较str3和str4的值,会是相同的。
出处:http://blog.csdn.net/cadcisdhht/article/details/6193071
- C面试题精选
- C面试题精选
- C/C++面试题精选
- C基础面试题精选
- C数据结构面试题精选
- C/C++面试题精选
- C/C++面试题精选
- C/C++面试题精选
- C/C++/C#面试题精选
- C/C++/C#面试题精选
- C/C++/C#面试题精选4
- 嵌入式c语言面试题精选
- C/C++/C#面试题精选(1)
- C/C++/C#面试题精选(2)
- C/C++/C#面试题精选(3)
- C/C++/C#面试题精选(4)
- C/C++/C#面试题精选(3)
- C/C++/C#面试题精选(4)
- 嵌入式Linux学习-------Linux内核移植
- linux通过远程桌面访问windows
- Apache配置http访问转https
- 从数据库用户表在fastdfs文件系统批量创建头像一例
- iOS---如何把导航默认的返回按钮设置成“返回”
- C/C++面试题精选
- PHP+MySQL的操作
- UIGestureRecognizer手势识别详解
- List接口、ArrayList类和LinkedList类 笔记
- IOS 的 7 中手势的介绍 和详细使用(UIGestureRecognizer) UIScreenEdgePanGestureRecognizer
- centos6.4安装mysql5.5
- C算法--堆排序
- CFileDialog类无故崩溃的解决及原因分析
- Hive远程模式安装