C++面试2(简答题)

1.new delete与malloc free的联系与区别?

答:相同点:都是在堆中动态创建堆内存。

     不同点:malloc函数创建动态内存时需要指定内存分配的字节数,但是它不能初始化动态内存对象。free函数不能调用动态内存对象的析构函数。new函数创建动态内存对象时不需要指定需要分配的字节数,它会自动调用对象的构造函数。delete函数也会自动调用析构函数。

2.main函数执行以前,还会执行什么代码?

答:全局对象的初始化或全局对象的构造函数会在main函数之前执行。

3.main函数执行完毕后,是否可能会再执行一段代码,给出说明?

答:可以,可以用_onexit注册一个函数,它会main之后执行int fn1(void),fn2(void),fn3(void),fn4(void).

_onexit函数包含在cstdlib库函数中,是一个回调函数,该函数必须是一个返回值为int,参数为void的无参函数。无论_onexit函数在main函数中的哪个位置,该回调函数都是最后执行。

#include "cstdlib"
#include "iostream"
using namespace std;
int fn1();
int fn2();
int fn3();
int fn4();
int main(int argc, char* argv[])
{
	printf("start!\n");
	_onexit(fn1);
	_onexit(fn2);
	_onexit(fn3);
	_onexit(fn4);
	printf("end!\n");
	return 0;
}
int fn1()
{
	cout<<"next.\n";
	return 0;
}
int fn2()
{
	cout<<"executed ";
	return 0;
}
int fn3()
{
	cout<<"is ";
	return 0;
}
int fn4()
{
	cout<<"This ";
	return 0;
}
结果:start
      end
      This is executed next.

4.分布写出BOOL、int、float、指针类型的变量a与“零”的比较语句?

答:BOOL:    if(a)  && if(!a);

int:   if(a == 0);

float:   const EXPERSSION EXP = 0.00000001;

  if(a<EXP && a>-EXP);

pointer:   if(a == NULL) or if( a!= NULL);

5.描述内存分配方式及他们的区别

答:1>从静态存储区域分配内存。静态内存的分配是在程序编译的时候就已经分配好了,这块内存在程序的整个运行期间都存在。如全局变量,static变量。

2>从栈存储区域分配内存。在程序运行期间,函数内的局部变量的存储单元都可以在栈内创建,函数执行结束时存储单元自动被释放。

3>从堆存储区域分配内存。也称为动态内存分配。程序在运行的时候用malloc或new进行分配内存,程序员自己负责在何时用free或delete释放内存,其生存期由程序员决定。

6.有关内存面试题

题1:

#include "cstdlib"
#include"iostream"
using namespace std;
void GetMemory(char* p)
{
	p = (char*)malloc(100);
}
void Test1(void)
{
	char* str = NULL;
	GetMemory(str);
	strcpy(str,"helloword");
	printf(str);
}
请问运行该程序会出现什么样的结果?

答:程序崩溃。(形参不能分配内存,因为函数没有被调用之前是不会占用内存的)形参p指向动态内存,当调用函数结束时,形参p被释放,实参str未指向任何内存,所以str一直为NULL,当运行到strcpy时,程序崩溃。可以通过以下进行改进:void GetMermory(char* &p);

题2:

char* GetMemory2(void)
{
	char p[]="hello word";
	return p;
}
void Test2(void)
{
	char* str = NULL;
	str = GetMemory2();
	printf(str);
}
请问运行Test2函数会有什么结果?

答:可能返回乱码。因为局部指针变量是由栈内存分配,该指针指向常量数据区“hello word”,当函数调用结束后,该指针所指向的内存被释放,返回的指针所指向的内存不可知。

题3:

void GetMemory3(char **p, int num)
{
	*p = (char*)malloc(num);
}
void Test3(void)
{
	char *str = NULL;
	GetMemory3(&str, 100);
	strcpy(str, "hello");
	printf(str);
}
请问运行Test3函数会有什么样的结果?

答:(1)能够输出结果(2)造成内存泄露
参数P为指针的指针,存放指针变量str的地址,*p = str,使用malloc后,*p内容被改变,当然str也被改变了,所以str指向malloc分配的内存,自然能够输出“hello”,在Test函数返回前使用delete str;str = NULL就OK了。

题4:

void Test4()
{
	char* str = (char*)malloc(100);
	strcpy(str,"hello");
	free(str);
	if (str != NULL)
	{
		strcpy(str,"word");
		printf(str);
	}
}
请问运行Test4函数会有什么样的结果?

答:篡改动态内存区的内容,后果难以预料,非常危险。因为free(str)之后,str成为野指针。if(str != NULL)语句不起作用。
7.如何引用一个已经定义过的全局变量?

答:两种方式。一是引用头文件的方式,二是使用extern关键字。

如果用引用头文件的方式来引用某个在头文件中声明的全局变量,如果那个变量引用错误,那么在编译期间就会报错。

如果使用extern关键字,如果那个变量引用错误时,在编译期间不会报错,二是在链接期间报错。如(error LNK2001: unresolved external symbol "int g_a")

8.在C++程序中调用被C编译器编译后的函数,为什么要加extern “C"?

答:因为C++语言支持函数重载,C语言不支持函数重载。同一个函数被C++编译后在库中的名字与C语言是不同的,假设某一个函数原型为:void foo(int x,int y);那么该函数被C编译器编译之后在库中的名字为_foo,而C++编译器编译之后在库中的名字为_foo_int_int。

所以C++提供extern "C"来解决C++语言与C语言名字不匹配问题。

9.内联函数与宏定义的差别是什么?

答:宏定义是在编译之前(编译预处理阶段)将程序中有关字符串替换成宏体,是在代码处不加任何验证的简单替换。

内联函数是在编译的时候内联函数是将函数直接被镶嵌到目标代码中。嵌入代码就是在调用内联函数的地方不是跳转,二是把代码直接写入到那里去。

inline函数一般只用于如下情况:1>一个函数不断被重复调用  2>函数只有简单几行,且函数内不包含for、while、switch语句。

10.类成员函数的重载、覆盖和隐藏的区别?

答:(1)重载:a.具有相同的范围(在同一个类中)b.具有相同的函数名 c.函数的参数不同 d.virtual关键字可有可无。

(2)覆盖指派生类函数覆盖基类函数:a.不同的范围(分别位于派生类和基类中)b.函数名相同  c.参数相同 d.基类函数必须有virtual关键字

(3)隐藏是指派生类的函数与基类的函数同名:a.如果派生类与基类的函数同名,但是参数不同,此时,无论有无virtual关键字,基类的函数将被隐藏。b.如果派生类的函数与基类的函数相同,参数也相同,但是基类函数没有virtual关键字,那么基类函数被隐藏。






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值