目录
- 一、选择题
- 二、编程题
- 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
解析:二进制表现方式:101010b
八进制表现方式:0123
十进制表现方式:123
十六进制表现方式:0x123或123h
所以m是八进制,n是十进制
%d:以十进制方式输出
%o:八进制方式输出
%x:十六进制方式输出
2、以下哪个选项一定可以将flag的第二个bit置0()
A flag&=~2
B flag|=2
C flag^=2
D flag>>=2
答案:A
解析:假设flag的值是10,二进制是0000 1010,按位或是有1为1,按位与是有0为0,按位异或是相异为1,所以只有按位与可以,所以选择A。也可以把值带入选项计算,A计算为0000 1000,B计算为0000 1010,C计算为0000 0010,D计算为0000 0010
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
解析:常量指针:所指空间的值是一个常量,能改变指针的指向。
指针常量:不能改变指针的指向,但是可以指针解引用改变所指空间的值
区分:const在 * 左边就是常量指针,在 * 右边就是指针常量
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
解析:数组名只有在 & 和sizeof之后,才表明是数组本身,&a也是一个地址,该地址类型为:int( * )[5],是一个数组指针,(&a + 1)取地址后,加1表示&a向后偏移5个整形元素的大小,所以指向数组的末尾,类型是一个数组指针类型,与p类型不同,所以强转为int *类型
5、二维数组X按行顺序存储,其中每个元素占1个存储单元。若X[4][4]的存储地址为Oxf8b82140,X[9][9]的存储地址为Oxf8b8221c,则X[7][7]的存储地址为()。
A Oxf8b821c4
B Oxf8b821a6
C Oxf8b82198
D Oxf8b821c0
答案:A
解析:假设数组X的起始地址为start,总共有M行,N列
&X[4][4] = start + 4 * N + 4 = 0xf8b82140
&X[9][9] = start + 9 * N + 9 = 0xf8b8221c
组成一个二元一次方程组
我们用第二种方式:
&X[4][4] = 0xf8b82140
&X[4][9] = 0xf8b82145
&X[9][9] = 0xf8b8221c
而X[4][9]和X[9][9]之间刚好相隔了5行
0xf8b8221c - 0xf8b82145 = 5 * N
D7 = 5 * N
所以5行中共有D7个元素,即有215个元素,N = 215/5 = 43,所以一行有43个元素
&X[7][7] = &X[7][9] - 2 -> &X[4][9] + 3 * 43 - 2
0xf8b82145 + 127 -> 0xf8b82145 + 0x7F = 0xf8b821c4
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
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
解析:数组名只有在 & 和sizeof之后,才表明是数组本身,所以数组的首元素是"morning",而这个"morning"的类型是char * ,要想p=a,p就必须给成二级指针,++m,指针就向后偏移一个位置,指向"afternoon"
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 = 7 -> 111
第一次循环:count++ --> count = 1,x = 7&6 = 111 & 110 = 110
第二次循环:count++ --> count = 2,x = 6&5 = 110 & 101 = 100
第三次循环:count++ --> count = 3,x = 4&3 = 100 & 000 = 000
所以func的功能是返回x中总共有多少个1
9999 -> 10 0111 0000 1111
所以有8个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
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
解析:
二、编程题
1、计算糖果
入口:题目链接
题目描述:
题目解析:
A,B,C是三个人手里的糖果数量,我们不知道A,B,C是多少?但是我们知道A - B, B - C, A + B, B + C的结果,这个结果题目是通过输入测试用例给我们的。所以本题本质是一个表达式求解问题。
解题思路:
1、A - B = a。2、B - C = b。 3、A + B = c。 4、B + C = d 这道题目的实质是:判断三元一次方程组是否有解及求解,1+3可以得到A=(a+c)/2;4-2可以得到C=(d-b)/2;2+4可以得到B2=(b+d)/2,3-1可以得到B1=(c-a)/2;
如果B1不等B2则表达式无解
代码展示:
#include <iostream>
using namespace std;
int main()
{
int a, b, c, d;
cin >> a >> b >> c >> d;
int A = (a + c) / 2;
int B1 = (b + d) / 2;
int B2 = (c - a) / 2;
int C = (d - b) / 2;
if (B1 != B2)
{
cout << "No" << endl;
}
else
{
cout << A << " " << B1 << " " << C << endl;
}
return 0;
}
2、进制转换
入口:题目链接
题目描述:
题目解析:
将10进制的数转换成N进制。N(2 ≤ N ≤ 16)可以看出进制最多可以到16进制。
代码展示:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string str, table = "0123456789ABCDEF";
int m, n;
cin >> m >> n;
if (m == 0)
{
cout << 0 << endl;
}
bool flag = false;
if (m < 0)
{
m = -m;
flag = true;
}
while (m != 0)
{
str = str + table[m % n];
m /= n;
}
if (flag == true)
{
str += "-";
}
reverse(str.begin(), str.end());
cout << str << endl;
return 0;
}