刷c语言练习题13(牛客网)
1、有以下程序
1
2
3
4
5
6
7
8
#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
解析:这道题还是比较容易的,记录的原因是为了在做题时提醒自己注意一些细节。首先在代码中定义了变量m和变量n,变量m以0开头,代表m的值是一个八进制数,n的值是一个十进制数。后面以%o的格式进行打印,并且没有加#,那么就是以无格式前缀的八进制输出。0123本身就是八进制数无需转换,十进制数123转换八进制为173,所以选择选项C。
2、 有以下程序
1
2
3
4
5
6
7
8
#include <stdio.h>
int
main() {
int
i, sum;
for
(i = 1; i < 6; i++)
sum += i;
printf
(
"%d\n"
, sum);
return
0;
}
程序运行后的输出结果是?
A、随机值
B、0
C、15
D、16
答案:A
解析:本题中栈区的局部变量sum未赋初值,计算机会默认赋随机值,所以最后输出的值也为随机值,选择选项A。对于一个局部变量未赋初值就直接拿来用,在学习编写代码的初期时有发生,本题的选项算是给我们一个提示,但如果本题改为填空题或者代码再长一些,那么做错的人就会增加。
3、 若有以下声明和定义
1
2
3
4
5
union
dt {
int
a;
char
b;
double
c;
} data;
以下叙述中错误的是()
A、data的每个成员起始地址都相同
B、变量data所占内存字节数与成员c所占字节数相等
C、程序段:data.a=5;printf("%f\n",data.c);输出结果为5.000000
D、data可以作为函数的实参
答案:C
解析:代码中给出的是一个共用体,共用体的所有成员共用一块空间地址,并且起始地址是相同的,选项A正确。因为共用体只会给最大成员开辟空间,共用体的所有成员共用一块空间地址,所以各个成员所占字节数是相等的,选项B正确。共用体是一种构造类型,可以作为实参传递,但形参的类型要与之对应,选项D正确。选项C中,将共用体成员a赋值为5,并且以%f的格式输出成员c。但是printf函数只是将内存中的数据以不同的类型进行输出,由于整数和浮点数在内存中的存储方式不一致,所以输出的结果不会是与整数等值的浮点数。这也正是共用体强调的为什么是共用一块空间地址,而不是共值。
浮点数在计算机中的存储格式为IEEE754标准:
以float c = 5.000000为例,在内存中占32位。c的值在计算机中分成三个部分进行存储:符号位(S)、阶码(E)、尾码(M)。
符号位(S):占一位,S=1代表为负数,S=0代表为正数
阶码(E):占八位,求5.000000的二进制表示:101.0(本例中小数部分为零,不能体现出小数部分转二进制的过程,下面给出小数部分的计算过程。方法为乘2取整,每次把小数部分乘2,取结果的整数部分,当结果的小数部分为零时结束运算,若产生循环一直得不到零则取近似值),之后要进行小数点的左移,使得二进制的形式变为1.xxxxxxx的形式,这个过程中移动的位数记为n,本例下n=2,E=n+偏移量(127)=129,化成二进制为10000001。
尾码(M):占二十三位,取在算阶码过程中得到的1.xxxxxx形式的数,去掉整数1,剩余的部分为尾码前面的位数,不足32位的部分用0补齐。
根据上面描述的方法,数据5.000000在内存中存储为:
0 10000001 01000000000000000000000 16进制为 40A00000 十进制为 1084227584
为了验证对于选项c的解释给出如下代码:
#include <stdio.h> int main() {union dt{int a;char b;float c;}data;data.a = 1084227584;printf("data.a = %d\n",data.a);printf("data.c = %f\n",data.c);data.a = 5;printf("data.a = %d\n",data.a);printf("data.c = %f\n",data.c); }
代码的运行结果为:
data.a = 1084227584
data.c = 5.000000
data.a = 5
data.c = 0.000000
4、 在上下文及头文件均正常的情况下,下面代码的输出是什么?
1
2
3
4
auto fn = [](unsigned
char
a){
cout << std::hex << (
int
)a << endl;
};
fn(-1);
A、ff
B、256
C、-1
D、Undefined
E、0
答案:A
解析:负数在计算机中以补码的形式进行存储,-1的补码二进制形式为32位全1。将-1作为参数传入函数fn,由于函数fn的形参类型为unsigned char a,传入的为11111111并且最高位不是符号位。(int)a进行强制转换并以16进制形式输出,由于转换后前面补的位为零,所以得到的十六进制输出为ff,选择选项A。
5、 十进制数50表示成符合C语言规定的八进制数为________。
A、20
B、32
C、62
D、062
答案:D
解析:十进制转k进制的方法为除k取余法。记录本题想提醒自己,看着简单的题不要快速作答,要认真读题,如果本题改为填空题要记得前面加0。
6、 如果x=2014,下面函数的返回值是()
1
2
3
4
5
6
7
8
int
fun(unsigned
int
x){
int
n =
0
;
while
(x +
1
){
n++;
x = x | (x +
1
);
}
return
n;
}
A、20
B、21
C、23
D、25
答案:C
解析:首先拿到题目先明确一件事,这样大的数作为参数进入循环绝对不是硬算得出结果,要找规律得出结论。这个规律往往只需要推几步就可以得出:
第一次进入循环:
n=1,00000000 00000000 00000111 11011110 | 00000000 00000000 00000111 11011111
结果:00000000 00000000 00000111 11011111
第二次进入循环:
n=2,00000000 00000000 00000111 11011111 | 00000000 00000000 00000111 11100000
结果:00000000 00000000 00000111 11111111
......
每一次进入循环得出的结果比原来少一个0,并且负责计数的n加一。
可以推得最后一次进入循环后,赋给x的结果为二进制32位全一,下次判断while中的条件,x+1会发生溢出,32位都会变成0从而表达式为假退出循环。
本题确定了是要找规律去解决问题后,也可以用小一点的数去找规律,能更快解决问题。
总之,这段代码主要的功能是统计一个数二进制表示中0的个数,2017的二进制表示为:
00000000 00000000 00000111 11011110,共有23个零,选择选项C。
在我的博客《刷c语言练习题1(牛客网)》中的第49题也是此类型的题,大家感兴趣的可以一起做一下。
7、 X定义如下,若存在则a.y[1]的值可能为()
X a; a.x = 0x11223344; union X{int x;char y[4]; };
A、11
B、22
C、33
D、44答案:BC
解析:
大端模式下,低字节存在高地址,高字节存在低地址。地址从高到低依次存放44332211。
小端模式下,低字节存在低地址,高字节存在高地址,地址从高到低依次存放11223344。
大端存储或小端存储与数组首地址是高地址还是低地址没有直接关系。数组通常是从低地址向高地址连续存储的,即数组的第一个元素存储在低地址,后续元素依次存储在高地址。那么如果是大端存储的情况下,a.y[1]的值为22,如果是小端存储的情况下,a.y[1]的值为33。选择选项BC。
8、 下面关于C语言中sizeof(int)说法正确的是()
A、编译时计算结果
B、运行时计算结果
答案:A
解析:sizeof是一个运算符而不是一个函数,是在编译时就计算出了结果,选择选项A。
拓展:1、与sizeof相比,strlen是一个库函数,strlen函数必须在运行时才能计算出来。
2、sizeof表达式中的运算不会计算。
9、 说明“double(*ptr)[N];”中的标识符ptr是()
A、N个指向double类型变量的指针
B、指向N个double类型变量的函数指针
C、一个指向由N个double类型元素组成的一维数组的指针
D、具有N个指针元素的一维指针数组,其每一个元素都只能指向double类型变量
答案:C
解析:从ptr出发,首先与*结合表明其是一个指针,然后与[N]表明这个指针指向的是一个有N个元素的数组,最后与double结合表明数组中的每一个元素都是double类型,选择选项C。
10、 不合法的main函数命令行参数表示形式是__________
A、main(int a, char *c[])
B、main(int arc, char **arv)
C、main(int argc, char *argv)
D、main(int argc, char *argv[])
答案:C
解析:首先大家都熟悉的main函数的标准函数原型是:
1、int main(int argc,char *argv[])
2、int main()
我进行选择的依据是,函数参数的个数、类型、顺序要与标准函数原型一致,选项A和选项C满足条件。观察选项B,第二个参数为一个二级指针,而标准函数原型中的是一个一级指针数组,让我们分析一下,指针数组的每一个元素都是一个一级指针,而数组名指向数组的首元素,所以一级指针数组的类型本质上是一个二级指针,所以选项B正确,选项C错误。