问答题
问答题1:下列选项正确的是?
void swap_int(int *a,int *b){
*a=*a+*b;
*b=*a-*b;
*a=*a-*b;
}
A 结果不正确,因为会溢出,用位与的方式就没问题
B 结果正确,即使会溢出
C 结果正确,不会溢出
D 其他选项都不对
提示:以 4bit 为例
设a = -5,b = -7
-5 = 1011 (补码)
-7 = 1001 (补码)
-5 + (-7) = 10100 = 0100=4 (溢出后为4)
4-(-7)= 4 +7=0100 + 0111 = 1011 = -5 的补码
4-(-5)= 4 + 5 = 0100 + 0101 = 1001 = -7 的补码
答案:B
问答题2:下列代码的输出是?(print已经声明过)
main(){
char str[]="Geneius";
print (str);
}
print(char *s){
if(*s){
print(++s);
printf("%c",*s);
}
}
问答题3:下列代码输出啥?
#include <iostream>
using namespace std;
int main(void){
const int a = 10;
int * p = (int *)(&a);
*p = 20;
cout<<"a = "<<a<<", *p = "<<*p<<endl;
return 0;
}
提示:注意这个是C++编译器,对于 const 常量在编译期间会编译成一张常量表,读取常量的操作都会从常量表直接读取,这是编译器针对const 常量做的优化,该操作类似于宏替换,只要遇到 a 就会输出 10,但是我们要知道,p 指向的地址内容确实已经改变了,变为20,可以通过解引用的操作取出地址的值;但是在 C编译里,不会对 const 常量做优化,所以输出的a 和 *p 都是 20
问答题4:以下代码共调用多少次拷贝构造函数?
Widget f(Widget u){
Widget v(u);
Widget w=v;
return w;
}
void main(){
Widget x;
Widget y=f(f(x));
}
提示:首先函数传参的时候,第一次拷贝构造,在函数里面有两次,第二层函数嵌套,里面又有三次拷贝构造,最后一个是拷贝构造 y
答案:7 次
问答题5: 以下代码有什么问题?
struct Test{
Test(int) {}
Test() {}
void fun() {}
};
int main() {
Test a(1);
a.fun();
Test b();
b.fun();
return 0;
}
(A)b.fun()会出错
(B)Test结构的定义中应该加上public修饰符,这样才能main函数中调用改类的方法
(C)Test(int){} 应该改成Test(int a){}
(D)以上说法都不正确
提示:Test b()
只是进行了函数声明,并不是构造b对象,所以使用函数名去调用成员函数,肯定会出错
问答题6:在32位环境下,以下程序的输出结果是?
class Base{
public:
virtual int foo(int x){
return x * 10;
}
int foo(char x[14]){
return sizeof(x) + 10;
}
};
class Derived : public Base{
int foo(int x){
return x * 20;
}
virtual int foo(char x[10]){
return sizeof(x) + 20;
}
};
int main(){
Derived stDerived;
Base *pstBase = &stDerived;
char x[10];
printf("%d\n", pstBase->foo(100) + pstBase->foo(x));
return 0;
}
提示:pstBase->foo(100);
由于基类指针指向子类对象,所以会调用子类的foo函数,返回2000,pstBase->foo(x)
传入进去的是一个指针,指针在32位操作系统下为4个字节
答案:2014
编程题
编程题1: 取手套
在地下室里放着n种颜色的手套,手套分左右手,但是每种颜色的左右手手套个数不一定相同。A先生现在要出门,所以他要去地下室选手套。但是昏暗的灯光让他无法分辨手套的颜色,只能分辨出左右手。所以他会多拿一些手套,然后选出一双颜色相同的左右手套
现在的问题是,他至少要拿多少只手套才能保证一定能选出一双颜色相同的手套
给定颜色种数n(1≤n≤13),同时给定两个长度为n的数组left,right,分别代表每种颜色左右手手套的数量。数据保证左右的手套总数均不超过26,且一定存在至少一种合法方案
测试样例:4,[0,7,1,6],[1,5,0,6]
返回:10(解释:可以左手手套取2只,右手手套取8只)
解题思路:本题的意思是随意取出的手套至少可以形成一组组合的最少手套数量。题目给的两个数组对应位置表示同一种颜色的左右手套数量。对于非0递增序列a1,a2…an,要想最终取值覆盖每一个种类 n =sum(a1…an) -a1 +1(也就是总数减去最小值之后加一) 所以对于左右手手套颜色都有数量的序列,想要覆盖每一种颜色,则最小数量leftsum = 左边数量和 - 左边最小值 +1, rightsum =右边数量和 -右边的最小值 +1。而对于有0存在的,则需要做累加,保证覆盖每一种颜色。
class Gloves{
public:
int findMinimum(int n, vector<int> left, vector<int> right) {
int left_sum = 0, left_min = INT_MAX;
int right_sum = 0, right_min = INT_MAX;
int sum = 0;
// 遍历每一种颜色的左右手套序列
for(int i=0;i<n;i++){
//对于有0存在的颜色手套,累加
if(left[i]*right[i]==0)
sum += left[i] + right[i];
// 对于左右手都有的颜色手套,执行累加 - 最小值 +1
// 找到最小值和总数
else{
left_sum += left[i];
right_sum += right[i];
left_min = min(left_min, left[i]);
right_min = min(right_min, right[i]);
}
}
//结果为有左右都有数量的手套序列的结果+有0存在的手套数+最后再加一肯定就能保证了
return sum +
min(left_sum-left_min+1, right_sum-right_min+1) + 1;
}
};