C语言程序设计(第5版)习题解答-第5章

第五章

注:以下所有代码需要添加头文件<stdio.h>、<math.h>

  1. 例5.6的三个程序
    代码如下
void matrix_4x5_program1();
void matrix_4x5_program2();
void matrix_4x5_program3();
int main()
{
    matrix_4x5_program1();
    matrix_4x5_program2();
    matrix_4x5_program3();
    return 0;
}

void matrix_4x5_program1()
{
    int num = 0;
    for(int i = 1; i <= 4; i++)
    {
        for(int j = 1; j <= 5; j++)
        {
            num++;
            printf("%d\t", i * j);
            if(num % 5 == 0) printf("\n");
        }
    }
    printf("\n");
}

void matrix_4x5_program2()
{
    int num = 0;
    for(int i = 1; i <= 4; i++)
    {
        for(int j = 1; j <= 5; j++)
        {
            num++;
            if(i == 3)
            {
                printf("\n");
                num--;
                break;
            }
            printf("%d\t", i * j);
            if(num % 5 == 0) printf("\n");
        }
    }
    printf("\n");
}

void matrix_4x5_program3()
{
    int num = 0;
    for(int i = 1; i <= 4; i++)
    {
        for(int j = 1; j <= 5; j++)
        {
            num++;
            if(i == 3 && j == 1) continue;
            printf("%d\t", i * j);
            if(num % 5 == 0) printf("\n");
        }
    }
}
  1. 补充例5.7程序
    代码如下
int main()
{
    int sign = 1, n = 1, count = 0;
    double pi = 0.0, term = 1.0;
    while(fabs(term) > 1e-8)
    {
        pi += term;
        n += 2;
        sign *= -1;
        term = sign * 1.0 / n;
        count++;
    }
    printf("pi = %10.8f\n", pi * 4);
    printf("count = %d\n", count);
    return 0;
}
  1. 求两个正整数的最大公约数和最小公倍数
    代码如下
void gcd_lcm();
int main()
{
    gcd_lcm();
    return 0;
}

void gcd_lcm()
{
    int a, b, gcd, lcm, temp;
    printf("a = ");
    scanf("%d", &a);
    printf("b = ");
    scanf("%d", &b);
    if(a < b)
    {
        temp = a;
        a = b;
        b = temp;
    }
    lcm = a * b;
    while(b != 0)
    {
        gcd = a % b;
        a = b;
        b = gcd;
    }
    printf("gcd = %d, lcm = %d\n", a, lcm / a);
}
  1. 统计一行字符中的英文字母、数字、空格和其他字符的个数
    代码如下
void count_char();
int main()
{
    count_char();
    return 0;
}

void count_char()
{
    char ch;
    int letters = 0, space = 0, digit = 0, other = 0;
    while((ch = getchar()) != '\n')
    {
        if((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
        {
            letters++;
        }
        else if(ch == ' ')
        {
            space++;
        }
        else if(ch >= '0' && ch <= '9')
        {
            digit++;
        }
        else
        {
            other++;
        }
    }
    printf("letters = %d, space = %d, digit = %d, other = %d\n", letters, space, digit, other);
}
  1. 求数列的前n项和
    代码如下
void sum_sequences();
int main()
{
    sum_sequences();
    return 0;
}

void sum_sequences()
{
    int a, len, temp = 0, sum = 0;
    printf("a = ");
    scanf("%d", &a);
    printf("len = ");
    scanf("%d", &len);
    for(int i = 1; i <= len; i++)
    {
        temp += a;
        sum += temp;
        a *= 10;
    }
    printf("sum = %d\n", sum);
}
  1. 求阶乘数列前n项的和
    代码如下
void factorial_sequences();
int main()
{
    factorial_sequences();
    return 0;
}

void factorial_sequences()
{
    int len = 20;
    double temp =1, sum = 0;
    for(int i = 1; i <= len; i++)
    {
        temp *= i;
        sum += temp;
    }
    printf("sum = %22.15e\n", sum);
}
  1. 求数列的前n项和
    代码如下
void sum_sequences();
int main()
{
    sum_sequences();
    return 0;
}

void sum_sequences()
{
    int len1 = 100, len2 = 50, len3 = 10;
    double sum1 = 0, sum2 = 0, sum3 = 0;
    for(int i = 1; i <= len1; i++)
    {
        sum1 += i;
    }
    for(int i = 1; i <= len2; i++)
    {
        sum2 += pow(i, 2);
    }
    for(int i = 1; i <= len3; i++)
    {
        sum3 += pow(i, -1);
    }
    printf("sum = %15.6f", sum1 + sum2 + sum3);
}
  1. 输出1000以内所有的水仙花数
    代码如下
/*
    水仙花数:153 = 1^3 + 5^3 + 3^3
    - 定义三个整型变量,分别存储百位,十位,个位
        - 计算百位直接除以100,hundred = 123 / 100 = 1
        - 计算十位直接除以10,ten = 123 / 10 - hundred * 10 = 2
        - 计算个位直接取余,one = 123 % 10 = 3
    - 定义一个变量,存储百位的三次方 + 十位的三次方 + 个位的三次方
    - 判断当前数是否等于这个变量
*/
void is_shuixianhua();
int main()
{
    is_shuixianhua();
    return 0;
}

void is_shuixianhua()
{
    int num, i, j, max = 1000, min = 100;
    printf("parcissus numbers are: \n");
    for(min; min < max; min++)
    {
        i = min / 100;
        j = min / 10 - i * 10;
        num = min % 10;
        if(min == i * i * i + j * j * j + num * num * num)
        {
            printf("%d ", min);
        }
    }
    printf("\n");
}
  1. 输出1000以内所有的完美数
    代码如下
/*
    从2开始,因为2的因子只有1和它本身,所以从2开始,有以下变量
    - a,从2开始
    - sum,因子的累加和,验证a == sum
    - i,计算因子,满足a % i == 0
*/
#define MAX 1000
void is_perfect_program1();
void is_perfect_program2();
int main()
{
    is_perfect_program1();
    is_perfect_program2();
    return 0;
}

void is_perfect_program1()
{
    int m, s;
    for(m = 2; m < MAX; m++)
    {
        // 从2开始,因为2的因子只有1和它本身,所以从2开始
        s = 0;
        for(int i = 1; i < m; i++)
        {
            // 计算m的因子,将因子累加
            if(m % i == 0) s += i;
        }
        if(s == m)
        {
            // 如果因子的累加和等于m,那么m就是完美数
            printf("%d, its factor is: ", m);
            for(int i = 1; i < m; i++)
            {
                // 再次计算m的因子,并将其输出
                if(m % i == 0) printf("%d ", i);
            }
            printf("\n");
        }
    }
}

void is_perfect_program2()
{
    int k1, k2, k3, k4, k5, k6, k7, k8, k9, k10;
    int a = 2, sum = 0, count;
    for(a; a <= MAX; a++)
    {
        count = 0;
        sum = a;                        // 存放尚未求出的因子之和,先存入本身
        for(int i = 1; i < a; i++)      // 计算因子
        {
            if(a % i == 0)
            {
                count++;                // 计算因子的个数
                sum -= i;               // 减去所找到的因子
                switch(count)           // 将找到的因子赋值给对应的变量
                {
                case 1:
                    k1 = i;
                    break;
                case 2:
                    k2 = i;
                    break;
                case 3:
                    k3 = i;
                    break;
                case 4:
                    k4 = i;
                    break;
                case 5:
                    k5 = i;
                    break;
                case 6:
                    k6 = i;
                    break;
                case 7:
                    k7 = i;
                    break;
                case 8:
                    k8 = i;
                    break;
                case 9:
                    k9 = i;
                    break;
                case 10:
                    k10 = i;
                    break;
                }
            }
        }
        if(sum == 0)
        {
            printf_s("%d, its factors are ", a);
            if(count > 1) printf_s("%d, %d", k1, k2);   // 数至少2个因子时,输出前2个因子,即1和它本身
            if(count > 2) printf_s(", %d", k3);
            if(count > 3) printf_s(", %d", k4);
            if(count > 4) printf_s(", %d", k5);
            if(count > 5) printf_s(", %d", k6);
            if(count > 6) printf_s(", %d", k7);
            if(count > 7) printf_s(", %d", k8);
            if(count > 8) printf_s(", %d", k9);
            if(count > 9) printf_s(", %d", k10);
            printf_s("\n");
        }
    }
}
  1. 计算分数数列前n项和
    代码如下
/*
    第一个分数是2/1,后一个分数分子是前一个分数分子分母之和,分母是前一个分数分子
    - 定义两个变量,分子和分母;一个临时变量,存储分子;一个变量,存储分数的和
    - 在每一次for循环中,先将当前分数累加至和变量中;再将当前分数的分子赋值给临时变量;
      计算下一个分数的分子和分母,进行下一次循环
*/
void sum_fractional_sequences_program1();
void sum_fractional_sequences_program2();
int main()
{
    sum_fractional_sequences_program1();
    sum_fractional_sequences_program2();
    return 0;
}

void sum_fractional_sequences_program1()
{
    int numerator1 = 2, denominator1 = 1, numerator2, denominator2;
    double sum = 0, fraction1, fraction2;
    fraction1 = (double)numerator1 / denominator1;
    sum += fraction1;
    for(int i = 1; i < 20; i++)
    {
        numerator2 = numerator1 + denominator1;
        denominator2 = numerator1;
        fraction2 = (double)numerator2 / denominator2;
        sum += fraction2;
        fraction1 = fraction2;
        numerator1 = numerator2;
        denominator1 = denominator2;
    }
    printf("sum = %f\n", sum);
}

void sum_fractional_sequences_program2()
{
    int numerator = 2, denominator = 1, temp;
    double sum = 0;
    for(int i = 1; i <= 20; i++)
    {
        // 对program1的改进,减少变量的冗余定义
        sum += (double)numerator / denominator;
        temp = numerator;
        numerator = numerator + denominator;
        denominator = temp;
    }
    printf("sum = %f\n", sum);
}
  1. 计算球所经过的高度以及第10次反弹的高度
    代码如下
void ball_rebound_height_program1();
int main()
{
    ball_rebound_height_program1();
    return 0;
}

void ball_rebound_height_program1()
{
    double height = 100, sum = 0;
    sum += height;
    for(int i = 1; i < 10; i++)
    {
        height /= 2;
        sum += height * 2;
    }
    printf("sum = %f\n", sum);
    printf("height = %f\n", height);
}
  1. 猴子吃桃问题
    代码如下
/*
    数学分析,quantities(n) = (quantities(n - 1) + 1) * 2, n > 1
*/
void peach_quantity_program1();
int peach_quantity_program2(int len);
int main()
{
    peach_quantity_program1();
    printf("peach = %d\n", peach_quantity_program2(10));
    return 0;
}

void peach_quantity_program1()
{
    int peach = 1;
    for(int i = 1; i < 10; i++)
    {
        peach = (peach + 1) * 2;
    }
    printf("peach = %d\n", peach);
}

int peach_quantity_program2(int len)
{
    // 递归
    int result = 0;
    if(len == 1) result = 1;
    else result = (peach_quantity_program2(len - 1) + 1) * 2;
    return result;
}
  1. 迭代法求平方根
    代码如下
/*
    迭代法,求平方根
    - 设定一个初始值x0
    - 设定一个临时变量xn,用迭代公式计算xn+1
    - 将xn赋值给x0,xn+1赋值给xn,进行下一次循环
    - 直到|xn - x0| < 1e-5

float sqrt_root(float num);
int main()
{
    printf("sqrt = %f\n", sqrt_root(2));
    return 0;
}

float sqrt_root(float num)
{
    float x0, xn;
    x0 = num / 2;
    xn = (x0 + num / x0) / 2;
    while(fabs(xn - x0) > 1e-5)
    {
        x0 = xn;
        xn = (x0 + num / x0) / 2;
    }
    return xn;
}
  1. 牛顿法求方程根
    代码如下
/*
    牛顿迭代法即牛顿切线法
    - 设定一个初始值x0,f(x0) = f'(x0)(x1 - x0)
    - 将x0赋值给x1,x1赋值给x0,进行下一次循环
    - 直到|xn - x0| < 1e-5
*/
double solve_quadratic_equation();
int main()
{
    double root0 = solve_quadratic_equation();
    printf_s("root is %5.2f\n", root0);
    return 0;
}

double solve_quadratic_equation()
{
    double x1, x0, f, f1;
    x1 = 1.5;
    do
    {
        x0 = x1;
        f = ((2 * x0 - 4) * x0 + 3) * x0 - 6;
        f1 = (6 * x0 - 8) * x0 + 3;
        x1 = x0 - f / f1;
    } while (fabs(x1 - x0) > 1e-5);
    return x1;
}
  1. 二分法求方程根
    代码如下
/*
    二分法,求方程的根
    - 设定一个初始值x1和x2,f(x1)和f(x2),若f(x1)和f(x2)同号,怎重新设定x1和x2直至f(x1)和f(x2)异号
    - 求出x0 = (x1 + x2) / 2,f(x0)
    - 若f(x0)和f(x1)同号,则在[x0, x2]中寻根,用x0代替x1,f(x0)代替f(x1)
    - 若f(x0)和f(x1)同号,则在[x1, x0]中寻根,用x0代替x2,f(x0)代替f(x2)
    - 直到|f(x0)| < 1e-5
*/
void binary_search();
int main()
{
    binary_search();
    return 0;
}

void binary_search()
{
    float x0, x1 = -10, x2 = 10, fx0, fx1, fx2;
    do
    {
        fx1 = x1 * ((2 * x1 - 4) * x1 + 3) - 6;
        fx2 = x2 * ((2 * x2 - 4) * x2 + 3) - 6;
    } while (fx1 * fx2 > 0);
    do
    {
        x0 = (x1 + x2) / 2;
        fx0 = x0 * ((2 * x0 - 4) * x0 + 3) - 6;
        if((fx0 * fx1) < 0)
        {
            x2 = x0;
            fx2 = fx0;
        }
        else
        {
            x1 = x0;
            fx1 = fx0;
        }
    } while (fabs(fx0) > 1e-5);
    printf_s("root is %5.2f\n", x0);
}
  1. 输出图案
    代码如下
/*
    打印图案一半分为上下、左右来进行打印,要理清逻辑
*/
void print_pattern();
int main()
{
    print_pattern();
    return 0;
}

void print_pattern()
{
    for(int i = 0; i <= 3; i++)
    {
        for(int j = 0; j <= 2 - i; j++)
        {
            printf(" ");
        }
        for(int k = 0; k <= 2 * i; k++)
        {
            printf("*");
        }
        printf("\n");
    }
    for(int i = 0; i <= 2; i++)
    {
        for(int j = 0; j <= i; j++)
        {
            printf(" ");
        }
        for(int k = 0; k <= 4 - 2 * i; k++)
        {
            printf("*");
        }
        printf("\n");
    }
}
  1. 编程找出三对赛手的名单
    代码如下
void print_name();
int main()
{
    print_name();
    return 0;
}

void print_name()
{
    char i, j, k;
    for(i = 'x'; i <= 'z'; i++)
    {
        for(j = 'x'; j <= 'z'; j++)
        {
            if(i != j)
            {
                for(k = 'x'; k <= 'z'; k++)
                {
                    if(i != k && j != k)
                    {
                        if(i != 'x' && k != 'x' && k != 'z')
                        {
                            printf("A---%c\nB---%c\nC---%c\n", i, j, k);
                        }
                    }
                }
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值