码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 《C Primer Plus》第12章复习题与编程练习


    《C Primer Plus》第12章复习题与编程练习

    • 复习题
      • 1. 哪些类别的变量可以成为它所在函数的局部变量?
      • 2. 哪些类别的变量在它所在程序的运行期一直存在?
      • 3. 哪些类别的变量可以被多个文件使用?哪些类别的变量仅限于在一个文件中使用?
      • 4. 块作用域变量具有什么链接属性?
      • 5. extern关键字有什么用途?
      • 6. 考虑下面两行代码,就输出的结果而言有何异同:
      • 7. 下面的变量对哪些函数可见?程序是否有误?
      • 8. 下面程序会打印什么?
      • 9. 假设文件的开始处有如下声明:
    • 编程练习
      • 1. 不使用全局变量,重写程序清单12.4
      • 2. 在美国,通常以英里/加仑来计算油耗;在欧洲,以升/100 公里来计算。下面是程序的一部分,提示用户选择计算模式(美制或公制),然后接收数据并计算油耗
      • 3. 重新设计编程练习2,要求只使用自动变量。该程序提供的用户界面不变,即提示用户输入模式等。但是,函数调用要作相应变化
      • 4. 在一个循环中编写并测试一个函数,该函数返回它被调用的次数
      • 5. 编写一个程序,生成100个1~10范围内的随机数,并以降序排列(可以把第11章的排序算法稍加改动,便可用于整数排序,这里仅对整数排序)
      • 6. 编写一个程序,生成1000个1~10范围内的随机数。不用保存或打印这些数字,仅打印每个数出现的次数。用 10 个不同的种子值运行,生成的数字出现的次数是否相同?可以使用本章自定义的函数或ANSI C的rand()和srand()函数,它们的格式相同。这是一个测试特定随机数生成器随机性的方法
      • 7. 编写一个程序,按照程序清单12.13输出示例后面讨论的内容,修改该程序。使其输出类似:
      • 8. 下面是程序的一部分:
      • 9. 编写一个符合以下描述的函数。首先,询问用户需要输入多少个单词。然后,接收用户输入的单词,并显示出来,使用malloc()并回答第1个问题(即要输入多少个单词),创建一个动态数组,该数组内含相应的指向char的指针(注意,由于数组的每个元素都是指向char的指针,所以用于储存malloc()返回值的指针应该是一个指向指针的指针,且它所指向的指针指向char)。在读取字符串时,该程序应该把单词读入一个临时的char数组,使用malloc()分配足够的存储空间来储存单词,并把地址存入该指针数组(该数组中每个元素都是指向 char 的指针)。然后,从临时数组中把单词拷贝到动态分配的存储空间中。因此,有一个字符指针数组,每个指针都指向一个对象,该对象的大小正好能容纳被储存的特定单词。下面是该程序的一个运行示例:

    复习题

    1. 哪些类别的变量可以成为它所在函数的局部变量?

    1. 自动存储类别
    2. 寄存器存储类别
    3. 静态、无链接存储类别

    2. 哪些类别的变量在它所在程序的运行期一直存在?

    1. 静态、无链接存储类别
    2. 静态、内部链接存储类别
    3. 静态、外部链接存储类别

    3. 哪些类别的变量可以被多个文件使用?哪些类别的变量仅限于在一个文件中使用?

    1. 静态、内部链接存储类别
    2. 静态、外部链接存储类别

    4. 块作用域变量具有什么链接属性?

    无链接

    5. extern关键字有什么用途?

    声明外部链接的静态变量,表明该变量或函数已经在别处定义了。

    6. 考虑下面两行代码,就输出的结果而言有何异同:

    int * p1 = (int *)malloc(100 * sizeof(int));
    int * p1 = (int *)calloc(100, sizeof(int));
    
    • 1
    • 2

    前者在分配时内存中存储元素的值是未定义的,后者中的每一个元素都设置为0。

    7. 下面的变量对哪些函数可见?程序是否有误?

    /* 文件 1 */ 
    int daisy;
    int main(void) 
    { 
        int lily; 
        ...; 
    } 
    int petal() 
    { 
        extern int daisy, lily; 
        ...; 
    }
    /* 文件 2 */ 
    extern int daisy; 
    static int lily; 
    int rose; 
    int stem() 
    { 
        int rose; 
        ...;
    } 
    void root() 
    {
        ...;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    1)
    文件1中daisy对main()和petal()可见,文件2中以extern声明的daisy才对stem()、root()可见
    文件1中main()中的lily仅对main()函数可见
    文件2中的lily,rose对文件2中的stem()和root()可见,其中stem()中声明的rose只对stem()可见
    2)
    文件1中lily的引用是错误的,不存在变量名为lily的外部链接变量

    8. 下面程序会打印什么?

    #include 
    char color = 'B';
    void first(void);
    void second(void);
    int main(void)
    {
        extern char color;
        printf("color in main() is %c\n", color);
        first();
        printf("color in main() is %c\n", color);
        second();
        printf("color in main() is %c\n", color);
        return 0;
    }
    void first(void)
    {
        char color;
        color = 'R';
        printf("color in first() is %c\n", color);
    }
     
    void second(void) 
    {
        color = 'G';
        printf("color in second() is %c\n", color);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    color in main() is B
    color in first() is R
    color in main() is B
    color in second() is G
    color in main() is G

    9. 假设文件的开始处有如下声明:

    static int plink;
    int value_ct(const int arr[], int value, int n);
    
    • 1
    • 2

    a.以上声明表明了程序员的什么意图?
    b.用const int value和const int n分别替换int value和int n,是否对主调程序的值加强保护。

    a.
    定义一个名为plink的内部链接的存储变量
    定义一个函数名为value_ct的函数,该函数第一个参数为int型的数组,且在函数执行过程中该数组内容不可改变,第二参数和第三个参数都是int型变量,该函数返回一个int型的值
    b.
    否,形参的值改变并不改变实参的值

    编程练习

    1. 不使用全局变量,重写程序清单12.4

    代码:

    #include 
    #include 
    void critic(int *u);
    int main(void)
    {
        int units;
        
        printf("How many pounds to a firkin of butter?\n");
        scanf("%d", &units);
        while (units != 56)
        {
            critic(&units);
        }
        printf("You must have looked it up!\n");
    
        system("pause");
        return 0;
    }
    void critic(int *u)
    {
        printf("No luck, my friend. Try again.\n");
        scanf("%d", u);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    2. 在美国,通常以英里/加仑来计算油耗;在欧洲,以升/100 公里来计算。下面是程序的一部分,提示用户选择计算模式(美制或公制),然后接收数据并计算油耗

    如果用户输入了不正确的模式,程序向用户给出提示消息并使用上一次输入的正确模式。请提供pe12-2a.h头文件和pe12-2a.c源文件。源代码文件应定义3个具有文件作用域、内部链接的变量。一个表示模式、一个表示距离、一个表示消耗的燃料。get_info()函数根据用户输入的模式提示用户输入相应数据,并将其储存到文件作用域变量中。show_info()函数根据设置的模式计算并显示油耗。可以假设用户输入的都是数值数据。

    代码:

    // pe12-2a.h
    #ifndef DRAFT_PE12_2A_H
    #define DRAFT_PE12_2A_H
    
    #include 
    
    static int mode;
    static double km, fc;
    
    void set_mode(int n);
    void get_info();
    void show_info();
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    // pe12-2a.c
    #include "pe12-2a.h"
    
    void set_mode(int n)
    {
        mode = n;
    }
    
    void get_info()
    {
        printf("Enter distance traveled in kilometers:");
        scanf("%lf", &km);
        printf("Enter fuel consumed in liters:");
        scanf("%lf", &fc);
    }
    
    void show_info()
    {
        if (mode)
        {
            printf("Fuel consumption is %.1lf miles per gallon.\n", km / fc);
        }
        else
        {
            printf("Fuel consumption is %.2lf liters per 100 km.\n", fc / km);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    3. 重新设计编程练习2,要求只使用自动变量。该程序提供的用户界面不变,即提示用户输入模式等。但是,函数调用要作相应变化

    代码:

    // pe12-2a.h
    #ifndef DRAFT_PE12_2A_H
    #define DRAFT_PE12_2A_H
    
    #include 
    
    void show_info(int mode);
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    // pe12-2a.c
    #include "pe12-2a.h"
    
    void show_info(int mode)
    {
        double km, fc;
    
        printf("Enter distance traveled in kilometers:");
        scanf("%lf", &km);
        printf("Enter fuel consumed in liters:");
        scanf("%lf", &fc);
        if (mode)
        {
            printf("Fuel consumption is %.1lf miles per gallon.\n", km / fc);
        }
        else
        {
            printf("Fuel consumption is %.2lf liters per 100 km.\n", fc / km);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    4. 在一个循环中编写并测试一个函数,该函数返回它被调用的次数

    代码:

    #include 
    #include 
    
    void func()
    {
        static int num = 0;
        printf("this function has ran %d times.\n", ++num);
    }
    
    int main(void)
    {
        int n = 0;
    
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
        {
            func();
        }
    
        system("pause");
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    5. 编写一个程序,生成100个1~10范围内的随机数,并以降序排列(可以把第11章的排序算法稍加改动,便可用于整数排序,这里仅对整数排序)

    代码:

    #include 
    #include 
    
    int cmpfunc(const void *a, const void *b)
    {
        return (*(int *)b - *(int *)a);
    }
    
    int main()
    {
        int value[100];
    
        for (int i = 0; i < 100; i++)
        {
            value[i] = rand() % 10 + 1;
        }
        qsort(value, 100, sizeof(int), cmpfunc);
        for (int i = 0; i < 100; i++)
        {
            printf("%d ", value[i]);
        }
        
        system("pause");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    6. 编写一个程序,生成1000个1~10范围内的随机数。不用保存或打印这些数字,仅打印每个数出现的次数。用 10 个不同的种子值运行,生成的数字出现的次数是否相同?可以使用本章自定义的函数或ANSI C的rand()和srand()函数,它们的格式相同。这是一个测试特定随机数生成器随机性的方法

    代码:

    #include 
    #include 
    #include 
    
    int main()
    {
        int n;
    
        for (int i = 0; i < 10; ++i)
        {
            n = 1000;
            srand(i);
            // srand(time(0));
            int *x = (int *)calloc(11, sizeof(int));
            while (n--)
            {
                x[rand() % 11 + 1]++;
            }
            for (int j = 1; j < 11; ++j)
            {
                printf("%d ", x[j]);
            }
            putchar('\n');
            // free(x);
        }
    
        system("pause");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    当把随机种子设置为srand(i)时,每次生成的数字出现的次数不同;

    在这里插入图片描述

    当把随机种子设置为srand(time(0))时,每次生成的数字出现的次数相同;

    在这里插入图片描述

    7. 编写一个程序,按照程序清单12.13输出示例后面讨论的内容,修改该程序。使其输出类似:

    Enter the number of sets; enter q to stop : 18
    How many sides and how many dice? 6 3
    Here are 18 sets of 3 6-sided throws.
    12 10 6 9 8 14 8 15 9 14 12 17 11 7 10 13 8 14
    How many sets? Enter q to stop: q
    
    • 1
    • 2
    • 3
    • 4
    • 5

    代码:

    // diceroll.h
    #ifndef DRAFT_DICEROLL_H
    #define DRAFT_DICEROLL_H
    
    extern int roll_count;
    int roll_n_dice(int dice, int sides);
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    // diceroll.c
    #include "diceroll.h"
    #include 
    #include           /* 提供库函数 rand()的原型 */
    int roll_count = 0;          /* 外部链接 */
    static int rollem(int sides) /* 该函数属于该文件私有 */
    {
        int roll;
        roll = rand() % sides + 1;
        ++roll_count; /* 计算函数调用次数 */
        return roll;
    }
    
    int roll_n_dice(int dice, int sides)
    {
        int d;
        int total = 0;
        if (sides < 2)
        {
            printf("Need at least 2 sides.\n");
            return -2;
        }
        if (dice < 1)
        {
            printf("Need at least 1 die.\n");
            return -1;
        }
        for (d = 0; d < dice; d++)
            total += rollem(sides);
        return total;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    // main.c
    #include 
    #include    /* 为库函数 srand() 提供原型 */
    #include      /* 为 time() 提供原型      */
    #include "diceroll.h" /* 为roll_n_dice()提供原型,为roll_count变量提供声明 */
    int main(void)
    {
        int dice, roll;
        int sides;
        int set;
    
        srand((unsigned int)time(0)); /* 随机种子 */
        printf("Enter the number of sets; enter q to stop :");
        if (scanf("%d", &set) != 1)
        {
            return 0;
        }
        printf("How many sides and how many dice?");
        while (scanf("%d %d", &sides, &dice) == 2 && sides > 0 && dice > 0)
        {
            printf("Here are %d sets of 3 6-sided throws.\n", set);
            for (int i = 0; i < set; ++i)
            {
                roll = roll_n_dice(dice, sides);
                printf("%d ", roll);
            }
            putchar('\n');
        }
        printf("The rollem() function was called %d times.\n", roll_count); /* 使用外部变量 */
        printf("GOOD FORTUNE TO YOU!\n");
    
        system("pause");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    8. 下面是程序的一部分:

    // pe12-8.c
    #include 
    int * make_array(int elem, int val); 
    void show_array(const int ar [], int n); 
    int main(void) 
    { 
        int * pa; 
        int size; 
        int value; 
        printf("Enter the number of elements: "); 
        while (scanf("%d", &size) == 1 && size > 0) 
        { 
            printf("Enter the initialization value: ");
            scanf("%d", &value); 
            pa = make_array(size, value); 
            if (pa) 
            { 
                show_array(pa, size); 
                free(pa); 
            } 
            printf("Enter the number of elements (<1 to quit): "); 
        } 
        printf("Done.\n"); 
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    提供make_array()和show_array()函数的定义,完成该程序。make_array()函数接受两个参数,第1个参数是int类型数组的元素个数,第2个参数是要赋给每个元素的值。该函数调用malloc()创建一个大小合适的数组,将其每个元素设置为指定的值,并返回一个指向该数组的指针。show_array()函数显示数组的内容,一行显示8个数。

    代码:

    int *make_array(int elem, int val)
    {
        int *p = (int *)malloc(elem * sizeof(int));
        for (int i = 0; i < elem; i++)
        {
            p[i] = val;
        }
        return p;
    }
    
    void show_array(const int ar[], int n)
    {
        for (int i = 0; i < n; i++)
        {
            printf("%d ", ar[i]);
            if ((i + 1) % 8 == 0)
            {
                printf("\n");
            }
        }
        printf("\n");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    9. 编写一个符合以下描述的函数。首先,询问用户需要输入多少个单词。然后,接收用户输入的单词,并显示出来,使用malloc()并回答第1个问题(即要输入多少个单词),创建一个动态数组,该数组内含相应的指向char的指针(注意,由于数组的每个元素都是指向char的指针,所以用于储存malloc()返回值的指针应该是一个指向指针的指针,且它所指向的指针指向char)。在读取字符串时,该程序应该把单词读入一个临时的char数组,使用malloc()分配足够的存储空间来储存单词,并把地址存入该指针数组(该数组中每个元素都是指向 char 的指针)。然后,从临时数组中把单词拷贝到动态分配的存储空间中。因此,有一个字符指针数组,每个指针都指向一个对象,该对象的大小正好能容纳被储存的特定单词。下面是该程序的一个运行示例:

    How many words do you wish to enter? 5
    Enter 5 words now: I enjoyed doing this exerise
    Here are your words:
    I
    enjoyed
    doing
    this
    exercise
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    代码:

    #include 
    #include 
    #include 
    
    int main(void)
    {
        int n;
    
        printf("How many words do you wish to enter? ");
        scanf("%d", &n);
        printf("Enter %d words now:\n", n);
        char **a = (char **)malloc(n * sizeof(char *));
        for (int i = 0; i < n; i++)
        {
            char b[100];
            scanf("%s", b);
            int n = strlen(b);
            char *str = (char *)malloc((n + 1) * sizeof(char));
            for (int j = 0; j < n; j++)
            {
                str[j] = b[j];
            }
            str[n] = '\0';
            a[i] = str;
        }
        printf("Here are your words:\n");
        for (int i = 0; i < n; i++)
        {
            printf("%s\n", a[i]);
        }
    
        system("pause");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    运行结果:

    在这里插入图片描述

  • 相关阅读:
    STC 51单片机56——摇摇棒
    MySQL告警“Connection attributes of length 570 were truncated“
    HTTP和HTTPS的区别、 HTTPS运行原理
    Java实现快速排序
    2022.11.8 固体物理
    JS 函数总结
    TCP_IP协议
    功能定义-后方碰撞预警
    羊大师提示,羊奶都有哪些惊人功效?
    【前端工程化】babel到底是个什么,了解babel的功能
  • 原文地址:https://blog.csdn.net/ProgramNovice/article/details/127776146
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号