欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C/C++基础知识面试题回顾及答案分享

程序员文章站 2022-04-23 17:20:05
1. typedef struct list_t{ struct list_t *next; struct list_t *prev; char data[0]; }...

1.

typedef struct list_t{
struct list_t *next;
struct list_t *prev;
char data[0];
}list_t;

请问在32位系统中,sizeof(list_t)的值为?

答案【8byte】

解析:用作定义时char[0]是空数组,是不占空间的。

2.C++是不是类型安全的?

答案【不是】

解析:如果规定两种不同类型之间必须通过显示转换则是安全的。

3.代码可以通过编译吗?如果不能应该如何修改?

template class Foo{
        T tVar;
    public:
        Foo(T t) : tVar(t) { }
};

template class FooDerived:public Foo
{
};

int main()
{
    FooDerived d(5);
    return 0;
}

A 代码可以正确通过编译。 B 编译错误,FooDerived是一个继承模板类的非模板类,它的类型不能改变。 C 编译错误,tVal变量是一个不确定的类型。

D 编译错误,可以在FooDerived类中添加一个构造函数解决问题。

答案【D】

解析:父类定义了带参数的构造函数,如果子类没有显示调用父类的构造方法,则默认调用父类的默认构造函数,于是这里默认构造函数消失了,子类需要显示调用父类的构造方法。

4.观察下面一段代码:

class ClassA
{
public:
    virtual ~ ClassA(){};
    virtual void FunctionA(){};
};
class ClassB
{
public:
   virtual void FunctionB(){};
};
class ClassC : public ClassA,public ClassB
{
    public:
};
ClassC aObject;
ClassA* pA=&aObject;
ClassB* pB=&aObject;
ClassC* pC=&aObject;

关于pA,pB,pC的取值,下面的描述中正确的是:

A pA,pB,pC的取值相同 B pC=pA+pB C pA和pB不相同

D pC不等于pA也不等于pB

答案【C】

解析 :aObject的地址从A的虚函数表开始,然后到B的虚函数表,再到C自身的成员

5.随着装填因子a的增大,用闭哈希法解决冲突,其平均搜索长度比用开哈希法解决冲突时的平均搜索长度增长得慢()【错】

开哈希表——-链式地址法 闭哈希表——-开放地址法

开哈希只会和相同值发生冲突,而闭哈希除了与相同值发生冲突,还会与不同值发生冲突 ;开哈希不受密度影响,而闭哈希受密度影响 。

6.下列叙述中错误的是( )

A 二叉链表是二叉树的存储结构 B 循环链表是循环队列的存储结构 C 栈是线性结构

D 循环队列是队列的存储结构

答案【B】

BD.队列两种存储方式:循环队列和链队列

C.栈是一种特殊存取方式的线性表。

7.下面程序会输出什么:

static int a=1; //静态全局变量
void fun1(void)
{ 
    a=2; //访问全局变量,改变值
}
void fun2(void)
{
    int a=3;  //定义一个局部变量,函数结束销毁
}
void fun3(void)
{
    static int a=4; //静态局部变量,函数结束仍存在,但别的函数不能引用它
}
int main()
{
  printf(“%d”,a); //首次输出,a = 1
  fun1( );  //修改a的值
  printf(“%d”,a); //输出2
  fun2( ); //没有改变全局变量a的值
  printf(“%d”,a); //输出2
  fun3( ); //一个新的变量,a,与printf的a并不是一个东西
  printf(“%d”,a);  //输出2
}

答案【1 2 2 2】

解析见注释部分

8.下面代码的输出结果是()

int main(){
   int pid;
   int num=1;
   pid=fork();
   if(pid>0){
   num++;
   printf("in parent:num:%d addr:%x\n",num,&num);
   }
   else if(pid==0){
   printf("in child:num:%d addr:%x\n",num,&num);
   }
}

答案【父子进程中输出的num不同,num地址相同】

解析:num不同比较好理解,num地址相同指的是虚拟地址相同,Linux中的资源分配都是虚拟机制,也就是说,他们还是会共用一个虚拟的地址,但是映射到物理内存就可能会不一样。

其实刚刚fork出来不止虚拟地址一样,物理地址也一样。当进程发生分歧时,即修改此变量时,才会分配不同的物理地址,也就是copy-on-write,写时复制。

9.线索化二叉树:左指针为空->指前驱;右指针为空->指后继

10.下列代码的输出结果是

int i = -1;
unsigned j = 1;
if (j > i)
    printf(" (j>i)成立\n");
else
    printf(" (j>i)不成立\n");

if (i < j)
    printf

答案【(j>i)不成立,(i\<\j)不成立】

表达式会包含隐式类型转换,它由编译器自动执行,不需程序员介入。

转换之后 signed int 被转换为unsigned int,以8字节为例,-1是11111111,比1大

11.如下语句通过算术运算和逻辑运算之后 i 和 j 的结果是()

【短路原则】

int i=0;
int j=0;
if((++i>0)||(++j>0))
{
/打印出i和j的值。
}

答案【i = 1;j = 0】

解析:先执行++i,此时i变为1,然后判断i>0为真。短路原则(||)不会计算后面的条件,因此++j不执行,j==0

12.关键字

【待补充】

13.下列代码编译时会产生错误的是()

#include 
using namespace std;
struct Foo {
    Foo() {}
    Foo(int) {}
    void fun() {}
};
int main(void) {
    Foo a(10); //语句1  
    a.fun(); //语句2  
    Foo b(); //语句3  
    b.fun(); //语句4  
    return 0;
    16.
}

答案【语句4】

解析:语句4出错来自语句3,Foo b()会被编译器认为声明了一个函数,正确的构造函数应该是Foo b;