参考资料:高教版《全国计算机等级考试二级教程——C语言程序设计》
P110 填空题
8.15
题目:
若有定义: char ch;
- 使指针p可以指向字符型变量的定义语句是__[1]__。
- 使指针p指向变量ch的赋值语句是__[2]__。
- 通过指针p给变量ch读入字符的scanf函数调用语句是__[3]__。
- 通过指针p给变量ch赋字符A的语句是__[4]__。
- 通过指针p输出ch中字符的语句是__[5]__。
题解:
思路:
- 使指针p指向字符型变量,需要将这个指针定义为char类型。
- 要使指针p指向ch变量,可以在定义它的时候初始化它,也可以单独赋值。
- scanf函数把从终端读入的数据依次放入各输入项所代表的存储单元中,而输入项中的(&变量名)可以用指向这个变量的指针来代替。(不知道为什么答案还给了*p = getchar();,题目中不是说scanf函数吗?)
- 可以使用间址运算符“*”来实现通过指针p给变量ch赋字符A的功能,这条语句与ch = 'A';等价。
- 在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↑ |
-
通过指针p,给s赋值,使其指向最后一个存储单元a[4]的语句是__[1]__。
-
s指向存储单元a[4],移动指针s,使之指向中间的存储单元a[2]的表达式是__[2]__。
-
已知k = 2,指针s已指向存储单元a[2],表达式*(s + k)的值是__[3]__。
-
指针s已指向存储单元a[2],不移动指针s,通过s引用存储单元a[3]的表达式是__[4]__。
-
指针s指向存储单元a[2],p指向存储单元a[0],表达式s - p的值是__[5]__。
-
若p指向存储单元a[0],则以下语句的输出结果是__[6]__。
for(i = 0; i < 5; i++) printf("%d", *(p + i)); printf("\n");
题解:
其实这五个连续的存储单元就是一个有五个元素的一维数组。
- s = p是让两个指针都指向a[2],所以在这种情况下只要让p向高地址移动3个存储单元,再赋值给p就可以。
- s指向a[4]时,要想让s指向a[2],只需要让s向低地址移动2个存储单元。
- s + k是让指针s向高地址移动两个存储单元,即让s指向a[4];间址运算符*表示通过指针来引用该地址的存储单元。*(s + k)的值即为a[4]中存储的内容,即50。
- 要求不移动指针s,可以通过间址运算符引用存储单元a[3]的内容。
- 两个指针指向一串连续的存储单元,所以可以相减。由于s与p相差两个存储单元,所以s - p的值为2。
- 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
网友评论