6/18作业

思维导图

复习

6/18作业_第1张图片

 

 6/18作业_第2张图片

1.

语句

1

for(a = 0, b = 0; b != 100 && a < 5; a++) scanf("%d", &b); 

scanf最多可执行次数为:( )

A

4

B

6

C

5

D

1

正确答案:C

官方解析:

这道题目考察了for循环和scanf执行的逻辑关系。C选项5次是正确答案,让我们来分析原因:

for循环的条件是b!=100 && a<5,其中:
1. a从0开始,每次循环加1,直到a<5不成立
2. b初始值为0,通过scanf读入新值
3. 循环终止条件是b==100或a>=5中任一个满足

所以scanf最多执行5次的原因是:
- 如果前5次输入的b都不等于100,那么当a增加到5时,a<5条件不再满足,循环结束
- 如果在执行过程中输入的某个b等于100,循环会提前结束
- 无论哪种情况,scanf都不可能执行超过5次

分析其他选项:
A选项4次错误:a可以从0递增到4,共5次机会
B选项6次错误:当a=5时循环条件已经不满足,不可能执行第6次
D选项1次错误:除非第一次就输入b=100,否则循环会继续执行

这个题目的关键是理解for循环的终止条件和scanf执行次数的对应关系,最多情况就是b始终不等于100,此时会执行到a=4这第5次。

知识点:C++、C语言

题友讨论(11) 

单选题

C语言

2.

十进制变量i的值为100,那么八进制的变量i的值为()

A

146

B

148

C

144

D

142

正确答案:C

官方解析:

这道题目考察了进制转换的知识点,具体是将十进制数100转换为八进制数。

要将十进制转换为八进制,我们可以通过除8取余的方法,从下往上读取余数:
100 ÷ 8 = 12 余 4
12 ÷ 8 = 1 余 4
1 ÷ 8 = 0 余 1

从下往上读取余数,得到八进制数:144

因此,十进制的100等于八进制的144,C选项正确。

分析其他选项:
A选项146:计算错误,146(八进制)=(1×8²)+(4×8¹)+(6×8⁰)=64+32+6=102(十进制)
B选项148:计算错误,148(八进制)=(1×8²)+(4×8¹)+(8×8⁰)=64+32+8=104(十进制)
D选项142:计算错误,142(八进制)=(1×8²)+(4×8¹)+(2×8⁰)=64+32+2=98(十进制)

这道题目主要考察了对八进制的理解和十进制转八进制的计算能力。八进制是以8为基数的数制,每一位上的数字范围是0-7。

知识点:C语言

题友讨论(5) 

单选题

C语言

3.

有以下程序,则数值为91的表达式为:

 Int a[10]={11,21,31,41,51,61,71,81,91,101},*p=a;

A

*p+9

B

*(p+8)

C

*p+=9

D

p+8

正确答案:B

官方解析:

定义一个长度为10的整型数组a,将a的首地址赋给了指针p。指针可以进行整数加减运算,其含义是指针的移动。因p指向a[0]那么p+8就指向a[8],*(p+8)代表p=8指向的内容就是a[8]的内容,即为91.

知识点:C语言

题友讨论(2) 

单选题

C语言

4.

要交换变量A和B的值,应使用的语句组( ) 

A

A=B;B=C;C=A

B

C=A;A=B;B=C

C

A=B;B=A

D

C=A;B=A;B=C

正确答案:B

官方解析:

在交换两个变量的值时,需要使用第三个临时变量作为中转,正确的交换步骤应该是:
1. 先将A的值保存到临时变量C中(C=A)
2. 将B的值赋给A(A=B)
3. 最后将临时变量C中保存的原A值赋给B(B=C)

因此选项B(C=A;A=B;B=C)给出的语句顺序是正确的。

分析其他选项:
A选项(A=B;B=C;C=A)错误:第一步就将A的值改为B,导致A的原值丢失,后续无法完成正确交换。

C选项(A=B;B=A)错误:没有使用临时变量,直接互相赋值会导致数据丢失。例如执行A=B后,A的原值就丢失了,再执行B=A实际上是将B的值又赋回B。

D选项(C=A;B=A;B=C)错误:虽然使用了临时变量C,但是B=A这步操作导致B的原值丢失,不能完成交换。

这个问题体现了在编程中使用临时变量来保存中间状态的重要性,也说明了操作的顺序对结果的影响。

知识点:C语言

题友讨论(3) 

单选题

C语言

5.

在 C 语言中有如下声明:char color = ‘B’; 请问’B’和color分别占()内存。

A

1字节、1字节

B

1字节、2字节

C

2字节、1字节

D

2字节、2字节

正确答案:A

官方解析:

字符变量占用一个字节,所以color占1字节。

字符常量存储为int类型(不是char类型),也就是说‘B’通常占用2或4字节,但实际上只使用int的1字节存储‘B’的编码。

所以正确答案为A。

知识点:C语言

题友讨论(0) 

单选题

C++

C语言

6.

以下能对二维数组a进行正确初始化的语句是(        )

A

int a[2][ ]=({1,0,1},{5,2,3});

B

int a[ ][3]={{1,2,3},{4,5,6}};

C

int a[2][4]=({1,2,3},{4,5},{6});

D

int a[ ][3]={(1,0,1)(),(1,1)};

正确答案:B

官方解析:

二维数组初始化需要严格遵循C语言的语法规则。B选项是正确的,因为它符合标准的二维数组初始化语法:指定了列数(3),使用了正确的大括号嵌套,且数据完整。

分析其他选项的错误原因:

A选项错误:
- 使用了圆括号({1,0,1},{5,2,3}),而数组初始化应该用大括号
- 第二维度的大小未指定,且使用了错误的分隔符

C选项错误:
- 使用了圆括号而不是大括号
- 数组各行元素个数不一致,且超出了声明的列数限制(声明4列但实际数据不足)
- 大括号嵌套结构不正确

D选项错误:
- 使用了圆括号(1,0,1)而不是大括号
- 初始化列表语法错误,使用了()作为行间分隔符
- 数据结构混乱,不符合二维数组初始化规范

正确的二维数组初始化应该:
1. 必须使用大括号,不能用圆括号
2. 指定列数(或行数)
3. 保持数据结构完整且符合声明的维度
4. 正确使用嵌套的大括号语法

知识点:C++、C语言

题友讨论(20) 

单选题

C语言

7.

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

1

2

3

4

5

main() {

    int a=4, b=5, c=0, d;

    d = !a&&!b||!c;

    printf("%d\n",d);

}

A

1

B

0

C

非0的数

D

-1

正确答案:A

官方解析:

这道题目考察了C语言中逻辑运算符的运算规则和优先级。让我们逐步分析表达式 d = !a&&!b||!c 的计算过程:

1. !a 的计算:
a=4(非0), 所以!a=0

2. !b 的计算:
b=5(非0), 所以!b=0

3. !c 的计算:
c=0, 所以!c=1

4. 按照运算符优先级,先计算 !a&&!b:
0&&0=0

5. 最后计算 0||!c:
0||1=1

因此 d 的最终值为1,所以 A 选项是正确答案。

分析其他选项:
B选项(0)错误:最终结果是1而不是0
C选项(非0的数)虽然从技术上说1也是非0的数,但是题目明确给出的结果就是1
D选项(-1)错误:逻辑运算的结果只可能是0或1

需要注意的要点:
1. ! 运算符的结果只有0和1
2. 逻辑运算符&&和||的运算结果也只有0和1
3. &&优先级高于||
4. 在C语言中,非0值都认为是真,0认为是假

知识点:C语言

题友讨论(21) 

单选题

C++

C语言

8.

以下逗号表达式的值为()

1

(x=4*5, x*5), x+25

A

25

B

20

C

100

D

45

正确答案:D

你的答案:B

官方解析:

这道题目考察了C/C++中逗号表达式的运算规则。

逗号表达式的计算规则是从左到右逐个计算表达式的值,但最终整个逗号表达式的值是最后一个表达式的值。

让我们来逐步分析这个表达式 (x=4*5, x*5), x+25:

1. 首先计算括号内的逗号表达式(x=4*5, x*5)
- x=4*5 执行赋值,x被赋值为20
- x*5 计算得100,这是括号内逗号表达式的值
- 但这个100并没有被使用

2. 最后计算 x+25
- 此时x的值是20(在第一步被赋值)
- 所以x+25 = 20+25 = 45
- 这是整个表达式的最终值

因此选D:45是正确的。

分析其他选项:
A(25)错误:这个值没有任何计算过程能得到25
B(20)错误:这只是x的中间值
C(100)错误:虽然在括号内的逗号表达式计算过程中出现过100,但它是中间结果,不是最终值

这类题目的关键是要理解逗号表达式的特点:只保留最后一个表达式的值作为整个表达式的值。

知识点:C++、C语言

题友讨论(51) 

单选题

C++

C语言

9.

在32位的系统中,下面代码打印结果为()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

union package {

    char head;

    int  body;

};

struct message {

    char id;

    int  crc;

    union package pack;

};

int main() {

    printf("size=%d\n",sizeof(struct message));

    return 0;

}

A

9

B

10

C

11

D

12

正确答案:D

你的答案:C

官方解析:

要计算结构体message的大小,需要考虑内存对齐和填充的规则。让我们逐步分析:

1. 结构体message包含三个成员:
- char id (1字节)
- int crc (4字节)
- union package pack (联合体)

2. 联合体package的大小:
- 包含char head(1字节)和int body(4字节)
- 联合体的大小由最大成员决定,所以是4字节

3. 内存对齐规则:
- 一般系统中int类型按4字节对齐
- char类型不需要特别对齐
- 整个结构体按照最大成员(int)的大小对齐,即4字节对齐

4. 计算过程:
- char id占1字节,后面填充3字节以对齐int
- int crc占4字节
- union package pack占4字节

所以总大小为: 1(id) + 3(填充) + 4(crc) + 4(pack) = 12字节

因此D选项12是正确答案。

其他选项分析:
A(9字节)错误:没有考虑内存对齐要求
B(10字节)错误:对齐计算有误
C(11字节)错误:没有考虑结构体整体需要按4字节对齐

知识点:C++、2018、C语言

题友讨论(16) 

单选题

C++

C语言

10.

要使a的低四位翻转,需要进行操作是()

A

a|0xF

B

a&0xF

C

a^0xF

D

~a

正确答案:C

官方解析:

要使变量a的低四位翻转,需要使用异或运算符^与0xF进行操作,因此C选项(a^0xF)是正确答案。

异或运算符^的特点是:对应位相同时结果为0,不同时结果为1。0xF的二进制表示为0000 1111,与a进行异或运算时,会使a的低4位发生翻转(0变1,1变0),而高位保持不变(与0异或保持原值)。

分析其他选项:
A. a|0xF(按位或):会将低4位全部置为1,不是翻转
B. a&0xF(按位与):会将高4位全部置为0,保留低4位原值,不是翻转
D. ~a(按位取反):会将所有位都取反,不仅仅是低4位

举例说明:
假设a = 1010 0101
则a^0xF = 1010 0101 ^ 0000 1111 = 1010 1010

可以看到,只有低4位发生了翻转(0101变为1010),高4位保持不变(1010),这正是题目要求的效果。

因此,使用异或运算符^是实现低4位翻转的正确方法。

知识点:C++、C++工程师、2019、C语言

题友讨论(10) 

单选题

C++

C语言

11.

运行下面这段C语言程序之后,输出在屏幕上的结果是:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#include

void foobar(int a, int *b, int **c)

{

    int *p = &a;

    *p = 101;

    *c = b;

    b = p;

}

int main()

{

    int a = 1;

    int b = 2;

    int c = 3;

    int *p = &c;

    foobar(a, &b, &p);

    printf("a=%d, b=%d, c=%d, *p=%d\n", a, b, c, *p);

    return (0);

}

A

a=1, b=2, c=3, *p=2

B

a=101, b=2, c=3, *p=2

C

a=101, b=101, c=2, *p=3

D

a=1, b=101, c=2, *p=3

正确答案:A

你的答案:D

官方解析:

让我们通过内存和指针的角度逐步分析这道题目。

这个程序的关键在于理解函数调用时参数的传递方式和指针操作的作用域。

foobar函数中的操作分析:
1. a是值传递,在函数内对a的修改不会影响main函数中的a
2. b是指针传递,但函数内b=p的赋值只改变了局部指针变量b的指向
3. *c是指向指针的指针,通过它可以修改main函数中p的指向

执行过程:
1. main函数中初始化 a=1, b=2, c=3,并让p指向c
2. 调用foobar时:
- p=&a 让p指向局部变量a
- *p=101 修改局部变量a为101
- *c=b 让main函数中的p指向b
- b=p 只改变了函数内部b的指向,对main中的b无影响

最终结果:
- main中的a仍然是1(因为是值传递)
- b保持为2(函数内的b=p只改变了局部变量)
- c仍然是3(未被修改)
- *p为2(因为p现在指向b,而b的值是2)

因此选项A(a=1, b=2, c=3, *p=2)是正确的。

分析其他选项:
B错误:认为a被修改为101,但实际上函数内的修改只影响局部变量
C错误:错误理解了指针赋值的影响范围
D错误:误解了函数内指针操作的作用域

知识点:C++、C语言

题友讨论(67) 

单选题

C语言

12.

以下正确的说法是(   )。

A

用户调用标准库函数前,必须重新定义

B

若已包含标准库头文件及相关命名空间,用户也可以重新定义标准库函数,但是该函数将失去原有含义

C

若已包含标准库头文件及相关命名空间,则系统不允许用户重新定义标准库函数

D

用户调用标准库函数前,不必使用预编译命令将该函数所在文件包括到用户源文件中

正确答案:C

你的答案:B

官方解析:

C选项正确。当程序已经包含了标准库头文件和相关命名空间后,标准库中的函数名、类型名等就被引入到了当前作用域中,根据C++标准规定,不允许用户重新定义这些已经存在于标准命名空间中的标识符,这是为了避免命名冲突和确保程序的正确性。

分析其他选项:

A错误:用户不需要也不应该重新定义标准库函数。标准库函数的定义已经在库文件中提供,只需要包含相应的头文件即可使用。

B错误:即使包含了标准库头文件和命名空间,用户也不能重新定义标准库函数。这样做会导致编译错误,而不是像选项说的"失去原有含义"。

D错误:使用标准库函数前必须使用预编译命令(如#include)将相应的头文件包含到源文件中。这是因为编译器需要知道函数的声明信息(如函数原型、返回类型等)才能正确编译程序。

这个规定的目的是保护标准库的完整性和一致性,防止用户无意中破坏标准库的功能,从而导致程序出现难以预料的错误。

知识点:C语言

题友讨论(6) 

单选题

C语言

13.

1

2

3

4

5

int i=0;

const int ci=i;

auto b=ci; //(1)

int *p=&i;

decltype(*p) c=i;//(2)

以上(1)(2)中变量b,c类型为()

A

const int ,int

B

int,int&

C

const int,int*

D

int,int*

正确答案:B

你的答案:A

官方解析:

这道题目考察了C++中auto和decltype关键字的类型推导规则。让我们逐个分析:

对于(1) auto b=ci:
- ci是const int类型
- 当auto用于初始化时会忽略顶层const属性
- 所以b的类型就是int

对于(2) decltype(*p) c=i:
- p是int*类型
- *p解引用操作会得到左值
- decltype对表达式结果为左值时,会推导出引用类型
- 所以c的类型是int&

因此,b的类型是int,c的类型是int&,B选项正确。

分析其他选项:
A错误:auto会忽略顶层const,所以b不是const int类型
C错误:decltype(*p)得到的是引用类型而不是指针类型
D错误:同C,c的类型是引用而不是指针

这里的关键点是要理解:
1. auto会忽略顶层const
2. decltype(*指针)会得到引用类型
3. auto和decltype有不同的类型推导规则

知识点:C++工程师、2017、C语言

题友讨论(25) 

单选题

C语言

14.

由多个源文件组成的C程序,经过编辑、预处理、编译、链接等阶段会生成最终的可执行程序。下面哪个阶段可以发现被调用的函数未定义?

A

预处理

B

编译

C

链接

D

执行

正确答案:C

官方解析:

C语言程序的编译过程分为预处理、编译、链接三个主要阶段,链接阶段是发现未定义函数的关键阶段。

链接阶段的主要工作是将多个目标文件组合成可执行程序,此时会检查所有函数调用是否都能找到对应的函数定义。如果发现某个函数被调用但找不到定义,链接器就会报告"未定义的引用"错误。

分析其他选项:

A. 预处理阶段错误:预处理主要处理#include、#define等预处理指令,展开宏定义,不会检查函数是否定义。

B. 编译阶段错误:编译器只负责将源代码转换为目标代码,检查语法错误。它能看到函数声明(prototype)就可以通过编译,不需要函数的具体定义。

D. 执行阶段错误:程序能够执行说明已经通过了链接,此时所有函数都已经找到定义,不会出现未定义的问题。

所以链接阶段是发现未定义函数的正确阶段,选C是对的。这也说明了为什么我们在编程时即使函数未定义,有时也能通过编译,但在链接时会报错。

知识点:C语言

题友讨论(27) 

多选题

C++

C语言

15.

volatile类型在以下哪些情况下需要使用()

A

外部中断会改变变量

B

外部任务会改变变量

C

变量使用的是动态申请的内存空间

D

对硬件寄存器进行操作

正确答案:ABD

你的答案:AD

官方解析:

volatile关键字主要用于确保多线程环境下变量的可见性和有序性。让我们分析正确选项和错误选项:

正确选项分析:
A. 外部中断会改变变量:正确。当变量可能被中断服务程序修改时,需要使用volatile确保主程序能够立即看到修改后的值。

B. 外部任务会改变变量:正确。在多任务环境下,如果变量会被其他任务修改,使用volatile可以确保变量值的及时可见性。

D. 对硬件寄存器进行操作:正确。硬件寄存器的值可能随时发生变化,使用volatile可以防止编译器优化,确保每次都直接读取寄存器的值。

错误选项分析:
C. 变量使用的是动态申请的内存空间:错误。变量是否使用动态内存与volatile无关。volatile关注的是变量的访问特性,而不是内存分配方式。动态分配的内存空间的变量并不一定需要volatile修饰。

总的来说,volatile适用于:
1. 多线程/中断环境下的共享变量
2. 需要与硬件直接交互的场景
3. 防止编译器优化导致的读取缓存问题

这些场景都有一个共同特点:变量的值可能在程序控制之外被修改,需要确保读取到的总是最新值。

知识点:C++、C++工程师、C语言

你可能感兴趣的:(算法,c语言)