牛客刷题:笔试常考题和易错题(长期更新)

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;
}

大家先看调试结果
这里写图片描述
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;
}

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

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;
}

输出结果与分析如下
这里写图片描述

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
这里写图片描述

14,若已定义:int a[9],*p = a;并在以后的语句中未改变p的值,不能表示a[1]地址的表达式是:
A,++p
B,a+1
C,p+1
D,a++
这里写图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值