C++刷题--选择题2

文章详细分析了C++中的指针操作,包括字符串输出、switch语句的执行流程、二维数组的初始化、函数返回多个值的方式以及结构体的内存对齐规则。同时,还探讨了递归函数的执行过程和计算二进制位1的个数的函数。
摘要由CSDN通过智能技术生成

1,以下程序的输出结果是()

#include <stdio.h>
int main() 
{
    char a[10] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', 0}, *p;
	int i;
	i = 8;
	p = a + i;
	printf("%s\n", p - 3);
}

A 6
B 6789
C ‘6’
D 789

解析 :B, p = a + i, 那么 p = &a[8]; p-3 ,那么p = &a[5], 输出格式为 %s,遇到‘\0’停止,‘\0’的值实际上就是0


以下程序的输出结果是()

#include <iostream.h>
int main()
{
		int x=3,y=3;
		switch(x%2)
		{ 
		 case 1:
		switch (y)
		{
		case 0:
			cout<<"first";
		case 1:
			cout<<"second";
			break;
		default:
			cout<<"hello";
		}
		case 2:
		   cout<<"third";
	    }

return 0;
}

A second third
B hello
C first second
D hellothird

解析 : D x % 3 的结果为1, 进入case1,y 的值为3,没有值,进入了默认default,打印了"hello", 然后指向完case1后,由于没有break 语句,所以继续向下执行case2,打印“third”


3,以下能对二维数组a进行正确初始化的语句是()
A int ta[2][]={{0,1,2},{3,4,5}};
B int ta[][3]={{0,1,2},{3,4,5}};
C int ta[2][4]={{0,1,2},{3,4},{5}};
D int ta[][3]={{0,2},{},{3,4,5}};

解析: B, 行标可以省略, 列表是不能省略的。这个可以这样思考, 二维数组其实是由许多个一维数组构成的,你觉得是一维数组的个数重要,还是一维数组中的元素个数重要呢? 显然是后者。 如果行标固定,列表不固定,那每个一维数组的元素都可以胡乱添加,只要满足行标就行了, 而列表固定,可以添加行数,但还是满足行列的要求的。C选项明显错误2行,它却给了3行。 而D选项用法没错,但是第一个一维数组 0和2之间给力 两个逗号。


4,能把函数处理结果的二个数据返回给主调函数,在下面的方法中不正确的是()
A return这二个数
B 形参用数组
C 形参用二个指针
D 用二个全局变量

解析 : A, C/C++的函数只能返回1个数。 B的话用数组实际上是数组元素的起始地址,也是个指针,你知道别人的地址,修改返回当然可以了。


5,int *p[4] 与选择项中的() 等价
A int p[4]
B int *p
C int *(p[4])
D int (*p)[4]

解析 : C,[ ]的优先级非常高,所以p和[ ]先结合, 所以是个数组,然后每个元素是指针int*


6, 设变量已正确定义,以下不能统计出一行中输入字符个数(不包含回车符)的程序段是
A n=0;while(ch=getchar()!=‘\n’)n++;
B n=0;while(getchar()!=‘\n’)n++;
C for(n=0;getchar()!=‘\n’;n++);
D n=0;for(ch=getchar();ch!=‘\n’;n++);

解析 : D, 肯定选择D, 因为for(表达式1;;) , 表达式1称为初始化,只会执行一次


7,以下代码
char *ptr;
char myString[] = “abcdefg”;
ptr = myString;
ptr += 5;

代码执行之后ptr指向的内容是?
A Compiler error
B fg
C efg
D defg

解析 : B , ptr = ptr + 5, 指向下标为5的地址


8,下面3段程序代码的效果一样吗()
int b;
(1)const int *a = &b;
(2)int const *a = &b;
(3)int *const a = &b;

A (2)=(3)
B (1)=(3)
C (1)=(2)
D 都不一样

解析 : C, 其实const作用在哪, 完全取决于放在 * 的前面 还是 * 的后面,放在*的前面,修饰的就是 *p, 防止 *的后面修饰就是p


9, 32位系统中,定义int **a[3][4],则变量占用内存空间为()
A 4
B 48
C 192
D 12

解析 : B, 32位系统下指针是4个字节, 而64位系统下是8个字节。 3 * 4 * 4 = 48


10,假设在一个 32 位 little endian 的机器上运行下面的程序,结果是多少?

#include <stdio.h>
int main()
{
	long long a = 1, b = 2, c = 3;
	printf("%d %d %d\n", a, b, c);
	return 0;
}

解析 : B,32位小端 , 大小端的区别,
大端 : 低地址存放的是数据的高位, 高地址存放的是数据的低位。
小端 : 低地址存放的是数据的低位, 高地址存放的是数据的高位。
可以认为cpu每次都是从低位数据开始读的,long long 是8个字节, 1 的2进制数据 01 00 00 00 00 00 00 00
而%d只读4个字节,当读取a的时候,先把a加入到缓存中,所以第一次读取为 01 00 00 00 也就是1,
第二个%d也读4个字节, 也就是 00 00 00 00 , 第三个%d先将b加入缓存是 02 00 00 00 00 00 00 00
然后第三个%d读的就是 02 00 00 00


有以下程序

#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, 0开头的是8进制数据,把123转换成8进制数据就是173。


12, 以下哪个选项一定可以将flag的第二个bit置0()
A flag&=~2
B flag|=2
C flag^=2
D flag>>=2

解析 : A 2的比特位是 0000 0000 0000 0000 0000 0000 0000 0010 取反 -->1111 1111 1111 1111 1111 1111 1111 1101, 然后的话0按位与0或1都是0.


13,请声明一个指针,其所指向的内存地址不能改变,但内存中的值可以被改变
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 放在*的前面, 修饰的是 *p, 表示指向的值不能改变, 放在 *的后面, 修饰的是指针,则指针不能修改指向的地址。


14以下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, &a —> 取地址数组名取出的是整个数组的地址, 加1跳过整个数组


15, 二维数组X按行顺序存储,其中每个元素占1个存储单元。若X[4][4]的存储地址为Oxf8b82140,X[9][9]的存
储地址为Oxf8b8221c,则X[7][7]的存储地址为()。

A Oxf8b821c4
B Oxf8b821a6
C Oxf8b82198
D Oxf8b821c0

解析 :A, 1个存储单元,相当是一个字节,设每一行有n个元素,那x[9][9] - x[4][4]的地址差为 220, 那他们具体之间隔多少隔元素呢?
n - 4 + (9 - 4 - 1) * n + 9 = 220 , 算出 n 为43, 那x[4][4] 和x[7][7] 又隔多少隔元素呢 ? 43 - 4 + (7 - 4 - 1) * 43 + 7 = 132
132 = 16 ^ 0 * 4 + 16 ^1 * 8 也就是 0x84
最终结果是 : 0xf8b82140 + 0x84 = 0xf8b821c4


16,根据下面递归函数:调用函数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。 递归函数展开 2 * 2 * 2 * 2 = 16


17,
以下程序的输出结果是:

#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是数组的起始地址,数组的起始地址也是二级char** ,所以这里的m++就是向后走一个元素“morning”


18,
求函数返回值,输入x=9999

int func(int x)
{
	int count=0;
	while (x)
	{
		count++;
		x=x&(x-1);//与运算
	}
	 return count;
}

解析 : A, 其实这道题难解,基本上只能蒙, 虽然我们知道这个函数的功能是统计数的二进制位1的个数, 但是9999不用计算机很难知道。


19,

#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, 这个函数的功能是统计递归展开了多少次。可以自己画图数一下, 是67次, 基本上可以猜测预估一下, 从8到结尾2,基本上是6
可以理解位是2 ^ 6


20,在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:4 + 2 + 2 + 4 + 1 + 3 = 16
B: 4 + 2 + 1 + 1 + 4 = 12

扩展问题 : 为什么要有结构体的内存对齐呢?
1, 为了访问数据方便, 因为cpu访问数据的时候, 如果访问没有对齐的数据可能要访问2次,而访问对齐的数据,只用访问一次
2, 可移植性,对于对齐的数据而言,拥有良好的跨平台性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

通过全部用例

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

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

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

打赏作者

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

抵扣说明:

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

余额充值