C++面试基础题错题集 day one

day 1:
char x[]="abcdefg";
char y[]={'a','b','c','d','e','f','g'};
answer:数组X的长度大于数组Y的长度;
solution:char x[]="abcdefg";中会隐式的在末尾添加空字符,而char y[]=
{'a','b','c','d','e','f','g'};则不会添加,空字符的出现取决于系统中空
字符的出现,这种定义下不是一个字符串。
 在gcc编译器下,针对以下代码,
const char str1[] = "abc";        
const char str2[] = "abc";
const char *p1 = "abc";
const char *p2 = "abc";
那么针对printf("%d %d %d %d\n",str1, str2,p1,p2)的结果, 判断下列说
法哪个是正确的:______。
正解:str1和str2地址不同,P1和P2地址相同。
解释:在定义char数组时,会将常量字符串中的值拷贝到字符数组中,因而
str1与str2指向的位置不同,但是定义的两个char*指针,p1,p2,都是指向常
量区的同一个字符串,因而两者相同
在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是: 
struct A
{
 int a;
 short b;
 int c;
 char d;
};
struct B
{
 int a;
 short b;
 char c;
 int d;
};
正解:16,12
解释:这类题目考察的是内存对齐:
结构体(struct)(或联合体(union))的数据成员,每个数据成员的对齐按照编
译选项指定的数据成员自身长度中,最长的那个。
A:
4(int)+1(short不够4,补2)+4(int)+4(char 不够4,补3) = 16
B:
4(int)+4(char 为1,short为2 ,补1)+4(int) = 12
 以下代码的输出是()
int a[5]={1,2,3,4,5};
int *ptr=(int*)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
正解:2,5
解释:数组名的值是一个指针常量,也就是数组第一个元素的地址。*(a+1)等
同于a[1],*(a+1)=2。
&a+1指向数组最后一个元素的下一个位置,故*(ptr-1)指向数组的最后一个元
素。
 有三个类A B C定义如下, 请确定sizeof(A) sizeof(B) sizeof(C)的大小顺
序.
struct A{
    A() {}
    ~A() {}
    int m1;
    int m2;
};
struct B:A{
    B() {}
    ~B() {}
    int m1;
    char m2;
    static char m3;
};
struct C{
    C() {}
    virtual~C() {}
    int m1;
    short m2;
};
正解:A<C<B
解释:类的大小只与成员变量(非static数据成员变量)和虚函数指针有关,
还要考虑到对齐. 
那么类A的大小是8个字节;
类B继承类A,在类A的8个字节基础上,再加上B自己的大小8字节,所以类B大
小是16个字节;
类C是4个字节+4个字节(考虑对齐)+4个字节(指向虚析构函数的指针)=12
个字节
下面哪种C/C++分配内存的方法会将分配的空间初始化为0
正解:calloc()
解释:1) malloc 函数: void *malloc(unsigned int size)
     在内存的动态分配区域中分配一个长度为size的连续空间,如果分配成
功,则返回所分配内存空间的首地址,否则返回NULL,申请的内存不会进行初
始化。
2)calloc 函数: void *calloc(unsigned int num, unsigned int size)
     按照所给的数据个数和数据类型所占字节数,分配一个 num * size 连
续的空间。
    calloc申请内存空间后,会自动初始化内存空间为 0,但是malloc不会进
行初始化,其内存空间存储的是一些随机数据。 
3)realloc 函数: void *realloc(void *ptr, unsigned int size)
    动态分配一个长度为size的内存空间,并把内存空间的首地址赋值给ptr
,把ptr内存空间调整为size。
    申请的内存空间不会进行初始化。
4)new是动态分配内存的运算符,自动计算需要分配的空间,在分配类类型的
内存空间时,同时调用类的构造函数,对内存空间进行初始化,即完成类的初
始化工作。动态分配内置类型是否自动初始化取决于变量定义的位置,在函数
体外定义的变量都初始化为0,在函数体内定义的内置类型变量都不进行初始
化。
 建立派生类对象时,3种构造函数分别是a(基类的构造函数)、b(成员对象的构
造函数)、c(派生类的构造函数)这3种构造函数的调用顺序为: 
正解:abc
解释:在继承中派生类的对象调用构造函数的顺序,应该是先调用基类的构造
函数,然后是成员中的对象对应类的构造函数,最后是派生类自己的构造函数
关于浅复制和深复制的说法,下列说法正确的是:
浅层复制:只复制指向对象的指针,而不复制引用对象本身。
深层复制:复制引用对象本身。
如果是浅复制,修改一个对象会影响另外一个对象
如果是深拷贝,修改一个对象不会影响到另外一个对象
若MyClass为一个类,执行
MyClass a[4],*p[5];语句时会自动调用该类构造函数的次数是:
正解:4
解释:把MyClass a[4],*p[5];分开写;
MyClass a[4];
MyClass *p[5];
则a[4]是类数组,有4个对象,调用构造函数4次
*p[5]是指针数组,也就是5个元素存放的是指向MyClass类型的对象的指针,


没有初始化的指针为空,不指向任何对象,也不调用构造函数。


下面对静态成员的描述中,正确的是:
正解:静态数据成员可以直接用类名调用
解释:静态数据成员不属于某一个对象,所以要在类外初始化,A错;
它是所以对象的公共成员,需要类名调用,B错;
静态数据成员初始化与这些权限控制的没有关系,C错;
故答案为D


以下哪些做法是不正确或者应该极力避免的:【多选】( )
正解:构造函数声明为虚函数
构造函数中调用虚函数
析构函数中调用虚函数
解释:所谓虚函数就是多态情况下只执行一个,而从继承的概念来讲,总是要先


构造父类对象,然后才能是子类对象,如果构造函数设为虚函数,那么当你在构


造父类的构造函数时就不得不显示的调用构造,还有一个原因就是为了防错,试


想如果你在子类中一不小心重写了个跟父类构造函数一样的函数,那么你的父


类的构造函数将被覆盖,也即不能完成父类的构造.就会出错.
在构造函数不要调用虚函数。在基类构造的时候,虚函数是非虚,不会走到派


生类中,既是采用的静态绑定。显然的是:当我们构造一个子类的对象时,先


调用基类的构造函数,构造子类中基类部分,子类还没有构造,还没有初始化


,如果在基类的构造中调用虚函数,如果可以的话就是调用一个还没有被初始


化的对象,那是很危险的,所以C++中是不可以在构造父类对象部分的时候调


用子类的虚函数实现。但是不是说你不可以那么写程序,你这么写,编译器也


不会报错。只是你如果这么写的话编译器不会给你调用子类的实现,而是还是


调用基类的实现。


在析构函数中也不要调用虚函数。在析构的时候会首先调用子类的析构函数,


析构掉对象中的子类部分,然后在调用基类的析构函数析构基类部分,如果在


基类的析构函数里面调用虚函数,会导致其调用已经析构了的子类对象里面的


函数,这是非常危险的。


在32位系统下下面程序输出的是
#include<stdio.h>
union uni
 {
     int a;
     char b;
 };
 struct str
 {
     int a;
     char b;
 };
 int main(int argc, char **argv)
 {
     printf("%d %d\n", sizeof(union uni), sizeof(struct str));
     return 0;
 }


正解:4 8
解释:union的大小取决于所占空间最大的变量的大小 并且是倍数  int a32位占4字节,所以uni的大小就是4字节
struct的大小由于内存对齐问题,int a四个字节,char b虽然是1个字节 但是为了存取效率,char b也被分配了一块4字节的空间,所以整个结构体所占空间为8字节




下面有关java和c++的描述,错误的是?
正解:c++和java支持多重继承
解释:JAVA没有指针的概念,被封装起来了,而C++有;JAVA不支持类的多继承,但支持接口多继承,C++支持类的多继承;C++支持操作符重载,JAVA不支持;JAVA的内存管理比C++方便,而且错误处理也比较好;C++的速度比JAVA快。
C++更适用于有运行效率要求的情况,JAVA适用于效率要求不高,但维护性要好的情况。


子类对象生成时:先调用父类的构造函数,然后在调用子类的构造函数; 析构时相反


 当一个类A 中没有声明任何成员变量与成员函数,这时sizeof(A)的值是多少?
正解:1















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值