今天是2月27日,做题第二天。“躺平”不可取,“躺赢”不可能。让我们一起继续加油,在心里种花,人生才不会荒芜!
第一题
32位系统中,如下程序执行的结果是()
#include <stdio.h>
int main()
{char str[] = {"hello world"};printf("%s",str);return 0;
}
A---“hello”
B---NULL
C---“hello world”
D---“h”
正确答案:C
解析:在数组名作为函数参数的时候,会退化成指针。也就是说数组名实际上就成了一个指针变量,故输出字符数组。
第二题
假定变量i、f和d的数据类型分别为int、float和double(int用补码表示,float和double分别用IEEE754单精度和双精度浮点数格式表示),已知i=785,f=1.5678e3,d=1.5e100。若在32位机器中执行下列关系表达式,则结果为“真”的是()
Ⅰ.i==(int)(float)i Ⅱ.f==(float)(int)f
Ⅲ.f==(float)(double)f Ⅳ.(d+f)-d==f
A---仅Ⅰ和Ⅱ
B---仅Ⅰ和Ⅲ
C---仅Ⅱ和Ⅲ
D---仅Ⅲ和Ⅳ
正确答案:B
解析:这题考察了自动类型转换规则 ,如果两个操作数的类型不同,C语言会自动将较低精度的操作数转换为较高精度的类型,然后在进行运算。整数类型之间的自动转换按照以下顺序:char->short->int->unsigned int->long->unsigned long->float->double。需要注意的是,自动类型转换可能导致精度损失或溢出问题,因此在进行精确计算时,应该使用适当的数据类型,并进行显式的类型转换。
接下来叫我们一起来看看这道题吧!对于Ⅰ和Ⅲ,从低到高的转换通常可以保持其值不变。而Ⅱ,先将float型的f转换成int型,小数点后的数位丢失,故其结果不为真。对于Ⅳ,根据不同类型数据混合运算的“类型提升”原则,等号左端的类型为double类型,结果不为真。
第三题
以下叙述中正确的是()
A---字符串常量“Hello”会被隐含处理成一个无名字符型数组,它有5个元素
B---不能用字符串常量对字符数组名进行整体赋值操作
C---char str[7]="string!";在语法上是合法的,运行也是安全的
D---char *str;str="Hello";与char str[];str="Hello";效果是一样的
正确答案:B
解析:A选项中,字符串常量“Hello”会被隐含处理成一个无名字符型数组,它有六个元素。C选项中,char str[7]="string!"在语法上是非法的,str数组长度为7,字符串“string!”长度为8,数组界限溢出。D选项中,char *str;str="Hello"是合法的。char str[];str="Hello"是非法的,数组名是常量,无法赋值。
第四题
执行以下代码段(程序已包含所有必需的头文件)会输出什么结果。()
char a[3];char b[] = "good";a = b;printf("%s", a);
A---go
B---goo
C---good
D---编译出错
正确答案:D
解析:a和b均为数组名,代表数组的首地址,无法相互赋值。
第五题
声明一个指向含有10个元素的数组的指针,其中每个元素是一个函数指针,该函数的返回值是int,参数是int *,正确的是()
A---(int *p[10])(int *)
B---int[10]*p(int *)
C---int(*(*p)[10])(int *)
D---int ((int *)[10])*p
正确答案:C
解析:先看未定义标识符p,p的左边是*,*p表示一个指针,跳出括号,由于[]的结合性大于*,所以*p指向一个大小为10的数组,即(*p)[10]。左边又有一个*号,修释数组的元素,*(*p)[10]表示*p指向一个大小为10的数组,且每个数组的元素为一个指针。跳出括号,根据右边(int *)可以判断(*(*p)[10])是一个函数指针,该函数的参数是int *,返回值是int。所以选C。
第六题
下面程序的输出是什么?
int main(void)
{int a[5] = {1, 2, 3, 4, 5};int *ptr = (int *)(&a + 1);printf("%d %d", *(a + 1), *(ptr - 1));return 0;}
A---2 1
B---2 5
C---1 2
D---5 2
正确答案:B
解析:这题主要要理解“数组的地址”和“数组首元素的地址”,这是两个不同的概念。*(a+1)就是a[1],输出为2 。&a就是数组的地址,&a+1就相当于加一个数组,即偏移一个数组。a是长度为5的int数组指针,所以要加5*sizeof(int),所以第四句语句执行后,ptr指向a[5];最后输出时,即*(ptr-1)时,ptr为int型指针,则-1操作减少sizeof(int *),指向a[4],输出为5 。
第七题
参考以下代码,在大端字节机器中想x.c的值为
union A
{short c;char buf[4];
} x = {0x01, 0x02, 0x03, 0x04}
A---0x0102
B---0x2010
C---0x3040
D---0x4030
正确答案:A
解析:根据题意x中的存储内容从低地址到高地址为01020304,如果将这个联合体解释为short类型,由于short类型占两个字节的存储空间,那么联合体的最低两个字节有效,也就是0102.又因为是大端存储,低地址占据最高有效位,所以实际的十六进制值为:0x0102 。
我们在书写的时候,对于地址,一般是低地址在左,高地址在右;而对于各种进制的数值,确是最高有效位在左,最低有效位在右,这是在理解大小端问题时我们需要注意的地方。
第八题
int A[2][3] = {1,2,3,4,5,6};则A[1][0]和*(*(A+1)+1)的值分别是()
A---4 5
B---4 3
C---3 5
D---3 4
正确答案:A
解析:对*(*(A+1)+1)进行剖析,A为(一维数组)首元素地址,即元素 123 的地址。所以(A+1)为元素 456 的地址。*(A+1)解引用为数组 4 5 6,*(A+1)为数组名,也是首元素地址,而 *(A+1)+1 为元素 5 的地址,解引用 *(*(A+1)+1)为 5 。
第九题
以下程序的输出结果是()
int main()
{int a[3][3] = {{1, 2}, {3, 4}, {5, 6}}, i, j, s = 0;for(i = 1; i < 3; i++)for(j = 0; j <= i; j++) s += a[i][j];printf("%d\n", s++);
}
A---18
B---19
C---20
D---21
正确答案:A
解析:首先,可以先把数组画出来
a[3][3] = {{1, 2}, {3, 4}, {5, 6}}
= 1 2 0
3 4 0
5 6 0
然后,分析循环
i=1, i<3 {1, 2}
j=0, j <= i i = 1 时 { (1, 0), (1, 1) }
i = 2 时 { (2, 0), {2, 1), (2, 2) }
得到对应的下标后,再对照刚才画的数组,挨个找对应元素:
a[1][0] = 3
a[1][1] = 4
a[2][0] = 5
a[2][1] = 6
a[2][2] = 0
sum = 18
最后 sum++ 是后置加加, 所以 printf 取18。
第十题
下面声明正确的是()
A---int a[5]={0,1,2,3,4,5};
B---char a[]={0,1,2,3,4,5};
C---char a={'A','B','C'};
D---int a[5]={0123};
正确答案:BD
解析:A选项a越界了。C选项a变量是一个char类型不是数组。D选项是这道题的易错选项,0123是八进制表示法,即83,后面4个数默认初始化为0 。也就是int a[5]={83,0,0,0,0};
追逐梦想的道路没有一条是平坦的,只有那些不畏艰难,能够不懈沿着陡峭的山路去攀登的人,才有可能去到达光辉的顶点!再坚持一下吧,当你身处黑暗,你能做的就是自己成为那束光,照亮自己。没关系,天空越黑,星星越亮,相信自己的能力,一定要努力成为更好的自己。