【C++】笔试训练(四)

一、选择题

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;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柒个葫芦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值