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):函数名相同 、函数参数相同、 分别位于派生类和基类中(虚函数)。