c语言面试笔试易错题,牛客刷题:笔试常考题和易错题(长期更新)

本文探讨了C++中模板类的优势,包括类型无关性、可复用性和类型安全性,并通过实例解析了指针运算和短路逻辑在条件判断中的应用。同时,分析了动态内存分配、引用和指针的区别,以及const常量在C++和C中的不同行为。此外,还介绍了类的构造函数、析构函数的使用规则,以及虚函数在多态中的作用。
摘要由CSDN通过智能技术生成

1,C++中为什么用模板类的原因?(即模板类的优点)

(1)可用来创建动态增长和减小的数据结构

(2)它是与类型无关的,因此具有很高的可复用性

(3)它在编译时而不是在运行时检查数据类型,保证了类型安全

(4)它是与平台无关的,有很强的可移植性

(5)可用于基本数据类型

2,以下程序的输出结果是什么?

int main()

{

int a = 1, b = 2, c = 3, d = 0;

if (a == 1 && b++ == 2)

{

if (b != 2 || c-- != 3)

{

cout << a << " " << b << " " << c << endl;

}

else

{

cout << a << " " << b << " " << c << endl;

}

}

else

{

cout << a << " " << b << " " << c << endl;

}

system("pause\n");

return 0;

}

这道题中与两点需要注意,(1)后置++是先使用再++;(2)||运算和&&运算的短路问题,||:当第一个条件为真时,则后面条件不执行。&&:当第一个条件不成立时,则后面的都不执行。因此,这道题第二个if语句,结果是1 3 3

3,以下代码中,a和b的地址相同吗,为什么?p1和p2地址相同吗,为什么?

int main()

{

int a = 1, b = 2, c = 3, d = 0;

if (a == 1 && b++ == 2)

{

if (b != 2 || c-- != 3)

{

cout << a << " " << b << " " << c << endl;

}

else

{

cout << a << " " << b << " " << c << endl;

}

}

else

{

cout << a << " " << b << " " << c << endl;

}

system("pause\n");

return 0;

}

大家先看调试结果

0818b9ca8b590ca3270a3433284dd417.png

a和b地址不同,p1和p2地址相同,原因是a和b是在栈空间的两个字符数组,地址不同,p1和p2指向的位置在常量区,值都是abcde,所以是同一常量,地址相同。

4,若Myclass是一个类名,则如下语句中调用构造函数的个数是?

Myclass c1,*c2;

Myclass *c3 = new Myclass;

Myclass &c4 = c1;

c1调用一次构造函数,c2是一个指针,用来动态描述对象,不会调用类的构造函数,c3的右边新创建一个对象会调用构造函数,但是注意,这里的赋值运算符不是类中的赋值运算符,而是普通的赋值运算符。c4是一个对象引用,是c1的一个别名,所以不会调用构造函数。

5,传地址或引用时,形参与实参都有相同的地址,传值调用时,只是将数据进行了复制,不会改变实参的值。

6,以下代码,sizeof(list_t) = ?

tyedef struct list_t

{

struct list_t *next;

struct list_t *prev;

char data[0];//柔性数组

}list_t;

柔性数组,把单一元素的数组放在一个struct的尾端,使得每个struct对象可以拥有可变大小的数组,柔性数组不占空间,只是作为一个符号地址存在。所以,sizeof(list_t) = 8

7,在C++中,下面代码的执行结果是?

int main()

{

const int i = 0;

int *j = (int *)&i;

*j = 1;

printf("%d,%d",i,j);

system("pause\n");

return 0;

}

这段代码在C++中的结果是0,1;在C语言中的结果是1,1;原因如下:

C语言中的const是运行时const,编译时只是定义。

而C++中,const变量是编译时的常量,可以像#define定义的常量一样使用,故C++中,const变量额值在编译时就已经确定了,直接对const变量进行了值的替换。

8,下面代码的输出结果是什么?

int main()

{

int a[3];

a[0] = 0, a[1] = 1, a[2] = 2;

int *p, *q;

p = a;

q = &a[2];

cout << a[q - p] << endl;

system("pause\n");

return 0;

}

指针间相减是其地址空间的距离,我用图来解释这道题:

0818b9ca8b590ca3270a3433284dd417.png

9,C++中,为了让某个类只能通过new来创建(即如果直接创建对象,编译器会报错),应该(将析构函数设为私有)。

编译器在为类对象分配栈空间时,会先检查类的析构函数的访问属性,其实不光是析构函数,只要是非静态的函数,编译器就会进行检查,如果类的析构函数是私有的,则编译器不会在栈上为类对象分配内存,因此,将析构函数设为私有,类对象就无法建立在栈(静态)上了,只能在堆上(动态new)分配类对象。

10,来看以下代码

class A

{

public:

virtual void print()

{

cout << "A::print()" << endl;

}

};

class C :public A

{

public:

virtual void print()

{

cout << "C::print()" << endl;

}

};

class B :public A

{

public:

virtual void print()

{

cout << "B::print()" << endl;

}

};

void print(A a)

{

a.print();

}

int main()

{

A a, *aa, *ab, *ac;

B b;

C c;

aa = &a;

ab = &b;

ac = &c;

a.print();

b.print();

c.print();

aa->print();

ab->print();

ac->print();

print(a);

print(b);

print(c);

system("pause\n");

return 0;

}

输出结果与分析如下

0818b9ca8b590ca3270a3433284dd417.png

11,请分析以下代码的输出结果

void f(char* x)

{

x++;

*x = 'a';

}

int main()

{

char str[sizeof("hello")];

strcpy(str, "hello");

f(str);

cout << str<< endl;

system("pause\n");

return 0;

}

输出结果为hallo,f函数的作用是将字符串第二个字符替换成a,由于函数是值传递,不影响指针指向,所以str指针还是从字符串开头开始的。

12,以下 代码的输出结果是?

static int a = 1;

void fun1()

{

a = 2;

}

void fun2()

{

int a = 3;

}

void fun3()

{

static int a = 4;

}

int main()

{

printf("%d", a);

fun1();

printf("%d", a);

fun2();

printf("%d", a);

fun3();

printf("%d\n", a);

system("pause\n");

return 0;

}

输出结果为1 2 2 2,通过分步调试可以看到每一个printf语句中的a地址都是全局变量a的地址。第一个printf输出全局变量a = 1,在调用fun1()时,全局变量a的值被修改为2,而调用其他函数时,a为每个函数的局部变量,出了其作用域即被销毁。因此printf输出的都是全局变量a的值。

13,关于PA、PB、PC的取值,以下说法正确的是?

class A

{

public:

virtual void FunTestA()

{}

};

class B

{

public:

virtual void FunTestB()

{}

};

class C :public B, public A

{

virtual void FunTestC()

{}

};

int main()

{

C c;

A* pA = &c;

B* pB = &c;

C* pC = &c;

system("pause");

return 0;

}

A,pA、pB、pC的取值相同

B,pC和pA不相同

C,pB和pB不相同

D,pC不等于pA,也不等于pB

正确答案选B

0818b9ca8b590ca3270a3433284dd417.png

14,若已定义:int a[9],*p = a;并在以后的语句中未改变p的值,不能表示a[1]地址的表达式是:

A,++p

B,a+1

C,p+1

D,a++

0818b9ca8b590ca3270a3433284dd417.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值