《C Prime Plus》(第六版) 第06章 C控制语句:循环 例题集和编程练习

​​​​​​​

  • OS: Mac Catalina 10.15.4 
  • Hardware: Intel Core i9/16G 2667MHz DDR4
  • 编译器版本:Mac Xcode 11.6 

第06章 C控制语句:循环


目录

例题1  依据用户输入的整数求和 Page 137

例题2  何时退出循环 Page 141

例题3  无限循环 Page 141

例题4  while循环分号的错误放置 Page 142

例题5 浮点数的比较 page 144

例题6 真值,假值 Page 144

例题7 表示真值的其它方法 Page 145

例题8 逻辑判断=会导致的错误 page 146

例题9 _Bool类型的使用 Page 148

例题10 指定循环次数的while循环 Page 150

例题11 for循环 Page 151

例题12 for 循环求x^3 Page 151

例题13 逗号运算符  Page 156

例题14 使用for做数列计算 Page 158

例题15 do...while 循环 Page 159

例题16 使用while循环重写例题15 Page 160

例题17 使用嵌套循环 Page 162

例题18 依赖外部循环的嵌套循环 Page 163

例题19 使用循环处理数组 Page 165

例题20 计算数的整数幂 Page 167

编程练习

习题1

习题2

习题3

习题4

习题5

习题6

习题7

习题8

习题9

习题10

习题11

习题12

习题13

习题14

习题15

习题16

习题17

习题18


​​​​​​​​​​​​​​

例题1  依据用户输入的整数求和 Page 137

/* summing.c -- 根据用户输入的整数求和 */
#include <stdio.h>

int main(void)
{
    long num;
    long sum = 0L;      /* 把sum初始化为0 */
    int status;
    
    printf("Please enter an integer to be summed ");
    printf("(q to quit): ");
    status = scanf("%ld", &num);
    while (status == 1) /* ==的意思是“等于” */
    {
        sum = sum + num;
        printf("Please enter next integer (q to quit): ");
        status = scanf("%ld", &num);
    }
    printf("Those integers sum to %ld.\n", sum);
    
    return 0;
}

程序输出结果:

例题2  何时退出循环 Page 141

/* when.c -- 何时退出循环 */
#include <stdio.h>

int main(void)
{
    int n =  5;
    
    while (n < 7)
    {
        printf("n = %d\n", n);
        n++;
        printf("Now n = %d\n", n);
    }
    printf("The loop has finished.\n");
    
    return 0;
}

程序输出结果:

例题3  无限循环 Page 141

/* while1.c -- 注意花括号的使用 */
/* 糟糕的代码创建了一个无限循环 */
#include <stdio.h>

int main(void)
{
    int n = 0;
    
    while (n < 3)
        printf("n is %d\n", n);
        n++;
    printf("That's all this program does\n");
    
    return 0;
}

程序输出:

注意:

  • 虽然n++写在了printf后面,但是没有使用花括号将其包含在while语句范围

例题4  while循环分号的错误放置 Page 142

/* while2.c -- 注意分号的位置 */
#include <stdio.h>

int main(void)
{
    int n = 0;
    
    while (n++ < 3);
        printf("n is %d\n", n);
    printf("That's all this program does.\n");
    
    return 0;
}

程序输出:

 注意:

  • while(n++ < 3)后面跟了;号,表示是一个空循环,其后的printf("n is %d\n", n)并不在循环内部。
  • 如果在程序上的确需要空循环,则使用分号(;)单独一行,并加以注释为何要空循环。

例题5 浮点数的比较 page 144

// cmpflt.c -- 浮点数的比较
#include <stdio.h>
#include <math.h>

int main(void)
{
    const double ANSWER = 3.14159;
    double response;
    
    printf("What is the value of pi?\n");
    scanf("%lf", &response);
    while (fabs(response - ANSWER) > 0.0001)
    {
        printf("Try again!\n");
        scanf("%lf", &response);
    }
    printf("Close enought!\n");
    
    return 0;
}

程序输出结果:

 注意:

  • 浮点数比较,避免使用==,>=,<=,而使用>或者<

例题6 真值,假值 Page 144

/* t_and_f.c -- C中的真和假的值 */
#include <stdio.h>

int main(void)
{
    int true_val, false_val;
    
    true_val = (10 > 2);        // 关系为真的值
    false_val = (10 == 2);      // 关系为假的值
    printf("true = %d; false = %d\n", true_val, false_val);
    
    return 0;
}

程序输出结果:

注意:

  • true!=0
  • false=0

例题7 表示真值的其它方法 Page 145

// truth.c -- 哪些值为真
#include <stdio.h>

int main(void)
{
    int n = 3;
    
    while(n)
        printf("%2d is true\n", n--);
    printf("%2d is false\n", n);
    
    n = -3;
    while(n)
        printf("%2d is true\n", n++);
    printf("%2d is false\n", n);
    
    return 0;
}

程序输出结果:

注意:

  • true!=0
  • false=0

例题8 逻辑判断=会导致的错误 page 146

// trouble.c -- 误用=会导致无限循环
#include <stdio.h>

int main(void)
{
    long num;
    long sum = 0L;
    int status;
    
    printf("Please enter an integer to be summed ");
    printf("(q to quit): ");
    status = scanf("%ld", &num);
    while (status = 1)
    {
        sum = sum + num;
        printf("Please enter next integer (q to quit): ");
        status = scanf("%ld", &num);
    }
    printf("Those integers sum to %ld.\n", sum);
    
    return 0;
}

程序输出结果:

注意:

  • scanf读入一个失败的数值,会将这个值返回原来的地方,当再次读入时有发生了错误。进入了无限循环的错误机制。 

xcode有代码检错机制,会提示用户的代码存在错误。如下图:

例题9 _Bool类型的使用 Page 148

// boolean.c -- 使用_Bool类型的便利variable
#include <stdio.h>

int main(void)
{
    long num;
    long sum = 0L;
    _Bool input_is_good;
    
    printf("Please enter an integer to be summed ");
    printf("(q to quit): ");
    input_is_good = (scanf("%ld", &num) == 1);
    while (input_is_good)
    {
        sum = sum + num;
        printf("Please enter next integer (q to quit): ");
        input_is_good = (scanf("%ld", &num) == 1);
    }
    printf("Those integers sum to %ld.\n", sum);
    
    return 0;
}

程序输出:

注意:

  • _Bool 为C99标准 
  • 如果引用<stdbool.h>则可以使用bool代替_Bool,并且可使用true和false,这样可以和c++兼容
  • 如果编译器不支持_Bool,则使用int代替

例题10 指定循环次数的while循环 Page 150

// sweetie1.c -- 一个计数循环
#include <stdio.h>

int main(void)
{
    const int NUMBER = 22;
    int count = 1;                      // 初始化
    
    while (count <= NUMBER)             // 测试
    {
        printf("Be my Valentine!\n");   // 行为
        count++;                        // 更新计数器
    }
    
    return 0;
}

输出结果:

注意:

  • 类似这种循环可以使用for循环代替

例题11 for循环 Page 151

// sweetie2.c -- 使用for循环的计数循环
#include <stdio.h>

int main(void)
{
    const int NUMBER = 22;
    int count;
    
    for (count = 1; count <= NUMBER; count++)
        printf("Be my Valentine!\n");
    
    return 0;
}

程序输出结果 :

注意:

  • 如果循环变量在循环外申明且for语句有初始化循环变量,则无需对循环外的循环变量初始化 

例题12 for 循环求x^3 Page 151

#include <stdio.h>

int main(void)
{
    int num;
    
    printf("    n  n cubed\n");
    
    for (num = 1; num <= 6; num++)
        printf("%5d %5d\n", num, num * num * num);
    
    return 0;
}

程序输出结果:

例题13 逗号运算符  Page 156

// postage.c -- 一类邮资
#include <stdio.h>

int main(void)
{
    const int FIRST_OZ = 46;  // 2013年邮资
    const int NEXT_OZ = 20;   // 2013年邮资
    int ounces, cost;
    
    printf(" ounces  cost\n");
    for (ounces = 1, cost = FIRST_OZ; ounces <= 16; ounces++, cost += NEXT_OZ)
        printf("%5d   $%4.2f\n", ounces, cost / 100.0);
    
    return 0;
}

程序输出结果:

例题14 使用for做数列计算 Page 158

/* zeno.c -- 求序列的和 */
#include <stdio.h>

int main(void)
{
    int t_ct;   // 项计数
    double time, power_of_2;
    int limit;
    
    printf("Enter the number of terms you want: ");
    scanf("%d", &limit);
    for (time = 0, power_of_2 = 1, t_ct = 1; t_ct <= limit;
         t_ct++, power_of_2 *= 2.0)
    {
        time += 1.0 / power_of_2;
        printf("time = %f when terms = %d.\n", time, t_ct);
    }
    
    return 0;
}

输出结果:

 注意:

  • 在做数学计算的程序中,因考虑数学方法化简后,再写程序

例题15 do...while 循环 Page 159

/* do_while.c -- 出口条件循环 */
#include <stdio.h>

int main(void)
{
    const int secret_code = 13;
    int code_entered;
    
    do
    {
        printf("To enter the triskaidekaphobia therapy club,\n");
        printf("please enter the secret code number: ");
        scanf("%d", &code_entered);
    }while (code_entered != secret_code);
    printf("Congratulations! You are cured!\n");
    
    return 0;
}

程序输出结果:

注意:

  • do...while循环至少执行一次

例题16 使用while循环重写例题15 Page 160

/* entry.c -- 出口条件循环 */
#include <stdio.h>

int main(void)
{
    const int secret_code = 13;
    int code_entred;
    
    printf("To enter the triskaidekaphobia therapy club,\n");
    printf("please enter the secret code number: ");
    scanf("%d", &code_entred);
    while (code_entred != secret_code)
    {
        printf("To enter the triskaidekaphobia therapy club,\n");
        printf("please enter the secret code number: ");
        scanf("%d", &code_entred);
    }
    printf("Congratulations! Your are cured!\n");
    
    return 0;
}

程序输出结果:

注意:

  • 依据实际情况,合理选择while循环,for循环,do...while循环

例题17 使用嵌套循环 Page 162

/* rows1.c -- 使用嵌套循环 */
#include <stdio.h>
#define ROWS 6
#define CHARS 10

int main(void)
{
    int row;
    char ch;
    
    for (row = 0; row < ROWS; row++)
    {
        for(ch = 'A'; ch < ('A' + CHARS); ch++)
            printf("%c", ch);
        printf("\n");
    }
    
    return 0;
}

程序输出结果

例题18 依赖外部循环的嵌套循环 Page 163

// rows2.c -- 依赖外部循环的嵌套循环
#include <stdio.h>
int main(void)
{
    const int ROWS = 6;
    const int CHARS = 6;
    int row;
    char ch;
    
    for (row = 0; row < ROWS; row++)
    {
        for (ch = ('A' + row); ch < ('A' + CHARS); ch++)
            printf("%c", ch);
        printf("\n");
    }
    
    return 0;
}

程序输出结果:

例题19 使用循环处理数组 Page 165

// scores_in.c -- 使用循环处理数组
#include <stdio.h>
#define SIZE 10
#define PAR 72
int main(void)
{
    int index, score[SIZE];
    int sum = 0;
    float average;
    
    printf("Enter %d golf scores:\n", SIZE);
    for (index = 0; index < SIZE; index++)
        scanf("%d", &score[index]); // 读取10个分数
    printf("The scores read in are as follows:\n");
    for (index = 0; index < SIZE; index++)
        printf("%5d", score[index]); //验证输入
    printf("\n");
    for (index = 0; index < SIZE; index++)
        sum += score[index];        //求总分
    average = (float)sum / SIZE;    //求平均分
    printf("Sum of scores = %d, average = %.2f\n", sum, average);
    printf("That's a handicap of %.0f.\n", average - PAR); // 求差点(它是平均分与标准分的差值)
    
    return 0;
}

程序输出结果:

注意:

  • 虽然输入了11个数字,但是只接受了10个数字,因为只使用10次循环读入数字
  • 读入给数组的数字应使用&score[index]

例题20 计算数的整数幂 Page 167

// power.c --计算数的整数次幂
#include <stdio.h>
double power(double n, int p); // ANSI函数原型

int main(void)
{
    double x, xpow;
    int exp;
    
    printf("Enter a number and the positive integer power");
    printf(" to which\nthe number will be raised. Enter q");
    printf(" to quit.\n");
    while (scanf("%lf%d", &x, &exp) == 2)
    {
        xpow = power(x, exp); //函数调用
        printf("%.3g to the power %d is %.5g\n", x, exp, xpow);
        printf("Enter next pair of numbers or q to quit.\n");
    }
    printf("Hope you enjoyed this power trip -- bye!\n");
    
    return 0;
}

double power(double n, int p) // 函数定义
{
    double power = 1;
    int i;
    
    for (i = 1; i <= p; i++)
        power *= n;
    
    return power; //返回pow的值
}

程序运行结果:

 注意:

  • scanf("%lf", &x)读入的数据存储为double类型
  • printf("%.3g", x)输出小数位保留3位的double类型


编程练习

习题1

编写一个程序,创建一个包含26个元素的数组,并在其中存储26个小写字母。然后打印数组的所有内容

#include <stdio.h>
#define SIZE 26
#define CHAR 'a'

void init_array(char* array);
void print_array(char* array);

int main(void)
{
    char array[SIZE];
    printf("array size 26, init array start with 'a'.\n");
    init_array(array);
    printf("now start print array.\n");
    print_array(array);
    
    return 0;
}

void init_array(char* array)
{
    int index;
    
    for (index = 0; index < SIZE; index++)
        array[index] = CHAR + index;
}

void print_array(char* array)
{
    int index;
    
    for (index = 0; index < SIZE; index++)
        printf("%2c", array[index]);
    printf("\n");
}

程序输出结果:

​​​​​​​

习题2

使用嵌套循环,按下面的格式打印字符:

#include <stdio.h>
#define ROW 5

int main(void)
{
    int row, count;
    
    for (row = 0; row < ROW; row++)
    {
        for(count = 0; count <= row; count++)
            printf("$");
        printf("\n");
    }
    
    return 0;
}

程序输出结果

习题3

使用嵌套循环,按下面的格式打印字母:

#include <stdio.h>
#define ROW  6

int main(void)
{
    int row, ch;
    
    for (row = 0; row < ROW; row++)
    {
        for (ch = 0; ch <= row; ch++)
            printf("%c", 'F' - ch);
        printf("\n");
    }
    
    return 0;
}

 程序输出结果:

习题4

使用嵌套循环,按下面的格式打印字母:

#include <stdio.h>
#define ROW  6

int main(void)
{
    int row, letter;
    char ch = 'A';
    
    for (row = 0; row < ROW; row++)
    {
        for (letter = 0; letter <= row; letter++)
            printf("%c", ch + letter);
        ch += letter;
        printf("\n");
    }
    
    return 0;
}

 程序输出结果:

​​​​​​​

习题5

编写一个程序,提示用户输入大写字母。使用嵌套循环以下面金字塔型的格式打印字母:

​​​​​​​ 

打印这样的图形,要根据用户输入的字母来决定。例如,上面的图形是在用户输入E后的打印结果。

提示:如果外层循环处理行,每行使用3个内层循环,分别处理空格、以升序打印字母、以降序打印字母。

#include <stdio.h>

int main(void)
{
    const char A = 'A';
    const char Z = 'Z';
    
    int i, j;
    char ch; //输入的字母
    printf("Enter an alphabet(A~Z): ");
    scanf("%c", &ch);
    
    if(ch >= A && ch <= Z)
    {
        //控制行
        for(i = A; i <= ch; i++)
        {
            //行前空格
            for(j = ch - i; j > 0; j--)
                printf(" ");
            //开始输出中间及左边的字母
            for(j = A; j <= i; j++)
                printf("%c", j);
            //开始输出中间右边的字母
            for(j -= 2; j >= A; j--) //j -= 2表示回到输出字符的前一个字符
                printf("%c", j);
            printf("\n");
        }
    } else
        printf("Must enter alphabet(A~Z), program exit.\n");
    
    return 0;
}

程序输出结果:

​​​​​​​

习题6

编写一个程序打印一个表格,每一行打印一个整数、该数的平方、该数的立方。

要求用户输入表格的上下限。使用一个for循环

#include <stdio.h>

int main(void)
{
    int start, end;
    
    printf("输入表格上下限制整数(步长=1):");
    scanf("%d%d", &start, &end);
    
    printf("%4s|%6s|%6s\n", "x", "x^2", "x^3");
    printf("-----------------------------\n");
    for(; start <= end; start++)
    {
        printf("%4d|%6d|%6d\n", start, start * start, start * start * start);
    }
    printf("-----------------------------\n");
    
    return 0;
}

程序输出结果 :

习题7

编写一个程序把一个单词读入一个字符数组中,然后倒序打印这个单词。

提示:strlen()函数(第4章介绍过)可用于计算数组最后一个字符的下标;

#include <stdio.h>
#include <string.h>

int main(void)
{
    char ch_array[181];
    size_t index;
    
    printf("输入一个单词,按回车结束输入: ");
    scanf("%s", ch_array);
    
    printf("倒序打印单词: ");
    /*
      size_t index = 0
      当index - 1时,index = 18446744073709551615
      将导致无限循环,解决方案是:使用循环控制
     */
    for(index = strlen(ch_array); index > 0; index--)
    {
        printf("%c", ch_array[index - 1]);
    }
    printf("\n");
    
    return 0;
}

程序输出结果:

 注意:

  • 1. 读入字符串到字符数组scanf()不需要地址符号 &
  • 2. strlen()使用头文件<string.h>
  • 3. size_t类型在0时,当减1时,值会变成:18446744073709551615,因为它是无符号型,所以在循环控制时不能使用<0来做检查

习题8

编写一个程序,要求用户输入两个浮点数,并打印两数之差除以两数之积的结果。在用户输入非数字之前,

程序应循环处理用户输入的每对值

#include <stdio.h>
#include <math.h>

#define EPSINON 0.000001  //计算误差不能超过0.000001

int main(void)
{
    float a, b;
    int count;
    char getBuff = '\0';
    
    printf("输入两个浮点数: ");
    count = scanf("%f%f", &a, &b);
    //必须有两个数被正确读入,两个数相乘不能为0
    while(count != 2 || abs(a * b - 0.0) <= EPSINON)
    {
        if(count != 2)
            printf("输入的数据无效,请输入两个浮点数:");
        else
            printf("分母不能为0.计算失败,请输入两个浮点数:");
        //读取失败后,清除scan缓冲区
        while((getBuff=getchar()!='\n' && getBuff != EOF));
        //重新输入
        count = scanf("%f%f", &a, &b);
    }
    
    printf("两数之差除以两数之积: (%f - %f) / (%f * %f) = %f\n",
           a, b, a, b, (a - b) / (a * b));
    
    return 0;
}

程序输出结果:

 注意:

  • 1. scanf()读入失败后,驻留在缓存区的字符要被清除,否则下次读入依旧错误
  • 2. float类型的读入或者计算会有误差,比如读入3.2但是数据储存为3.200005,不能直接使用浮点数进行比较,需使用误差范围控制。这里使用EPSINON=0.000001控制
  • 3. 计算这个例题时要控制分母不能为0,如果为0,将导致计算结果为无穷大(inf)

习题9

修改练习8,使用一个函数返回计算结果

#include <stdio.h>
#include <math.h>

#define EPSINON 0.000001  //计算误差不能超过0.000001

float cal(float a, float b);

int main(void)
{
    float a, b;
    int count;
    char getBuff = '\0';
    
    printf("输入两个浮点数: ");
    count = scanf("%f%f", &a, &b);
    //必须有两个数被正确读入,两个数相乘不能为0
    while(count != 2 || abs(a * b - 0.0) <= EPSINON)
    {
        if(count != 2)
            printf("输入的数据无效,请输入两个浮点数:");
        else
            printf("分母不能为0.计算失败,请输入两个浮点数:");
        //读取失败后,清除scan缓冲区
        while((getBuff=getchar()!='\n' && getBuff != EOF));
        //重新输入
        count = scanf("%f%f", &a, &b);
    }
    
    printf("两数之差除以两数之积: (%f - %f) / (%f * %f) = %f\n",
           a, b, a, b, cal(a, b));
    
    return 0;
}

float cal(float a, float b)
{
    return (a - b) / (a * b);
}

程序输出结果:

​​​​​​​

习题10

10. 编写一个程序,要求用户输入一个上限整数和下限整数,计算从上限到下限范围内所有整数的平方和,并显示计算结果。然后程序继续提示用户输入上限和下限整数,并显示结果,直到用户输入的上限整数等于或小于下限整数为止。程序的运行示例如下:

Enter lower and upper integer limits: 5 9
The sums of the squares from 25 to 81 is 255
Enter next set of limits: 3 25
The sums of the squares from 9 to 625 is 5520
Enter next set of limits: 5 5
Done
#include <stdio.h>

unsigned int sums(int a, int b);

int main(void)
{
    int a, b;
    do
    {
        printf("Enter lower and upper integer limits: ");
        scanf("%d%d", &a, &b);
        if(a >= b) break;
        
        printf("The sums of the squares from %d to %d is %u\n", a, b, sums(a, b));
    }while(1);
    printf("Done\n");
    
    return 0;
}

unsigned int sums(int a, int b)
{
    int i = a;
    unsigned int sums = 0;
    
    for(; i <= b; i++)
    {
        sums += i * i;
    }
    
    return sums;
}

程序输出结果 :

习题11

编写一个程序,在数组中输入8个整数,然后按倒序打印这8个整数

#include <stdio.h>

#define LENGTH 8

int main(void)
{
    int array[LENGTH], index;
    printf("输入8个整数: ");
    for(index = 0; index < LENGTH; index++)
        scanf("%d", &array[index]);
    //倒序输出
    printf("倒序输出:");
    for(index = LENGTH - 1; index >= 0; index--)
        printf(" %d ", array[index]);
    printf("\n");
    
    return 0;
}

程序输出结果:

习题12

考虑下面两个无限序列

     1.0 + 1.0/2.0 + 1.0/3.0 + 1.0/4.0 + ...
     1.0 - 1.0/2.0 + 1.0/3.0 - 1.0/4.0 + ...

编写一个程序计算这两个无限序列的总和,直到达到某次数。提示:奇数个数-1 相乘得-1,偶数个数-1相乘得1。让用户交互地输入指定的次数,当用户输入0或负值时结束输入。查看运行100项、1000项、10000项后的总和,是否发现每个序列都收敛于某值

/*
 对于两个序列求和,可使用简化方法,将上下两个序列上下相加得:
      2 + 2(1.0/3.0) + 2 (1.0/5.0) + ...
     =2(1 + 1.0/3.0 + 1.0 / 5.0 + ...)
 可知,只需要计算奇数项,偶数项全部为0,将所有奇数项相加后乘以2
 */
#include <stdio.h>

double cal_sums(unsigned int count);
double cal_1(unsigned int count);
double cal_2(unsigned int count);

int main(void)
{
    int count = 0;
    printf("输入项: ");
    while(scanf("%d", &count) == 1)
    {
        if(count <= 0)break;
        
        printf("序列1 = %.12lf\n", cal_1(count));
        printf("序列2 = %.12lf\n", cal_2(count));
        printf("序列总和 = %.12lf\n输入项: ", cal_sums(count));
    }
    printf("Done\n");
    
    return 0;
}

//计算序列1
double cal_1(unsigned int count)
{
    double sums = 0;
    unsigned int i = 1;
    
    for(; i <= count; i++)
        sums += 1.0 / i;
    
    return sums;
}

//计算序列2
double cal_2(unsigned int count)
{
    unsigned int i = 1;
    double sums = 0;
    
    for(; i <= count; i++)
    {
        if(i % 2 == 0)
            sums += -1.0 / i;
        else
            sums += 1.0 / i;
    }
    
    return sums;
}

double cal_sums(unsigned int count)
{
    unsigned int i = 1;
    double sums = 0;
    
    //如果是偶数,则总项-1,因为偶数项相加得0
    if(count % 2 == 0) count--;
    
    for(; i <= count; i += 2) //只计算奇数项
    {
        sums += 1.0 / i;
    }
    sums *= 2;
    
    return sums;
}

程序输出结果:

对比数学软件计算结果(Mathematica)

 注意:

  • 1. 对于数值计算的应优先考虑数学上的优化,使用数学方法化简后再编写程序。对于上题的例子求和是,将两个序列上下相加后可简化操作,具体见注释说明
  • 2. 对于数学计算的,应该使用数学软件进行检查是否计算正确
  • 3. 对于舍入误差或者丢弃进度快速计算的参考数值计算相关书籍,比如微分中值定理

习题13

编写一个程序,创建一个包含8个元素的int类型数组,分别把数组元素设置为2的前8次幂。使用for循环设置数组元素的值,使用do while循环显示数组元素的值

#include <stdio.h>
#include <math.h>

#define LENGTH 8

int main(void)
{
    int array[LENGTH], index = 0;
    printf("数组初始化...\n");
    for(; index < LENGTH; index++)
        array[index] = 0;
    
    printf("设置数组....");
    for(index = 0; index < LENGTH; index++)
        array[index] = pow(2, index);
    printf("设置完毕.\n");
    
    printf("输出数组: ");
    index = 0;
    do
    {
        printf(" %d", array[index++]);
    }while(index < LENGTH);
    printf("\nDone.\n");
    
    return 0;
}

程序输出结果:

习题14

编写一个程序,创建两个包含8个元素的double类型数组,使用循环提示用户为第一个数组输入8个值。第二个数组元素的值设置为第一个数组对应元素的累积之和。例如第二个数组的第4个元素的值是第一个数组前4个元素之和,第二个数组的第5个元素的值是第一个数组前5个元素之和(用嵌套循环可以完成,但是利用第二个数组的第5个元素是第二个元素的前4个元素与第一个数组的第5个元素之和,只用一个循环就能完成任务,不需要使用嵌套循环)。最后使用循环显示两个数组的内容,第一个数组显示成一行,第二个数组显示在第一个数组的下一行,而且每个元素都与第一个数组各元素相对应.

#include <stdio.h>

void print(double *p, int size);

int main(void)
{
    const int LENGTH = 8;
    int index = 0;
    double array1[LENGTH], array2[LENGTH];
    
    printf("读入8个double类型数值:");
    for(; index < LENGTH; index++)
        scanf("%lf", &array1[index]);
    
    printf("开始计算...");
    for(index = 0; index < LENGTH; index++)
    {
        if(index == 0)
            array2[index] = array1[index];
        else
            array2[index] = array2[index - 1] + array1[index];
    }
    printf("计算完毕.\n开始输出...\n");
    
    printf("第一个数组:");
    print(array1, LENGTH);
    printf("\n第二个数组:");
    print(array2, LENGTH);
    printf("\nDone.\n");
    
    return 0;
}

void print(double *p, int size)
{
    int index = 0;
    for(; index < size; index++)
        printf(" %.5lf\t", p[index]);
}

程序输出结果:

​​​​​​​

习题15

编写一个程序,读取一行输入,然后把输入的内容倒序打印出来。可以把输入存储在char类型的数组中,假设每行字符不超过255。回忆一下,根据%c转换说明,scanf()函数一次只能从输入中读取一个字符,而且在用户按下Enter键时scanf()函数会生成一个换行字符(\n)

#include <stdio.h>
#include <string.h>

int main(void)
{
    const int LENGTH = 256;
    size_t i = 0;
    char array[LENGTH];
    
    printf("输入一行文本(不超过255个字符):\n");
    scanf("%[^\n]", array); //读入整行字符串,直到遇到回车换行截止
    printf("输入的字符串总长度:%zu\n", strlen(array));
    
    printf("开始倒序输出:");
    for(i = strlen(array); i > 0; i--)
    {
        printf("%c", array[i - 1]);
    }
    printf("\nDone.\n");
    return 0;
}

程序输出结果:

在Debug状态下,可以看到在字符数组array[4]是'\0',如下图。未在windows环境下测试 

习题16

Daphne以10%的单利息投资了100美元(也就是说,每年投资获利相当于原始投资的10%)。Deirdre以5%的复合利息投资了100美元(也就是说,利息是当前余额的5%,包括之前的利息)。编写一个程序,计算需要多少年Dirdre的投资才会超过Daphne,并显示那时两人的投资额

#include <stdio.h>

void printLine(void);

int main(void)
{
    //初始投资成本
    float initDaphne = 100.0, initDeirdre = 100.0;
    float interestDaphne = 0.0, interestDeirdre = 0.0;
    //单利息10%,复利息5%
    const float SINGLE_INTERSET = 0.1, COMPOUND_INTERSET = 0.05;
    //累计投资资本
    float investDaphne = initDaphne, investDeirdre = initDeirdre;
    //年
    short int year = 0;
    
    printf("Daphne\t\t\t\t单利\t\t利率:%.2f%%\t|Deirdre\t\t\t复利\t\t利率:%.2f%%\n",
           SINGLE_INTERSET * 100,COMPOUND_INTERSET * 100);
    printLine();
    printf("年\t投资额\t\t利息\t\t\t余额\t\t\t|投资额\t\t利息\t\t\t余额\n");
    printLine();
    do
    {
        year++;
        //Daphne的利息 = 原始投资 * 10%
        interestDaphne = initDaphne * SINGLE_INTERSET;
        printf("%d\t%.4f\t%.4f\t", year,
               investDaphne, interestDaphne);
        //Daphne的投资额 = 投资额+利息
        investDaphne += interestDaphne;
        printf("\t%.4f\t",investDaphne);
        
        //Deirdre的利息 = 累计投资额 * 5%
        interestDeirdre = investDeirdre * COMPOUND_INTERSET;
        printf("|%.4f\t%.4f", investDeirdre, interestDeirdre);
        //Deirdre的投资额 = 累计投资额+利息
        investDeirdre += interestDeirdre;
        printf("\t\t%.4f\n",investDeirdre);
        
    }while(investDeirdre <= investDaphne);
    printLine();
    
    return 0;
}

void printLine(void)
{
    printf("--------------------------------------");
    printf("--------------------------------------\n");
}

程序运行结果:

 注意:

1. 复利计算方式有专用数学公式,上面的习题没有使用数学公式,数学公式如下:

其中A为总收入,P为投资额,r为复利,k为每年支付的次数,t为年数

参考文献:

《Intermediate Algebra》9th Edition. International Edition. By Gustafson、Karr、Massey. Page 627 

习题17

Chuckie Lucky赢得了100万美元(税后),他把奖金存入年利率8%的账户。在每年的最后一天,Chuckie取出10万美元。便携一个程序,计算多少年后Chuckie会取完账户的钱?

#include <stdio.h>

void printLine(void);

int main(void)
{
    //初始投资成本
    float init = 1000000;
    float interest = 0.08;
    //复利息8%
    const float COMPOUND_INTERSET = 0.08;
    //每年年末固定取走一笔10万的金额
    const float WITHDRAW_MONDY = 100000;
    //累计投资资本
    float invest = init;
    //年
    short int year = 0;
    
    printf("Chuckie Lucky\t\t\t复利\t\t利率:%.2f%%\n",
           COMPOUND_INTERSET * 100);
    printLine();
    printf("年\t投资额\t\t\t利息\t\t\t取款金额\t\t余额\n");
    printLine();
    do
    {
        year++;
        //利息 = 累计投资额 * 10%
        interest = invest * COMPOUND_INTERSET;
        printf("%d\t%12.4f\t%10.4f\t", year, invest, interest);
        //投资额 = 投资额+利息
        invest += interest;
        //如果足够扣减10万,则扣减10万,否则扣减余额
        if(invest - WITHDRAW_MONDY >= 0)
        {
            //取款金额
            printf("%6.0f\t", WITHDRAW_MONDY);
            //投资额 = 投资额+利息-取款金额
            invest -= WITHDRAW_MONDY;
        }
        else
        {
            //取款金额
            printf("%6.0f\t", invest);
            //投资额 = 投资额+利息-取款金额
            invest = 0;
        }
        printf("\t%11.4f\n",invest);
        
    }while(invest > 0);
    printLine();
    
    return 0;
}

void printLine(void)
{
    printf("------------------------------");
    printf("------------------------------\n");
}

程序输出结果:

习题18

Rabnud博士加入了一个社交圈。起初他有5个朋友。他注意到他的朋友数量以下面的方式增长。第1周少了1个朋友,剩下的朋友数量翻倍;第2周少了2个朋友,剩下的朋友数量翻倍。一般而言,第N周少了N个朋友,剩下的朋友数量翻倍。编写一个程序,计算并显示Rabnud博士每周的朋友数量。该程序一直运行,知道超过邓巴数(Dunbar's number)。邓巴数是粗略估算一个人在社交圈中有稳定关系的成员的最大值,该值大约是150

#include <stdio.h>

void printline(void);

int main(void)
{
    //起初朋友数
    unsigned int init = 5;
    //结余朋友数
    unsigned int sums = init;
    //周数
    unsigned short weeks = 1;
    //少了的人数
    unsigned short lost_friend = weeks;
    //余下人数
    unsigned short remain_friend = 0;
    //Dunbar's number
    const unsigned int DUNBARS_NUMBER = 150;
    
    printf("Rabnud 博士\n");
    printline();
    printf("第N周\t|起初值\t少了N个朋友\t余下朋友数\t余下朋友翻倍数\n");
    printline();
    do
    {
        //第N周
        printf("%4d\t", weeks);
        //起初值
        printf("|%4d\t", sums);
        //少了的人数
        lost_friend = weeks;
        //余下人数
        remain_friend = sums - lost_friend;
        //余下朋友翻倍数
        sums = remain_friend * 2;
        printf("%4d\t\t%4d\t\t%4d\n", lost_friend,
               remain_friend, sums);
        weeks++;
    }while(sums <= DUNBARS_NUMBER);
    printline();
    
    return 0;
}

void printline(void)
{
    printf("------------------");
    printf("------------------------------------\n");
}

程序输出结果:

​​​​​​​

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值