• 抬起头,继续前进吧,去把这个不完美的故事,变成你成所期望的样子
  • 登山路上我们会放弃很多东西,但这些被我们丢掉在我们登上山顶之际,都会一一回来
  • 不论开发还是逆向,数学水平的高低直接决定了”你的饭碗里有没有肉”
  • 万丈高楼平地起,勿在浮沙筑高台

《C语言程序设计:现代方法》第九章练习

C 菜鸟 2年前 (2018-02-24) 145362次浏览 已收录 5个评论
[隐藏]

        本篇为菜鸟在学习《C 语言程序设计:现代方法》中第九章函数时做的练习题,如果有错误或疑问的话,欢迎大家指正~

1、三角面积

下列计算三角面积的函数有两处错误。找出这些错误,并且说明其修改方法。(提示:公式没有错误)

float triangle_area(float base, height)
float product;
{
    product = base * height;
    return (product / 2);
}

答:
1、形参 height 没有声明类型。修改为 float height
2、product 作为局部变量使用,却作为形参声明。将 float product 加入到函数体中

知识点:即使多个形参具有相同数据类型,也必须对每个形式参数分别进行类型说明

2、区间检测

编写函数 check(x, y, n),如果 x 和 y 都落在 0 到 n-1 的闭区间内,那么使得函数 check 返回 1。否则,函数应该返回 0。假设 x、y 和 n 都是 int 类型。
答:

int check(int x, int y, int n) {
	if (((0 < x) && (x < n - 1)) && ((0 < y) && (y < n - 1))) {
		return 1;
	}
	return 0;
}

3、最大公约数

编写函数 gcd(m, n)用来计算整数 m 和 n 的最大公约数。使用 Euclid 算法。
答:

int gcd(int m, int n) {
    int nTemp;
    while(n != 0) {
        nTemp = n;
        n = m % n;
        m = nTemp;
    }
    return m;
}

4、时间转换

编写函数 day_of_year(month, day, year),使得函数返回某 month 某 day 是 year 这一年中的第几天(1 和 366 之间的整数)。
答:

void day_of_year(int month, int day, int year){
    int i, dayNumber = 0;
    for (i = 1; i <= month; i++) {
        switch (i) {
            case 1 :
            case 3 :
            case 5 :
            case 7 :
            case 8 :
            case 10 :
            case 12 :
                dayNumber += 31;
                break;
            case 2 :
                dayNumber += 29;
                break;
            case 4 :
            case 6 :
            case 9 :
            case 11 :
                dayNumber += 30;
                break;
        }
    }
    dayNumber += day;
    printf("The %d/%d is the %d days of the %d\n", month, day, dayNumber, year);
}

5、数字位数

编写函数 num_digits(n),使得函数返回正整数 n 中数字的个数。
答:

int num_digits(int n)
{
    int digit = 0;
    while (n != 0) {
        n /= 10;
        digit++;
    } 
    return digit;
}

6、获取数字

编写函数 digit(n, k),使得函数返回正整数 n 中第 k 个数字(从右边算起)。例如,digit(829, 1)返回 9,digit(829, 2)返回 2,而 digit(829, 3)则返回 8。
如果 k 大于 n 所含有的数字的个数,那么函数返回-1。
答:

int digit(int n, int k)
{
    int digit, a[20];
    while (n != 0) {
        a[digit] = n % 10; 
        n /= 10;
        digit++;
    }
    if (k > digit) {
        return -1;
    }
    return a[k - 1]; 
}

7、函数定义

假设函数 f 有下列定义:
int f(int a, int b) {…}
那么下列哪条语句是合法的?(假设 i 的类型为 int 而 x 的类型为 float。)
(a)i = f(83, 12);
(b)x = f(83, 12);
(c)i = f(3.15, 9.28);
(d)x = f(3.15, 9.28);
(e)f(83, 12);
答:都合法

8、函数原型

对于返回为空且有一个 float 型形式参数的函数,下列哪个函数原型是有效的?
(a)void f(float, x);
(b)void f(float);
(c)void f(x);
(d)f(float x);
答:(b)

9、程序输出判断

下列程序输出是什么?

#include <stdio.h>

void swap(int a, int b);

main()
{
    int x = 1, y = 2;
	
    swap(x, y);
    printf("x = %d, y = %d\n", x, y);
    return 0;
}

void swap (int a, int b)
{
	int temp;
	
    temp = a;
	a = b;
	b = temp;
}

答: x = 1, y = 2

10、数组信息

编写函数,使得函数返回下列值。(假设 a 和 n 是形式参数,其中 a 是有 int 型值的数组,而 n 则是数组的长度。)
(a)数组 a 中的最大元素
(b)数组 a 中所有元素的平均值
(c)数组 a 中正数元素的数量
答:

#include <stdio.h>

#define ARRAY_SIZE 5

int array_max_number(int a[], int n);
int array_avg_number(int a[], int n);
int array_positive(int a[], int n);

main()
{
    int a[ARRAY_SIZE], i, aInfo[3];
    printf("Enter 5 number: ");
    for (i = 0; i < ARRAY_SIZE; i++) {
        scanf("%d", &a[i]);
    }

    aInfo[0] = array_max_number(a, ARRAY_SIZE);
    printf("The max element is: %d\n", aInfo[0]);

    return 0;
}

int array_max_number(int a[], int n)
{
    int i, maxNumber = 0;
    for (i = 0; i < n; i++) {
        if (a[i] > maxNumber) {
            maxNumber = a[i];
        }
    }
    return maxNumber;
}

int array_avg_number(int a[], int n)
{
    int i, sumNumber = 0;
    for (i = 0; i < n; i++) {
        sumNumber += a[i];
    }
    return (sumNumber / n);
}

int array_positive(int a[], int n)
{
    int i, positive = 0;
    for (i = 0; i < n; i++) {
        if (a[i] > 0) {
            positive++;
        }
    }
    return positive;
}

11、修改函数

如果数组 a 的所有元素值都等于 0,那么假设下列函数返回 TRUE;如果数组的所有元素都是非 0 的,则函数返回 FALSE。
下面的函数有错误。请找出错误并说明修改方法

Bool has_zero(int a[], int n)
{
    int i;
    for (i = 0; i < n; i++) 
        if (a[i] == 0) 
            return TRUE;
        else
            return FALSE;
}

答:return FALSE 处在 else 的位置,当检测到一个元素非 0 时,该函数就退出了。并未遍历完数组中的所有元素
修改:去掉 else,将 return FALSE 放在循环体外

12、重写函数

下面的函数用来找到三个数的中间数。重新编写该函数,使得其只有一条 return 语句

float median(float x, float y, float z)
{
    if (x <= y) 
        if (y <= z) return y;
        else if (x <= z) return z;
        else return x;
    if (z <= y) return y;
    if (x <= z) return x;
    return z;
}

答:

float median(float x, float y, float z)
{
    return x <= y ? (y <= z ? y : (x <= z ? z : x)) : (z <= y ? y : (x <= z ? x : z));
}

13、简化 fact 函数

int fact(int n) 
{
    if (n <= 1)
        return 1;
    else
        return n * fact(n - 1);
}

通过将条件表达式放入 return 语句来精简 fact 函数
答:

int fact(int n)
{
    return n <= 1 ? 1 : n * fact(n - 1);
}

14、重写 fact 函数

请重新编写 fact 函数,使得编写后的函数不再递归
答:

int fact(int n)
{
    int i, result = 1;
    for (i = 1; i <= n; i++) {
        result *= i;
    }
    return result;
}

15、递归 gcd

编写递归版本的 gcd 函数。有一种用于 gcd(m, n)的策略:如果 n 为 0,那么返回 m;否则,递归地调用 gcd 函数,把 n 作为第一个实际参数进行传递,而把 m%n 作为第二个实际参数进行传递
答:

int gcd(int m, int n)
{
    if (n == 0) {
        return m;
    } else {
        gcd(n, (m % n));
    }
}

16、函数跟踪

思考下面的函数

void pb(int n) {
    if (n != 0) {
        pb(n / 2);	
        putchar('0' + n % 2);
    }
}

手动进行函数的跟踪。然后编写程序调用此函数,把用户录入的数据传递给此函数。函数做了什么?
答:
函数跟踪:
pb(3) 3 不等于 0,执行 pb(3 / 2),即 pb(1)。
pb(1) 1 不等于 0,执行 pb(1 / 2), 即 pb(0)。
pb(0) 0 != 0 不成立,不进行任何操作。
pb(1) pb(0)执行完毕后,输出字符(‘0’ + 1 % 2),即’1’。
pb(3) pb(1)执行完毕后,输出字符(‘0’ + 3 % 2),即’1’。
函数调用:

[root@localhost lianxiti_9]# cat test16.c 
#include <stdio.h>

void pb(int n) {
    if (n != 0) {
        pb(n / 2);
        putchar('0' + n % 2); 
    }
}

main()
{
    int n;
    printf("Enter a number: ");
    scanf("%d", &n);
    pb(n);
    printf("\n");

    return 0;
}
[root@localhost lianxiti_9]# ./test16
Enter a number: 8
1000

函数输出了输入数据的 2 进制字符串。

17、排序

编写程序,要求用户录入一串整数(把这串整数存储在数组中),然后通过调用 selection_sort 函数来排序这些整数。
在给定 n 个元素的数组后,selection_sort 函数必须做如下工作:
(a)搜索数组找出数组中最大的元素,然后把它移到数组最后
(b)递归地调用函数本身来对前 n-1 个元素数组进行排序
答:

#include <stdio.h>

#define ARRAY_SIZE 10 

void selection_sort(int a[], int length);

main()
{
    int i, a[ARRAY_SIZE]; 

    printf("Enter 10 number: ");
    for (i = 0; i < ARRAY_SIZE; i++) {
        scanf("%d", &a[i]);
    }
    selection_sort(a, ARRAY_SIZE);
    
    printf("Sort result is: ");
    for (i = 0; i < ARRAY_SIZE; i++) {
        printf(" %d", a[i]);
    }
    printf("\n");

    return 0;
}

void selection_sort(int a[], int length)
{
    int i, temp;
    if (length >= 1) {
        for (i = 0; i < length - 1; i++) {
            if (a[i] > a[(length - 1)]) {
                temp = a[length - 1];
                a[length - 1] = a[i];
                a[i] = temp;
            }
        }
        selection_sort(a, (length - 1));
    }
}

学习心得 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明《C 语言程序设计:现代方法》第九章练习
喜欢 (10)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(5)个小伙伴在吐槽
  1. 您好!非常感谢您的分享,对我这种初学的菜鸟来说,非常受益。 目前只有9章,后续是否会持续更新呢?非常期待,谢谢~~
    顾诗2018-04-30 18:00 回复
    • 菜鸟
      会的,最近比较忙,后面好几章的习题都写完了,还没来的及排版,排好版会更新上来的~
      菜鸟2018-05-12 12:49 回复
  2. 大佬(我是真的菜鸟),那个17的函数跟踪是咋回事啊,那个putchar为什么里面可以加一个+n%2 然后就是那个程序到底是怎么运行的啊,大佬你可以详细的说下吗?(菜鸟不省感激).
    小白2018-10-31 19:58 回复
    • 菜鸟
      不好意思回复晚了,那个pb函数就是将一个数转成2进制输出出来了,以下面的函数调用pb(8)来说明,8不等0,pb(8 / 2)进行迭代,即pb(4),pb(2),pb(1), pb(0)时结束,pb(0)则是迭代终止,然后返回。pb(1)的下一句putcher()里 1 % 2 = 1,然后加上'0'转ASCII码后进行输出1【注意char类型也是可以参与计算的,就是其ASCII码值】,2 % 2和4 % 2以及8 % 2都是输出0,最后输入一个8显示1000。不知道这么讲解决你的疑惑了没^_^
      菜鸟2018-11-12 10:05 回复
  3. Say, you got a nice blog post.Thanks Again.
    porno cocuk2019-01-14 05:09 回复