题目摘录-编程语言(C++)(三)

Q 21 :

题目:
    i的初始值为0,i++在两个线程里面分别执行100次,能得到最大值是(),最小值是()。

答案:
    200
    2

解答:
    考察多线程操作同一未上锁变量。
    1. 每次都准确加1,结果为最大,200。
    2. 结果为2时步骤:
        a取内存0到寄存器,b取内存0到寄存器;
        a执行99次并写入内存,内存值为99;
        b执行1次并写入内存,内存值被覆盖为1;
        a取内存1到寄存器,b取内存1到寄存器;
        b执行99次并写入内存,内存值为100;
        a执行1次,写入内存,覆盖之前的100,值为2。
    3. 每次计算过程必须是先从内存取数然后计算,之后再重新写入内存。但对各个线程而言,取数和计算中间可以被另一个线程打断。

Q 22 :

题目:
    char fun(char x, char y){
        if(x)
            return(y);
    }
    int main(){
        int a = '0', b = '1', c = '2';
        printf("%c\n", fun(fun(a, b), fun(b, c)));
    }

答案:
    2

解答:
    1. 均为字符,非布尔值的0,所以每次返回后者。

Q 23 :

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

答案:
    1

解答:
    1. 一个空类对象的大小是1byte。这是被编译器安插进去的一个字节,这样就使得这个空类的两个实例得以在内存中配置独一无二的地址。

Q 24 :

题目:
    有以下程序:
    #include<stdio.h>
    #include<stdlib.h>
    void fun(int *pl, int *p2, int *s){
        s = (int*)calloc(1, sizeof(int));
        *s = *pl + *p2;
        free(s);
    }
    int main(){
        int a[2] = {1, 2}, b[2] = {40, 50}, *q = a;
        fun(a, b, q);
        printf("%d\n", *q);
    }

答案:
    1

解答:
    考察形参不改变变量值问题。
    1. p是指针变量,但是是值传递,其值(指向数组a首元素的地址)并没有改变。
    2. 通过解引用*p才是数组a的地址,才能改变数组a的值。

Q 25* :

题目:
    在32位操作系统gcc编译器环境下,下面程序的运行结果为:
    #include <iostream>
    using namespace std;
    class A{
    public:
        int b;
        char c;
        virtual void print(){
            cout << "this is father’s fuction! " << endl;
        }
    };
    class B: A{
    public:
        virtual void print(){
            cout << "this is children’s fuction! " << endl;
        }
    };
    int main(int argc, char * argv[]){
        cout << sizeof(A) << " " << sizeof(B) << endl;
        return 0;
    }

答案:
    12
    12

解答:
    考察结构体对齐及虚继承和虚函数继承的区别。
    1. A的大小包括本身的虚函数指针及定义的变量。
    2. B的大小包括本身的虚函数指针和继承自A的变量b和c。
    3. 如果是虚继承,则B的大小会增加4字节,增加的内容为指向虚继承的指针。

Q 26 :

题目:
    有如下语句序列:
    char str[10];
    cin >> str;
    当从键盘输入"I love this game"时,str中的字符串是:

答案:
    I
解答:
    1*. cin遇空格,结束输入。

Q 27 :

题目:
    阅读下面代码,程序会打印出来的值是:
    #include <stdio.h>
    void f(char** p){
        *p += 2;
    }
    int main(){
        char *a[] = {"123", "abc", "456"}, **p;
        p = a;
        f(p);
        printf("%s\r\n", *p);
    }

答案:
    3

解答:
    1. p的类型为char **,(*P)的类型为char *。
    2. p原本指向字符串"123"。
    3. *p是char *类型的,*p + 2表示指向第一个字符串第三个字符。
    4. p是char **类型的,p + 2表示只想第三个字符串,*(p + 2) = "456"。
    5. p的值是*p的地址,虽然p是形参本身值未变,但*p的值在调用函数中被改变。

[Q 28]:

题目:
    下列对函数double add(int a, int b)进行重载,正确的是:

答案:
    int add(int a, int b, int c)
    int add(double a, double b)
    double add(double a, double b)

解答:
    考察重载概念。
    1. 在使用重载时只能通过相同的方法名,不同的参数形式实现。
    2. 不同参数形式包括:
        参数类型不同(至少有一个)
        参数个数不同
        *如果同时在类中,对于函数名相同的const函数和非const函数能够构成重载
    3. 编译器区分重载函数是通过“返回类型 + 函数名 + 参数列表”重新改写函数名还区分重载函数的,但返回值类型在C++中并不作为重载标记。

Q 29 :

题目:
    在linux gcc下,关于以下代码,正确的是:
    std::string& test_str(){
        std::string str = "test";
        return str;
    }
    int main(){
        std::string& str_ref = test_str();
        std::cout << str_ref << std::endl;
        return 0;
    }

答案:
    编译警告
    返回局部变量的引用,运行时出现未知错误
    把代码里的&都去掉之后,程序可以正常运行

解答:
    考察调用函数返回值和变量生命周期问题。
    1. 返回值为局部变量时可以正确运行。
    2. 返回值为指针时,看指针指向的变量实体定义的位置,如果是定义在栈上的变量则会出错,指向静态区则不会有问题。
    3. 引用返回的是局部变量本身,而不是复制一份再返回,所以结果难以预料。
    4. 如果去掉&,string类会调用复制构造函数,形同局部变量返回,可以正常运行。

Q 30 :

题目:
    下面有关继承、多态、组合的描述,说法错误的是:

答案:
    继承可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展
    覆盖是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同

解答:
    考察继承、多态概念。
    1. 父类只有非private的部分才能被子类继承访问。
    2. 重载(overload):函数名相同 、函数参数不同、 必须位于同一个域(类)中。
    3. 覆盖(override):函数名相同 、函数参数相同、 分别位于派生类和基类中(虚函数)。

猜你喜欢

转载自blog.csdn.net/weixin_38337616/article/details/88369197
今日推荐