目录
一、选择题
二、编程题
三、选择题题解
四、编程题题解
一、选择题
1、有以下程序,程序运行后的输出结果是()
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int m=0123, n=123;
printf("%o %o\n", m, n);
return 0;
}
A.0123 0173
B.0123 173
C.123 173
D.173 173
2、以下哪个选项一定可以将flag的第二个bit置0()
A.flag&=~2
B.flag|=2
C.flag^=2
D.flag>>=2
3、请声明一个指针,其所指向的内存地址不能改变,但内存中的值可以被改变。
A.const int const *x = &y;
B.int * const x = &y;
C.const int *x = &y;
D.int const *x = &y;
E.const int * const x = &y;
4、以下C语言指令:运行结果是什么?
int a[5] = {1,3,5,7,9};
int *p = (int *)(&a+1);
printf(“%d,%d”,*(a+1),*(p-1));
A.2,1
B.3,1
C.3,9
D.运行时崩溃
5、二维数组X按行顺序存储,其中每个元素占1个存储单元。若X[4][4]的存储地址为Oxf8b82140,X[9][9]的存储地址为Oxf8b8221c,则X[7][7]的存储地址为()。
A.Oxf8b821c4
B.Oxf8b821a6
C.Oxf8b82198
D.Oxf8b821c0
6、根据下面递归函数:调用函数Fun(2),返回值是多少()
int Fun(int n)
{
if(n==5)
return 2;
else
return 2*Fun(n+1);
}
A.2
B.4
C.8
D.16
7、以下程序的输出结果是:
#include <iostream>
using namespace std;
void func(char **m)
{
++m;
cout<<*m<<endl;
}
int main()
{
static char *a[]={"morning", "afternoon", "evening"};
char **p;
p=a;
func(p);
return 0;
}
A.afternoon
B.字符o的起始地址
C.字符o
D.字符a的起始地址
8、求函数返回值,输入x=9999
int func(int x)
{
int count=0;
while (x)
{
count++;
x=x&(x-1);//与运算
}
return count;
}
A.8
B.9
C.10
D.12
9、下列程序执行后,输出的结果为()
#include <stdio.h>
int cnt = 0;
int fib(int n)
{
cnt++;
if (n == 0)
return 1;
else if (n == 1)
return 2;
else
return fib(n - 1) + fib(n - 2);
}
void main()
{
fib(8);
printf("%d", cnt);
}
A.41
B.67
C.109
D.177
10、在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是()
struct A
{
int a;
short b;
int c;
char d;
};
struct B
{
int a;
short b;
char c;
int d;
};
A.16,16
B.13,12
C.16,12
D.11,16
二、编程题
1、计算糖果 题目链接
2、进制转换 题目链接
三、选择题题解
1、有以下程序,程序运行后的输出结果是()
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int m=0123, n=123;
printf("%o %o\n", m, n);
return 0;
}
A.0123 0173
B.0123 173
C.123 173
D.173 173
正确答案:C
题解:
此题考查进制之间的转换以及各进制的前缀,首先我们明确计算机世界中,有许多进制,我们要记住最常用的机制的前缀,比如二进制的前缀为0B,八进制的前缀为0,十进制无前缀,十六进制的前缀为0X;此题m是一个八进制的数,n是一个十进制的数,打印时,要求我们按照八进制打印,因此将n转换为八进制为0173,故打印结果为C选项
2、以下哪个选项一定可以将flag的第二个bit置0()
A.flag&=~2
B.flag|=2
C.flag^=2
D.flag>>=2
正确答案:A
题解:
选项A,2转换为二进制为0000 0010(此处以8个比特位为例),对其取反后为1111 1101,此时我们那这个数和任何数进行按位与,第二个比特位都为0,回忆一下按位与的规则,一零则零,都一才一;
3、请声明一个指针,其所指向的内存地址不能改变,但内存中的值可以被改变。
A.const int const *x = &y;
B.int * const x = &y;
C.const int *x = &y;
D.int const *x = &y;
E.const int * const x = &y;
正确答案:B
题解:
根据题意知,题目想让我们找到指针常量,我们判断修饰其指向内容就要放在*前,修饰这个指针则必须放在*后,标识符前;故选B;
4、以下C语言指令:运行结果是什么?
int a[5] = {1,3,5,7,9};
int *p = (int *)(&a+1);
printf(“%d,%d”,*(a+1),*(p-1));
A.2,1
B.3,1
C.3,9
D.运行时崩溃
正确答案:C
题解:
本题考察对指针的理解,p被(int*)(&a + 1)赋值,而&a取到的是整个数组的地址,因此对其+1·跳过整个数组,指向最后一个元素的下一个位置;并对其强制类型转换成int*,而打印时,打印a+1,a代表首元素地址,+1,代表第二个元素地址,打印3,p-1指向最后一个元素地址,故打印9;选C;
5、二维数组X按行顺序存储,其中每个元素占1个存储单元。若X[4][4]的存储地址为Oxf8b82140,X[9][9]的存储地址为Oxf8b8221c,则X[7][7]的存储地址为()。
A.Oxf8b821c4
B.Oxf8b821a6
C.Oxf8b82198
D.Oxf8b821c0
正确答案:A
题解:
本题主要考察十六进制之间的计算,本题给出我们x[4][4]与x[9][9]的地址,我们不妨计算都计算出他们开始的地址,也就是x[4][0]与x[9][0]的地址,然后相减得到的数字除以5,就是每一行最多有多少个字节,然后在将x[4][0]加上3倍的行字节再加上7,便是最后结果;
6、根据下面递归函数:调用函数Fun(2),返回值是多少()
int Fun(int n)
{
if(n==5)
return 2;
else
return 2*Fun(n+1);
}
A.2
B.4
C.8
D.16
正确答案:D
题解:
本题考察对递归的理解,我们不难算出结果为16,可通过如下递归展开图理解;
7、以下程序的输出结果是:
#include <iostream>
using namespace std;
void func(char **m)
{
++m;
cout<<*m<<endl;
}
int main()
{
static char *a[]={"morning", "afternoon", "evening"};
char **p;
p=a;
func(p);
return 0;
}
A.afternoon
B.字符o的起始地址
C.字符o
D.字符a的起始地址
正确答案:A
题解:
首先要弄清本题答案,得小知道a是什么,a是一个数组,数组中存放着三个字符指针,分别指向三个字符串,p是一个二级指针,把a赋值给p,也就是将第一个指针的地址给p,我们把p传给m,并对m+1,跳过其指向数据的类型,char** m指向的是一个char*,因此跳过一个char*,指向第二个字符串的指针的地址,对其解引用打印,则打印第二个字符串;
8、求函数返回值,输入x=9999
int func(int x)
{
int count=0;
while (x)
{
count++;
x=x&(x-1);//与运算
}
return count;
}
A.8
B.9
C.10
D.12
正确答案:A
题解:
我们不难推测出,x=x&(x-1)是消除数字的二进制中最低位的1,实际上这个循环就是查看该数的二进制表示中,有多少个1,故结果A;
9、下列程序执行后,输出的结果为()
#include <stdio.h>
int cnt = 0;
int fib(int n)
{
cnt++;
if (n == 0)
return 1;
else if (n == 1)
return 2;
else
return fib(n - 1) + fib(n - 2);
}
void main()
{
fib(8);
printf("%d", cnt);
}
A.41
B.67
C.109
D.177
正确答案:B
题解:
由题意不难知,我们要求的是斐波那契数列的递归次数,我们f(0)递归了1次,f(1)递归了1次,f(2) = 1(自己)+f(0) + f(1)=3次,依次类推;
10、在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是()
struct A
{
int a;
short b;
int c;
char d;
};
struct B
{
int a;
short b;
char c;
int d;
};
A.16,16
B.13,12
C.16,12
D.11,16
正确答案:C
题解:
首先,我们的了解结构体对齐规则;如下所示;
首先是A结构体,第一个成员a为整型,占0-3字节的空间,b成员为short,必须再2的整数倍的地址处,因此占4-5字节,c成员为整型,必须为4的整数倍,因此占8-11字节,最后d为char类型,必须为1的整数倍,因此占12字节,有根据结构体对齐规则,必须为最大对齐数的整数倍,故一共占16字节,B类也同理推导;如下图;
四、编程题题解
1、计算糖果
我们将四个表达式(A - B, B - C, A + B, B + C)得值依次保存进num1,num2,num3,num4中;不难发现有以下关系;
为什么最后需要验证一下呢,因为这里的出发都是整形除法,如果存在不成立的等式;代码如下;
#include <iostream>
using namespace std;
int main()
{
int num1, num2, num3, num4;
int A, B1, B2, C;
cin >> num1 >> num2 >> num3 >> num4;
A = (num1 + num3) / 2;
B1 = (num3 - num1) / 2;
B2 = (num2 + num4) / 2;
C = (num4 - num2) / 2;
if(B1 == B2)
{
cout << A << " " << B1 << " " << C;
}
else
{
cout << "No" << endl;
}
}
2、进制转换
本题依旧可以考虑使用类似于除十取余法,只不过这里不除十,除n,每次取余得到n进制的最低位,然后对其除n,循环此步,由于n的范围是2到16,因此,我们还要考虑出现的余数大于等于10的情况,此时需要用ABCDEF代替,因此,我们需要开辟一个字符数组,一一对应;具体代码如下;
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string str, num_str;
num_str = "0123456789ABCDEF";
int m, n;
cin >> m >> n;
// 防止m为0的情况
if(m == 0)
{
cout << 0 << endl;
return 0;
}
// 判断m正负
int flag = 0;
if(m < 0)
{
m *= -1;
flag = 1;
}
while (m)
{
int num = m % n;
str += num_str[num];
m /= n;
}
// 如果为负数,尾插'-'
if(flag)
{
str += "-";
}
// 逆置得到正确结果
reverse(str.begin(), str.end());
cout << str << endl;
}