2019-03-07 计算机二级C语言程序设计之课后习题(4)

参考资料:高教版《全国计算机等级考试二级教程——C语言程序设计》

P110 填空题

8.15

题目:

若有定义: char ch;

  1. 使指针p可以指向字符型变量的定义语句是__[1]__。
  2. 使指针p指向变量ch的赋值语句是__[2]__。
  3. 通过指针p给变量ch读入字符的scanf函数调用语句是__[3]__。
  4. 通过指针p给变量ch赋字符A的语句是__[4]__。
  5. 通过指针p输出ch中字符的语句是__[5]__。

题解:

思路:

  1. 使指针p指向字符型变量,需要将这个指针定义为char类型。
  2. 要使指针p指向ch变量,可以在定义它的时候初始化它,也可以单独赋值。
  3. scanf函数把从终端读入的数据依次放入各输入项所代表的存储单元中,而输入项中的(&变量名)可以用指向这个变量的指针来代替。(不知道为什么答案还给了*p = getchar();,题目中不是说scanf函数吗?)
  4. 可以使用间址运算符“*”来实现通过指针p给变量ch赋字符A的功能,这条语句与ch = 'A';等价。
  5. 在printf函数中也可以使用间址运算符,通过指针p来输出ch中的内容。因为ch是char类型,所以也可以用putchar()函数来输出。

答案如下:

1. char *p;
2. p = &ch;
3. scanf("%c", p);或*p = getchar();
4. *p = 'A';
5. printf("%c", *p);或putchar(*p);

8.16

题目:

若有如下表所示的五个连续的int类型的存储单元并赋值如表,且已定义int *p, *s;其中p指向存储单元a[1]。

a[0] a[1] a[2] a[3] a[4]
10 20 30 40 50
p↑
  1. 通过指针p,给s赋值,使其指向最后一个存储单元a[4]的语句是__[1]__。

  2. s指向存储单元a[4],移动指针s,使之指向中间的存储单元a[2]的表达式是__[2]__。

  3. 已知k = 2,指针s已指向存储单元a[2],表达式*(s + k)的值是__[3]__。

  4. 指针s已指向存储单元a[2],不移动指针s,通过s引用存储单元a[3]的表达式是__[4]__。

  5. 指针s指向存储单元a[2],p指向存储单元a[0],表达式s - p的值是__[5]__。

  6. 若p指向存储单元a[0],则以下语句的输出结果是__[6]__。

    for(i = 0; i < 5; i++)
        printf("%d", *(p + i));
    printf("\n");
    

题解:

其实这五个连续的存储单元就是一个有五个元素的一维数组。

  1. s = p是让两个指针都指向a[2],所以在这种情况下只要让p向高地址移动3个存储单元,再赋值给p就可以。
  2. s指向a[4]时,要想让s指向a[2],只需要让s向低地址移动2个存储单元。
  3. s + k是让指针s向高地址移动两个存储单元,即让s指向a[4];间址运算符*表示通过指针来引用该地址的存储单元。*(s + k)的值即为a[4]中存储的内容,即50。
  4. 要求不移动指针s,可以通过间址运算符引用存储单元a[3]的内容。
  5. 两个指针指向一串连续的存储单元,所以可以相减。由于s与p相差两个存储单元,所以s - p的值为2。
  6. p指向a[0],则p + i指向a[i]。这段语句的作用是依次读取这五个存储单元的内容,再输出,最后输出一个换行符。

答案如下:

1. s = p + 3;
2. s = s - 2;(也可以写 s--, s--;或 s -= 2;)
3. 50
4. *(s + 1)
5. 2
6. 10 20 30 40 50 (换行)

P110 编程题

8.17

题目:

请编写函数,其功能是对传送过来的两个浮点数求出和值与差值,并通过形参传送回调用函数。

题解:

这道题的原理很简单,考察点主要是如何通过指针把多个结果传回主函数。

由于这个函数不需要返回值,所以定义为void类型。

定义函数fun()如下:

void fun(int x, int y, int *h, int *c)
{
    *h = x + y;         //将两数之和存储在x中
    *c = x - y;         //将两数之差存储在y中
}

在这个函数中,声明了两个临时指针h和c,将x+y的内容存入变量x所在的地址,将x-y的内容存入变量y的地址,从而达到返回多个数据的目的。

运行测试:

完整程序如下:

#include <stdio.h>

void fun(int, int, int*, int*);     //函数fun()的声明语句

int main(void)
{
    int x = 0, y = 0;

    scanf_s("%d%d", &x, &y);        //读入x和y
    fun(x, y, &x, &y);              //调用fun()函数求两数之和和两数之差
    //由于在fun函数中,将两数之和放在了x中,将两数之差放在了y中,所以输出时两数之和为x,两数之差为y
    printf("两数之和为:%d, 两数之差为: %d\n", x, y);

    return 0;
}

void fun(int x, int y, int* h, int* c)
{
    *h = x + y;
    *c = x - y;
}

输入输出:

1 2
两数之和为:3, 两数之差为: -1

8.18

题目:

请编写函数,对传送过来的三个数选出最大数和最小数,并通过形参传回调用函数。

题解:

这个问题的原理也是比较简单的,关键还是如何利用指针传回最大数和最小数。

因为没有返回值,同样将其定义为void类型。

这里在主函数单独定义了两个整型变量max和min来存放最大值和最小值,当然用a和b来存放也是可以的,原理差不多。

定义fun()函数如下:

void fun(int a, int b, int c, int* max, int* min)
{
    *max = a;
    *min = a;

    //判断最大值
    if (b > * max)
        * max = b;
    
    if (c > * max)
        * max = c;
    
    //判断最小值
    if (b < *min)
        * min = b;
    
    if (c < *min)
        * min = c;
}

运行测试:

完整程序如下:

#include <stdio.h>

void fun(int, int, int, int*, int*);                //函数fun()的说明语句

int main(void)
{
    int a = 0, b = 0, c = 0, max = 0, min = 0;

    scanf_s("%d%d%d", &a, &b, &c);
    fun(a, b, c, &max, &min);                       //调用fun函数来求最大最小值
    printf("最大的数为:%d, 最小的数为: %d\n", max, min);

    return 0;
}

void fun(int a, int b, int c, int* max, int* min)
{
    *max = a;
    *min = a;

    if (b > * max)
        * max = b;
    
    if (c > * max)
        * max = c;
    
    if (b < *min)
        * min = b;
    
    if (c < *min)
        * min = c;
}

输入输出:

1 3 2
最大的数为:3, 最小的数为: 1

P145 填空题

9.25

题目:

以下findmax返回s所指数组中最大元素的下标,数组中元素的个数由t传入,请填空。

int findmax(int s[], int t)
{
    int k, p;
    
    for(p = 0, k = p; p < t; p++)
        if(s[p] > s[k])
            __[1]__;
    
    return __[2]__;
}

题解:

要判断最大元素的下标,只需要将元素逐个与最大的元素比较,然后将最大下标存储在变量k中,最后将变量k返回。

具体看注释吧。

int findmax(int s[], int t)
{
    int k, p;                       //声明两个整型变量
    
    for(p = 0, k = p; p < t; p++)   //利用for循环来对数组的元素逐个比较
        //这个if将下标最大的元素存储在s[k]中,如果找到更大的,就进行替换
        if(s[p] > s[k])             
            __[1]__;
   
    return __[2]__;                 //把最大元素的下标返回
}

完整的函数如下:

int findmax(int s[], int t)
{
    int k, p;
    for(p = 0, k = p; p < t; p++)
        if(s[p] > s[k])
            k = p;
    return k;
}

9.26

题目:

用以下程序统计从终端输入的字符中每个大写字母的个数,num[0]中统计字母A的个数,其他以此类推。用#号结束输入。请填空。

#include <stdio.h>
#include <ctype.h>

int main(void)
{
    int num[26] = {0}, i;
    char c;
    
    while(__[1]__ != '#')
        if( isupper( c ) )
            num[__[2]__] += 1;
    
    for(i = 0; i < 26; i++)
        if( num[i] )
            printf("%c: %d\n", i + 'A', num[i]);
    
    return 0;
}

题解:

看注释吧。

#include <stdio.h>
#include <ctype.h>

int main(void)
{
    int num[26] = {0}, i;       //声明计数用的数组num[26]并初始化为0,声明一个循环变量
    char c;
    
    while(__[1]__ != '#')       //用#号结束输入,这里应该是用getchar()函数判断输入是否为#
        if( isupper( c ) )      //用ctype.h的函数isupper()判断大小写
            num[__[2]__] += 1;  //用数组来统计大写字母的个数,这个空中应该填写计算出的数组下标
    
    for(i = 0; i < 26; i++)     //用for循环依次输出每个大写字母的个数
        if( num[i] )            //如果num[i]不等于0,即这个大写字母存在,将它的个数输出
            printf("%c: %d\n", i + 'A', num[i]);
    
    return 0;
}

完整的程序如下:

#include <stdio.h>
#include <ctype.h>

int main(void)
{
    int num[26] = {0}, i;
    char c;
    
    while((getchar()) != '#')
        if( isupper( c ) )
            num[c - 'A'] += 1;
    
    for(i = 0; i < 26; i++)
        if( num[i] )
            printf("%c: %d\n", i + 'A', num[i]);
    
    return 0;
}

P145 编程题

9.27

题目:

输入一行数字字符,请用数组元素作为计数器来统计每个数字字符的个数。用下标为0的元素统计字符‘0’的个数,用下标为1的元素统计字符‘1’的个数……

题解:

跟9.26用相同的方法实现即可。

#include <stdio.h>

int main(void)
{
    int num[10] = { 0 }, i;             //定义一个有10个元素的数组作为计数器
    char c;

    while ((c = getchar()) != '\n')     //判断输入结束
            num[c - '0'] += 1;          //计算每个数字的个数

    for (i = 0; i < 10; i++)            //使用for循环输出计算结果
        if (num[i])                     //如果这个数字存在(计数不为0)就输出
            printf("%d: %d\n", i , num[i]);

    return 0;
}

输入输出:

1223334444555556666667777777888888889999999990
0: 1
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
7: 7
8: 8
9: 9
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容