【考研复习】李春葆新编C语言习题与解析(错误答案订正+部分习题详细解答)

有偿出电子书及解答!!!!!!!!!!私我
有偿出电子书及解答!!!!!!!!!!私我
有偿出电子书及解答!!!!!!!!!!私我
有偿出电子书及解答!!!!!!!!!!私我
有偿出电子书及解答!!!!!!!!!!私我

新编C语言习题与解析

做习题时发现有些错误答案,写篇博客进行改正记录。不对地方欢迎指正~
使用g++进行编译。

第二章·数据类型及其运算

2-2-4

在这里插入图片描述
乘除和求余的优先级一样高。 所以正确的解释如下:
2.5+1*7%2/4=2.5+7%2/4=2.5+1/4=2.5+0=2.5。
之后再统一精度。


2-1-17

在这里插入图片描述
C. 其中b的表达形式错误,若加上0x1e2b则正确。所以C错误。
D. e后为整数。指数命名规则:e前有数,后有整数。所以D错误。


以下部分为第二章的答案详细解答
将20题和25对比记忆:
在这里插入图片描述
答案为:BC
A. 连续赋值,从右至左分割,第一个赋值表达式的左侧是9+e+f为表达式,错误。赋值表达式左侧应该为变量。
B. 逗号表达式,赋值正确。
C. 逗号表达式,赋值正确。
D. 出现的问题和A选项类似,左侧不应该是表达式而是变量。
在这里插入图片描述
这里的B选项和上题对应,而且要注意的是25题要选的是表达式不是语句哦。

2-1-80

在这里插入图片描述
该题不同编译器给的结果不同,vc++就是上述结果。
gcc的结果为:a=8,x=210,b=1,y=6


第三章·选择语句和循环语句

3-1-12

在这里插入图片描述
根据后面选项,可知题目为-1.


3-1-14

在这里插入图片描述

在这里插入图片描述
A. case后的常量表达式不是整型,且switch后也不是整型;
B. switch(a);后有分号错误;
C. case后的常量表达式不是整型;
D. switch(a+b);后有分号。若无分号,正确答案为D。


3-1-22

在这里插入图片描述
少了个S,应该都看得出来。


3-1-23

在这里插入图片描述
红色框处应该为分号。


3-2-40

在这里插入图片描述
输出部分偶数之和应该直接输出c,而不是c-11。

#include <stdio.h>
int main()
{
    int a,b,c;
    a=c=0;
    for (int i = 0; i < 10; i+=2)
    {
        a+=i;
        b=i+1;
        c+=b;
    }
    printf("even = %d\n",a);
    printf("odd = %d\n",c);
} // namespace std;


3-2-56

在这里插入图片描述

  1. j%2==1当判断条件为1的时候输出
  2. 每个集合之间有逗号(数字之间的逗号可以用个if做一下)
#include<stdio.h>
int main(){
    int n,m,i,j,k;
    printf("n=");
    scanf("%d",&n);
    //计算具有子集的个数
    m=1;
    for(i=1;i<=n;i++){
        m=m*2;
    }
    m--;
    for(i=0;i<=m;i++){
        printf("{");
        j=i;
        k=0;
        while(j!=0){
            if(j%2==1) printf("%d",k);
            k++;
            j/=2;
        }
        printf("},");
        if((i+1)%5==0) printf("\n");
    }
    printf("\n");
}

第四章·数组

4-1-3

在这里插入图片描述
在定义数组时,定义赋初值的个数等于数组长度,则数组长度可以省略,所以只给部分数组元素赋初值时,对数组的长度声明不能省略。故答案为A、B。
简记:一维数组可以省略,二维数组行能省略,列不能。


4-1-9

这里有一个歧义题目
在这里插入图片描述
书上说:定义静态数组时才会初始化全为0。该定义不是静态数组,故将初值只赋值给前两个元素。
网上说:数组为初始化,中存放的是乱码,但是只要初始化一个数,其余数据自动填充0,所以数组元素都为0。
两者歧义,先按照书上定义的来,另外苏小红书中也提到静态数组定义的时候会将数组元素赋为0。


4-1-16

在这里插入图片描述

由于题目中要求输出行列号元素之和为3的数组元素,故正确答案为:x<=3,y<=2,z==3.


4-1-26

在这里插入图片描述
我们看第十个判断题:如果想使一个数组中全部元素的值为0,可以写成int a[10]={0*10};。请问这句话的说法是正确的吗?

个人认为: 题目等价于 int a[10]={0},表示只给第一个元素赋初值,后面9个元素值默认为0.
拓展: int a[10]={1*10},是否正确,初始化的结果是什么?
输出结果:10,0,0,0,0,0,0,0,0,0


4-2-20

在这里插入图片描述


第五章·指针

5-1-4

在这里插入图片描述
该题无正确选项。B具体解释可看5-1-14


第五章的指针是重点,所以按照5-1-10为例简单介绍一下行指针和列指针的使用和区别(我自己也梳理梳理)。ps:该题答案是正确的
首先明确的是当指向一维数组和二维数组时,所需要的指针变量是不同的。
这是因为在指向二维数组的时候总是要经过这样的转换:
在这里插入图片描述
在这里插入图片描述

  1. 指向一维数组的指针变量:在C语言规定中,数组名代表数组首地址,而且是一个地址常量,所以指针可以直接指向地址(即数组)p=a等价于p=a[0].
  2. 指向多维数组的指针变量:
  • a+1是跳过一行。因为二维数组名是行指针,加1是跳过一行不是一个元素。
  • 只有列指针才是指向“真正”的元素。即指向某一个元素的存储单元。
  • 一维数组名表示的是行指针,二维数组名表示的是列指针。

5-2-10

在这里插入图片描述
现在是二维数组,二维数组名是行指针,而在二维情况下int *p是一维的,不能直接将a数组赋值给p,换句话说因为p是指针;a是指向指针的指针,两个无法赋值


行指针和列指针辨析:
那么行指针和列指针怎么理解呢?我个人理解的是:行指针跳一行,列指针因为已经从行指向了列所以跳一个元素。
在这里插入图片描述

在这里插入图片描述
对于行指针:其实就是二维数组名的等价代换例如,a[2][2]等价于p[2][2]
对于列指针:

  • p+1指向a[0][0]
  • p+6指向a[1][1]
    以此类推

5-1-11

在这里插入图片描述
在这里插入图片描述
该题正确答案应该为D:
a='\'.转义符号后应该包含其他符号,如下表。
b='\xab'.该类型符合下表中\xhh类型的二位16进制。
c='\0xab'.C语言中没有这种形式的转义字符。
d="\017".首先\0看作一个空字符,17作为十进制数字。

这道题还需要注意的是给d分配的是字符串而不是字符,这是因为字符串的首地址可以直接使用指针指向,而字符不行。另外转义字符还需要和八进制、十六进制的表示做区别
在这里插入图片描述
上图参考《李春葆新编C语言习题与解析》12页

5-2-4

在这里插入图片描述
在这里插入图片描述
5-2-4:
A. p指针指向“are you”字符串。程序段正确
B. a为地址常量,不能进行++a操作。程序段错误
C. a[11]数组内存为11,而st指向的字符串为11+1(最后还有’\0\),数组内存不够。程序段错误
D. a数组未声明多大的数组。程序段错误
5-2-11:
A. p指针指向“are you”字符串。程序段正确
B. a为地址常量,不能进行++a操作。程序段错误
C. a[11]数组内存为11,而st指向的字符串为11+1(最后还有’\0\),数组内存不够。程序段错误
D. p指针指向"w are you"字符串。程序段正确


5-2-36

在这里插入图片描述

#include<stdio.h>
#include<string.h>
int main(){
    char *ptr1,*ptr2;
    ptr1=ptr2="abcde";
    while(*ptr2!='\0')
        putchar(*ptr2++);
    while(--ptr2>=ptr1)
        putchar(*ptr2);
    putchar('\n');
}

本题答案有误,编译器输出结果为:abcdeedcba


5-3-14

在这里插入图片描述
在这里插入图片描述
本题答案有误,编译器输出结果为:

greeting[0]=Hello
greeting[1]=Good morning
greeting[2]=How are you
Hello
Good morning
How are you

第六章·函数

6-1-6

在这里插入图片描述
B选项正确。

在这里插入图片描述
在这里插入图片描述

储备知识:
在这里插入图片描述
当数组名即地址作为实参时,这三种形式等价。

A) 参数2,数组长度不限。正确
B) 参数2,数组长度41, &a[9] 从9-50是41。正确
C) 参数2,指针用地址调用。正确
D) 参数2,为整型,不能传入地址。不正确

参考问题解答


6-3-26

在这里插入图片描述
这道题的答案的提问方式错了,应该问的是正确的定义方式。
当用二维数组作为形参时,第一维的大小可以省略,但第二维的大小是不能省略的,必须和实参数组第二维的大小一致。所以正确答案是C。
参考问题答案


6-3-31

在这里插入图片描述
这道题应该不是字符串从大到小排序,而是输出字符串长度最大的。对应答案为B则正确。


6-3-34

在这里插入图片描述
第三个形式表示错误应为:void fun(double (*b)[22])


6-3-37

在这里插入图片描述
输出格式不对,正确格式为:1,3,2


第七章·结构体与共用体

7-4-2

在这里插入图片描述
答案应为D。
A. a.next后应该赋值为c的地址;另外这种形式就是不对的,变量a的next应该指向地址,而不是结构体c。
B. 首先p和q链接之后,q.next变为q了,第二句中的q.next和p.next是让他们的指针域互指,不能形成正确的单链表。
C. 该选项当p和q连结之后,反的错误和B类似,p和q指针域互指了。
D. 首先变量a的指针域p指向变量c,然后让变量c的指针域指向变量b。答案正确。
另外,没有变量名时,应该先连后头的,再把前面连上,否则断链了
参考答案链接


对比这两种共用体题型记忆,题目并无错误

7-5-6

#include<stdio.h>
int main(){
    union 
    {
        short int i[2];
        long k;
        char c[4];
    }r,*s=&r;
    s->i[0]=0x39;
    s->i[1]=0x38;
    printf("%c\n",s->c[0]);
}
  1. 首先明确union所有成员共用一个内存单元,大小由空间最大的来决定,同时值共用且会覆盖。上述代码内存空间为4个字节(short int占两个字节,有两个数组元素共四个字节;long也是占用四个字节;char占四个字节,有四个数组元素共四个字节)。
  2. 然后通过 s->i[0]=0x39; s->i[1]=0x38;给i进行赋值,也就是i的前两个字节存的是0x39后两个字节存的0x38。由于他们使用同一个内存空间c数组也是同样存储。
    存储方式如图所示:

有个超级易错的点:一个字节8位,放8个二进制。并且x86系统支持的小端存放,即低地址放低字节。

  1. 然后再看输出,printf("%c\n",s->c[0]);c以字符的方式输出到屏幕上,也就是以十六进制字符的方式输出到屏幕上。值得注意的是0x39所代表的字符是’9’(在ASCII表中的十六进制)。所以输出的是‘9‘。
  2. 这样的理解方式我认为比答案解析要清楚。另外值得注意的是题目中给了‘0’字符十进制ASCII码为48,那么我们就可以算得‘0’字符对应十六进制ASCII码为30,从而得到最后可以输出’9’。

7-5-8

#include<stdio.h>
int main(){
    union 
    {
        char s[2];
        short int i;
    }a;
    a.i=0x1234;
    printf("%x,%x\n",a.s[0],a.s[1]);
}

分析步骤和上面类似:

  1. 共用体a占用2个字节
  2. i变量占用两个字节,第一个个字节存储0x34,第二个字节存储0x12。
  3. 输出格式为十六进制,故分别输出34和12。

总结

  • 小端存储:低地址低字节,一个字节内顺序存储
  • 一个字节放8位!这里很容易错!
  • 注意输出格式,是字符还是十六进制。如果是字符记住‘0’字符对应十六进制ASCII码为30。
  • 对比记忆,‘0’字符对应十六进制ASCII为30.

这个题再多说一点:如果输出的是整数的话要按照先高地址然后再低地址这样存储。以下面这个题目为例:

#include <stdio.h>
int main()
{
    union 
    {
        char i[2];
        int k;
    }r;
    r.i[0]=2;
    r.i[1]=0;
    printf("%d\n",r.k);
}

运行结果为:2

存储结构如图所示,如果要输出整数k的话首先要输出高地址中的0,然后再输出2,那么输出结果是02吗?并不是的,实际上当输出整数时,前标志0是不会输出的,和十六进制0x相似也不会输出,所以输出结果为2。

7-5-9

在这里插入图片描述
该题D选项有问题。

在这里插入图片描述


第九章·文件

9-1-1

在这里插入图片描述
在这里插入图片描述
本题答案为D
A.文本文件的每一个字节放一个ASCII码,代表一个字符。文本文件也称为ASCII码文件,具有可读性。故A选项正确。
B. 由于数据在计算机中是以二进制形式存放的,因此二进制文件中的数据可以直接读出,而不需要像文本文件那样把ASCII码转换成二进制,因此速度较快。故B选项正确。
C. 在文本文件中,数据以ASCII码形式存放的,用户很难判定一个数据到底占几个字节,所以不适合使用随机读写方式。故C选项正确。
D. 数据以二进制形式存放,占有的字节数是固定的,所以可以进行随机读写,当然也可以顺序读写。所以,D选项为所选。
参考答案链接

9-2-11

在这里插入图片描述
本题答案为C
fprintf 存入fp所指向的ASCII文件中,非二进制文件
fread 从二进制文件fp中读取count个数据块
fputc 将字符写到fp指向的文件中去,不一定二进制


  • 40
    点赞
  • 138
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 75
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 75
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Lydia.na

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

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

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

打赏作者

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

抵扣说明:

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

余额充值