C++面试题 (31-40)

31.下面代码的输出结果是

class B
{
	float f;	//4个字节
	char p;		//1个字节	内存对齐所以4个字节
	int adf[3];	//12个字节
}
cout <<"" << sizeof(B);	//20

32.一个空类占多少空间?多重继承的空类呢?

解析
1 1 详情看上期

33.内联函数和宏的差别是?

内联函数和普通函数相比可以加快程序的运行速度,因为不需要中断调用,在编译的时候内联函数可以直接被镶嵌到目标代码中。而宏只是一个简单的替换。
内联函数要做参数类型检查,这是内联函数跟宏相比的优势。
inline是指嵌入代码。就是在调用函数的地方不是跳转,而是把代码直接写到那里去,对于短小的代码来说,inline可以带来一定的效率提升,而且跟C时代的宏函数相比,inline更安全可靠,可是这个是以增加空间消耗为代价的。所以是否使用inline据具体情况取舍。
inline一般用于如下
(1)一个函数不断被重复调用。
(2)函数只有简单几行,而且函数内不包含for/while/switch语句。
一般来说写小程序没必要定义成inline,但是如果要完成一个工程项目,当一个简单的函数被多次调用时,这个时候就要考虑用inline
宏在C语言极其重要,但是在c++中用得就少多了。 关于宏的第一个规则是:就不应该去使用它,除非不得不这样做。 几乎每个宏都表明了程序设计语言里或者程序里或者程序员的一个缺陷,因为他将在编译器看到程序的正文之前重新摆布这些正文。宏也是许多程序设计工具的主要麻烦。
宏是在代码处不加任何验证的简单替代,而内联函数是将代码直接插入调用处,减少了普通函数调用时的资源消耗。
宏不是函数,只是在编译前(编译预处理阶段)将程序中有关字符串替换成宏体。

34.指针和引用的差别。

(1)非空区别。在任何情况下都不能使用指向空值的引用。一个引用总是指向某些对象。而指针可以为空值。如果你需要一个变量,这个变量可以指向一个对象也可以不指向任何对象,这时你应该把变量声明为指针;相反,你只让这个变量指向一个确定的对象且不能为空,这时你需要把它声明为引用。
(2) 合法性区别。在使用引用前不需要测试它的合法性。相反,指针则应该总是被测试,防止其为空。这都是他们的非空区别导致的。
(3) 可修改区别。指针可以被重新赋值以指向另一个不同的对象。但引用则总是指向在初始化时被指定的对象,以后都不能更改,但其指定的对象的内容是可以改变的。
(4) 应用区别。 在以下情况下你应该用指针:一是你考虑到存在不指向任何对象的可能(在这种情况下,你能够设置指针为空),二是你需要在不同的时刻指向不同的对象(在这种情况下,你能够改变指针的指向)。 如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么你应该使用引用。

35.看下面的程序哪里有错

#include <iostream>
using namesapce std;
int main()
{
	int iv;
	int iv2 = 1024;
	int iv3 = 999;
	int &reiv;	//错误声明引用,引用不能为空,必须初始化。
	int &reiv2 = iv;
	int &reiv3 = iv;
	int*pi;
	*pi = 5;	//错误,指针并未指向实际的地址,这个时候去对他赋值是错误的,因为赋的值不知道存储在哪里。
	pi = &iv3;
	const double di;	//错误,const常量赋值时,必须同时初始化。
	const double maxWage = 10.0;
	const double minWage = 0.5;
	const double* pc = &maxWage;

	cout << pi;
	return 0;
}

36.下面关于“this”指针的叙述哪个是不正确的

  1. 让x类的每个对象都指向他的地址;
  2. 可以隐形传递this指针
  3. 不能在类的成员函数理明确声明。//错误。
  4. 他是一个常量函数中的一个常量指针。

37.将下面程序中的 this指针改成非this指针的传递方式,编写程序实现。

#include <iostream>
#include <string.h>
using namespace std;
struct X
{
private:
    int   len;
    char* ptr;
public:
    int GetLen()
    {
        return len;
    }
    char* GetPtr()
    {
        return ptr;
    }
    X& Set(char *);   // 返回类对象的引用
    X& Cat(char *);
    X& Copy(X&);
    void Print();
};
X& X::Set(char *pc)
{
    len = strlen(pc);
    ptr = new char[len];
    strcpy(ptr, pc);
    return *this;
}
X& X::Cat(char *pc)
{
    len += strlen(pc);
    strcat(ptr, pc);
    return *this;
}
X& X::Copy(X &x)
{
    Set(x.GetPtr());
    return *this;
}
void X::Print()
{
    cout << ptr << endl;
}
 
int main()
{
    X xobj1;
    xobj1.Set("abcd").Cat("efgh"); 
    xobj1.Print();
    
    X xobj2;
    xobj2.Copy(xobj1).Cat("ijkl");
    xobj2.Print();
 
    return 0;
}

修改后

#include <iostream>
#include <string.h>
using namespace std;
struct X
{
private:
    int len;
    char *ptr;
public:
    int GetLen()
    {
        return this->len;
    }
    char *GetPtr()
    {
        return this->ptr;
    }
    X &Set(char *);   // 返回类对象的引用
    X &Cat(char *);
    X &Copy(X&);
    void Print();
};
X &X::Set(char *pc)
{
    this->len = strlen(pc);
    this->ptr = new char[this->len];
    strcpy(this->ptr, pc);
    return *this;
}
X &X::Cat(char *pc)
{
    this->len += strlen(pc);
    strcat(this->ptr, pc);
    return *this;
}
X &X::Copy(X &x)
{
    this->Set(x.GetPtr());
    return *this;
}
void X::Print()
{
    cout << this->ptr << endl;
}
 
int main()
{
    X xobj1;
    xobj1.Set("abcd").Cat("efgh"); 
 
    xobj1.Print();
    X xobj2;
    xobj2.Copy(xobj1).Cat("ijkl");
 
    xobj2.Print();
 
    return 0;
}

38.这个程序测试后会有什么结果

#include <iostream>

void GetMemory(char*p,int num)
{
	p = (char*)malloc(sizeof(char)*num);
}

int main()
{
	char* str = NULL;
	GetMemory(str,100);
	strcpy(str,"hello");
	return 0;
}

解析
void GetMemory中的p实际上是主函数str的一个副本,编译器总要为函数的每个参数制作临时副本。在题中p申请了新的内存,只是把p指向的地址改变了,但是str丝毫未变。因为Get函数没有返回值,因此str并不是指向p所申请的那一段内存,所以函数get并不能输出任何东西。事实上,每执行一次get函数就会申请一块内存,但是申请的内存却不能有效的释放,结果内存一直被独占,最终造成内存泄漏。

注意区分值传递和引用传递

修改

#include <iostream>

void GetMemory(char**p,int num)
{
	*p = (char*)malloc(sizeof(char)*num);
}

int main()
{
	char* str = NULL;
	GetMemory(&str,100);
	strcpy(str,"hello");

	cout << *str << endl;
	cout << str << endl;
	cout << &str<< endl;
	free(p);
	return 0;


}

答案:程序崩溃。因为GetMemory并不能动态传递内存,Test函数中的str一直都是NULL 可以运行。不理解什么叫动态传递内存????

39、这个程序测试后会有什么结果

#include <iostream>
using namesapce std;

char* GetMemory(void)
{
	char p[] ="hello world";
	return p;
}

int main()
{

	char* str =NULL;
	str = GetMemory();
	cout << str;
	return 0;
}

解析
可能是乱码,也有可能正常输出,因为GetMemory返回的是指向“栈内存”的指针,该指针的地址不是NULL,但是其原来的内容已经被清除,新内容不可知。

40.下面代码的输出结果是

#include <iostream>
using namespace std;

void change(int* a,int &b,int c)
{
	c = *a;
	b = 3;
	*a = 2;
}

int main()
{
	int a = 1;
	int b = 2;
	int c = 3;
	change(&a,b,c);
	cout << a << b << c;	// 2  3   3
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值