《C語(yǔ)言入門(mén)經(jīng)典(第4版)》課后練習(xí)參考答案

第1章 C語(yǔ)言編程

練習(xí)1.1 編寫(xiě)一個(gè)程序,用兩個(gè)printf()語(yǔ)句分別輸出自己的名字和地址。

#include <stdio.h>

int main(void) {
    printf("姓名:小獅子\n");
    printf("地址:月亮之上\n");
    return 0;
}

練習(xí)1.2 將上一個(gè)練習(xí)修改成所有的輸出只用一個(gè)printf()語(yǔ)句。

#include <stdio.h>

int main(void) {
    printf("姓名:小獅子\n地址:月亮之上\n");
    return 0;
}

練習(xí)1.3 編寫(xiě)一個(gè)程序,輸出下列文本,格式如下所示:"It's freezing in here," he said coldly.

#include <stdio.h>

int main(void) {
    printf("\"It's freezing in here,\" he said coldly.\n");
    return 0;
}

第2章 編程初步

習(xí)題2.1 編寫(xiě)一個(gè)程序,提示用戶用英寸輸入一個(gè)距離,然后將該距離值輸出為碼、英尺和英寸的形式。

#include <stdio.h>

/*
 * 1碼=3英尺=36英寸
 */
int main()
{
    float len_inch = 0.0f;  // 英寸
    float len_foot = 0.0f;  // 英尺
    float len_yard = 0.0f;  // 碼
    
    // 提示用戶用英寸輸入一個(gè)距離
    printf("請(qǐng)用英寸輸入一個(gè)距離:");
    scanf("%f", &len_inch);
    
    // 計(jì)算英尺
    len_foot = len_inch / 12;
    
    // 計(jì)算碼
    len_yard = len_foot / 3;
    
    // 輸出計(jì)算后的結(jié)果
    printf("%.2f英寸 = %.2f英尺 = %.2f碼\n", len_inch, len_foot, len_yard);
    
    return 0;
}

習(xí)題2.2 編寫(xiě)一個(gè)程序,提示用戶用英尺和英寸輸入一個(gè)房間的長(zhǎng)和寬,然后計(jì)算并輸出面積,單位是平方碼,精度為小數(shù)點(diǎn)后兩位數(shù)。

#include <stdio.h>

int main()
{
    float length_in_foot = 0.0f;    // 房間的寬度 單位英尺
    float width_in_inch = 0.0f; // 房間的寬度 單位英寸
    float area_in_yard = 0.0f;  // 房間的面積 單位平方碼
    
    // 提示用戶輸入房間的長(zhǎng)度
    printf("請(qǐng)輸入房間的長(zhǎng)度(單位:foot):");
    scanf("%f", &length_in_foot);
    
    // 提示用戶輸入房間的寬度
    printf("請(qǐng)輸入房間的寬度(單位:inch):");
    scanf("%f", &width_in_inch);
    
    // 計(jì)算房間的面積 1碼=3英尺=36英寸
    area_in_yard = (length_in_foot / 3) * (width_in_inch / 36);
    
    // 輸出房間的面積
    printf("房間的面積是:%.2f平方碼。\n", area_in_yard);
    
    return 0;
}

習(xí)題2.3 一個(gè)產(chǎn)品有兩個(gè)版本:其一是標(biāo)準(zhǔn)版,價(jià)格是$3.5,其二是豪華版,價(jià)格是$5.5。編寫(xiě)一個(gè)程序,使用學(xué)到的知識(shí)提示用戶輸入產(chǎn)品的版本和數(shù)量,然后根據(jù)輸入的產(chǎn)品數(shù)量,計(jì)算并輸出價(jià)格。

#include <stdio.h>

int main()
{
    float price_of_normal = 3.5;    // 普通版單價(jià)
    float price_of_deluxe = 5.5f;   // 豪華版單價(jià)
    int number_of_normal = 0;    // 普通版的數(shù)量
    int number_of_deluxe = 0;   // 豪華版的數(shù)量
    float total_price = 0.0f;   // 總價(jià)
    
    // 提示用戶輸入產(chǎn)品的數(shù)量
    printf("請(qǐng)輸入普通版的數(shù)量:");
    scanf("%d", &number_of_normal);
    printf("請(qǐng)輸入豪華版的數(shù)量:");
    scanf("%d", &number_of_deluxe);
    
    // 計(jì)算總價(jià)
    total_price = number_of_normal * price_of_normal + number_of_deluxe + price_of_deluxe;
    
    // 輸出總價(jià)
    printf("總價(jià)為:$%.2f\n", total_price);
    
    return 0;
}

習(xí)題2.4 編寫(xiě)一個(gè)程序,提示用戶從鍵盤(pán)輸入一個(gè)星期的薪水(以美元為單位)和工作時(shí)數(shù),它們均為浮點(diǎn)數(shù),然后計(jì)算并輸出每個(gè)小時(shí)的平均時(shí)薪,輸出格式如下所示:

Your average hourly pay rate is 7 dollars and 54 cents.

#include <stdio.h>

int main()
{
    float salary = 0.0f;    // 一個(gè)星期的薪水(以美元為單位)
    float hours = 0.0f; // 工作時(shí)數(shù)
    float salary_per_hour = 0.0f;   // 每個(gè)小時(shí)的平均時(shí)薪
    
    // 提示用戶輸入一個(gè)星期的薪水
    printf("請(qǐng)輸入一個(gè)星期的薪水(以美元為單位):");
    scanf("%f", &salary);
    
    // 提示用戶輸入工作時(shí)數(shù)
    printf("請(qǐng)輸入工作時(shí)數(shù):");
    scanf("%f", &hours);
    
    // 計(jì)算每個(gè)小時(shí)的平均時(shí)薪
    salary_per_hour = salary / hours;
    
    // 輸出結(jié)果
    printf("Your average hourly pay rate is %d dollars and %d cents.\n", (int)salary_per_hour, (int)(salary_per_hour * 100) % 100);
    
    return 0;
}

第3章 條件判斷

習(xí)題3.1 編寫(xiě)一個(gè)程序,首先給用戶以下兩種選擇:

(1)將溫度從攝氏度轉(zhuǎn)換為華氏度。

(2)將溫度從華氏度轉(zhuǎn)換為攝氏度。

接著,程序提示用戶輸入溫度值,并輸出轉(zhuǎn)換后的數(shù)值。從攝氏度轉(zhuǎn)換為華氏度,可以乘以 1.8 再加上 32。從華氏度轉(zhuǎn)換為攝氏度,可以先減去 32 后,再乘以 5,除以 9。

#include <stdio.h>
#include <ctype.h>

int main()
{
    float temperature = 0.0f;   // 用戶輸入的溫度值
    char ch = '\0';
    float result = 0.0f;    // 轉(zhuǎn)換后的溫度值

    // 提示用戶都有哪種轉(zhuǎn)換方式
    printf("程序提供如下兩種轉(zhuǎn)換方式:\n");
    printf("    A. 將溫度從攝氏度轉(zhuǎn)換為華氏度\n    B. 將溫度從華氏度轉(zhuǎn)換為攝氏度\n");

    // 提示用戶輸入選擇的轉(zhuǎn)換方式
    printf("請(qǐng)選擇轉(zhuǎn)換方式(A or B):");
    scanf("%c", &ch);

    if (tolower(ch) == 'a')
    {
        printf("請(qǐng)輸入溫度值:");
        scanf("%f",  &temperature);
        result = temperature * 1.8 + 32;
        printf("%.2f攝氏度 = %.2f華氏度\n", temperature, result);
    }
    else if (tolower(ch) == 'b')
    {
        printf("請(qǐng)輸入溫度值:");
        scanf("%f", &temperature);
        result = (temperature - 32) * 5 / 9;
        printf("%.2f華氏度 = %.2f攝氏度\n", temperature, result);
    } 
    else
    {
        printf("選擇錯(cuò)誤\n");
    }

    return 0;
}

習(xí)題3.2 編寫(xiě)一個(gè)程序,提示用戶輸入3個(gè)整數(shù)值,分別代表月、日、年。例如用戶輸入了12、31、2003,程序就以31st December 2003 的格式輸出該日期。

必須在日期值的后面加上th、nd、st 和 rd。例如1st、2nd、3rd、4th、11th、12th、13th、14th、21st、22nd、23rd、24th。

#include <stdio.h>

int main()
{
    int year = 0;
    int month = 0;
    int day = 0;
    // 定義一個(gè)代表12個(gè)月份的枚舉類型,枚舉器值從1開(kāi)始
    enum Month { January = 1, February, March, April, May, June, July, August, September, October, November, December };    

    // 提示用戶輸入月、日、年
    printf("請(qǐng)輸入月、日、年:");
    scanf("%d%d%d", &month, &day, &year);

    // 輸出日
    if (day < 1 || day > 31)
    {
        printf("輸入日期有誤 ");
    } 
    else if (day % 10 == 1 && day != 11)
    {
        printf("%dst ", day);
    }
    else if (day % 10 == 2 && day != 12)
    {
        printf("%dnd ", day);
    }
    else if (day % 10 == 3 && day != 13)
    {
        printf("%drd ", day);
    }
    else 
    {
        printf("%dth ", day);
    }

    // 輸出月
    switch (month)
    {
    case January:
        printf("January ");
        break;
    case February:
        printf("February ");
        break;
    case March:
        printf("March ");
        break;
    case April:
        printf("April ");
        break;
    case May:
        printf("May ");
        break;
    case June:
        printf("June ");
        break;
    case July:
        printf("July ");
        break;
    case August:
        printf("August ");
        break;
    case September:
        printf("September ");
        break;
    case October:
        printf("October ");
        break;
    case November:
        printf("November ");
        break;
    case December:
        printf("December ");
        break;
    default:
        printf("輸入月份有誤 ");
        break;
    }

    // 輸出年
    printf("%d\n", year);

    return 0;
}

習(xí)題3.3 編寫(xiě)一個(gè)程序,根據(jù)從鍵盤(pán)輸入的一個(gè)數(shù)值,計(jì)算總價(jià)(單價(jià)是$5),數(shù)值超過(guò)30的折扣是10%,數(shù)值超過(guò)50的折扣是15%。

#include <stdio.h>

int main()
{
    float unit_price = 5.0f;    // 商品單價(jià)
    float discount = 0.0f;  // 商品折扣
    int number = 0; // 商品數(shù)量

    // 提示用戶輸入商品數(shù)量
    printf("請(qǐng)輸入商品數(shù)量:");
    scanf("%d", &number);

    // 計(jì)算折扣
    if (number <= 30)
    {
        discount = 0.0f;
    }
    else if (number <= 50)
    {
        discount = 0.1f;
    }
    else
    {
        discount = 0.15f;
    }

    // 輸出總價(jià)
    printf("商品的總價(jià)為:%.2f\n", number * unit_price * (1 - discount));

    return 0;
}

習(xí)題3.4 修改本章最后的計(jì)算器例子,讓用戶選擇輸入y或Y,以執(zhí)行另一個(gè)計(jì)算,輸入n或N就結(jié)束程序。(注意:這需要實(shí)用goto語(yǔ)句,下一章將介紹一個(gè)更好的方法。)

#include <stdio.h>

int main()
{
    double number1 = 0.0;
    double number2 = 0.0;
    char operation = 0;
    char choice = 0;

    begin:
    printf("Enter the caculation\n");
    scanf("%lf %c %lf", &number1, &operation, &number2);

    switch (operation)
    {
    case '+':
        printf("= %lf\n", number1 + number2);
        break;
    case '-':
        printf("= %lf\n", number1 - number2);
        break;
    case '*':
        printf("= %lf\n", number1 * number2);
        break;
    case '/':
        if (number2 == 0)
            printf("\n\n\aDivision by zero error!\n");
        else
            printf("= %lf\n", number1 / number2);
        break;
    case '%':
        if ((long)number1 == 0)
            printf("\n\n\aDivision by zero error!\n");
        else
            printf("= %ld\n", (long)number1 % (long)number2);
        break;
    default:
        printf("\n\n\aIllegal operation!\n");
        break;
    }

    printf("Do you want to continue? (y or n): ");
    scanf(" %c", &choice);  // 注意:%c 前面的空格不能去掉

    if (choice == 'y' || choice == 'Y')
        goto begin;

    return 0;
}

第4章 循環(huán)

習(xí)題4.1 編寫(xiě)一個(gè)程序,生成一個(gè)乘法表,其大小由用戶輸入來(lái)決定。例如,如果表的大小是4,該表就有4行4列。行和列標(biāo)記為1~4.表中的每一個(gè)單元格都包含行列之積,因此第三行第4列的單元格包含12。

#include <stdio.h>

int main()
{
    int num_row = 0;
    int num_col = 0;
    
    printf("請(qǐng)輸入行數(shù)和列數(shù):");
    scanf("%d%d", &num_row, &num_col);
    
    printf("    ");
    for (int i = 1; i <= num_col; i++)
    {
        printf("%3d ", i);
    }
    printf("\n");
    
    for (int i = 1; i <= num_row; i++)
    {
        printf("%-4d", i);
        for (int j = 1; j <= num_col; j++)
        {
            printf("%3d ", i * j);
        }
        printf("\n");
    }
    return 0;
}

習(xí)題4.2 編寫(xiě)一個(gè)程序,為0~127之間的字符碼輸出可打印的字符。輸出每個(gè)字符碼和它的符號(hào),這兩個(gè)字符占一行。列要對(duì)齊(提示:可以使用在ctype.h中聲明的isgraph()函數(shù),確定哪個(gè)字符是可以打印的)。

#include <stdio.h>
#include <ctype.h>

int main()
{
    for (int i = 0; i <= 127; i++)
    {
        if (isgraph(i))
        {
            printf("%d  %c\n", i, i);
        }
    }
    return 0;
}

習(xí)題4.3 擴(kuò)展上一題,給每個(gè)空白字符輸出對(duì)應(yīng)的名稱,例如newline,space,tab等。

// 本題略

習(xí)題4.4 使用嵌套循環(huán)輸出一個(gè)用星號(hào)繪制的盒子,與程序4.2類似,但是它的寬和高由用戶輸入。

#include <stdio.h>

int main()
{
    int height = 0;
    int width = 0;
    
    printf("請(qǐng)輸入盒子的寬和高:");
    scanf("%d%d", &width, &height);
    
    for (int i = 1; i <= height; i++)
    {
        for (int j = 1; j <= width; j++)
        {
            if (i == 1 || i == height)
            {
                printf("*");
            }
            else
            {
                if (j == 1 || j == width)
                {
                    printf("*");
                }
                else
                {
                    printf(" ");
                }
            }
        }
        printf("\n");
    }
    return 0;
}

習(xí)題4.5 修改程序4.7的猜謎游戲,在玩家猜錯(cuò)數(shù)字后,可以用一個(gè)選項(xiàng)讓玩家繼續(xù)玩下去,且想玩多久就玩多久。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>

int main()
{
    int chosen = 0;
    int guess = 0;
    int limit = 20;
    char another_game = 'Y';
    
    srand(time(NULL));
    chosen = 1 + rand() % limit;
    
    printf("\nThis is a guessing game."
           "\nI have chosen a number between 1 and 20 which you must guess.\n");
    
    do
    {
        printf("\nEnter a guess: ");
        scanf("%d", &guess);
        
        if (guess == chosen)
        {
            printf("\nYou guessed it!\n");
            return 0;
        }
        
        if (guess < 1 || guess > 20)
        {
            printf("\nI said between 1 and 20.\n");
        }
        else
        {
            printf("\nSorry. %d is wrong.\n", guess);
        }
        
        printf("\nDo you want to play again(y/n)? ");
        scanf(" %c", &another_game);
    }while(toupper(another_game) == 'Y');
    return 0;
}

第5章 數(shù)組

習(xí)題5.1 編寫(xiě)一個(gè)程序,從鍵盤(pán)上讀入5個(gè)double類型的值,將它們存儲(chǔ)到一個(gè)數(shù)組中。計(jì)算每個(gè)值的倒數(shù)(值x的倒數(shù)是 1.0/x),將結(jié)果存儲(chǔ)到另一個(gè)數(shù)組中。輸出這些倒數(shù),并計(jì)算和輸出倒數(shù)的總和。

#include <stdio.h>

int main()
{
    double original[5] = { 0.0 };
    double result[5] = { 0.0 };
    double sum = 0.0;

    for (int i = 0; i < 5; i++)
    {
        printf("%d -> ", i + 1);
        scanf("%lf", &original[i]);
    }

    for (int i = 0; i < 5; i++)
    {
        result[i] = 1.0 / original[i];
    }

    for (int i = 0; i < 5; i++)
    {
        printf("result[%d] = %lf\n", i, result[i]);
        sum += result[i];
    }

    printf("sum = %lf\n", sum);

    return 0;
}

習(xí)題5.2 定義一個(gè)數(shù)組 data,它包含 100 個(gè) double 類型的元素。編寫(xiě)一個(gè)循環(huán),將以下的數(shù)值序列存儲(chǔ)到數(shù)組的對(duì)應(yīng)元素中:

1/(2*3*4) 1/(4*5*6) 1/(6*7*8) ... up to 1/(200*201*202)

編寫(xiě)另一個(gè)循環(huán),計(jì)算:

data[0] - data[1] + data[2] - data[3] + ... - data[99]

將這個(gè)結(jié)果乘以 4.0,加 3.0,輸出最后的結(jié)果。

#include <stdio.h>

int main()
{
    double data[100] = { 0.0 };
    double sum = 0.0;
    double result = 0.0;
    
    for (int i = 1; i <= 100; i++)
    {
        data[i - 1] = 1.0 / ((2 * i) * (2 * i + 1)*(2 * i + 2));
    }
    
    for (int i = 0; i < 100; i++)
    {
        sum += (i % 2 ? -1 : 1) * data[i];
    }
    
    result = sum * 4.0 + 3.0;
    
    printf("計(jì)算結(jié)果為:%lf\n", result);
    return 0;
}

習(xí)題5.3 編寫(xiě)一個(gè)程序,從鍵盤(pán)上讀入 5 個(gè)值,將它們存儲(chǔ)到一個(gè) float 類型的數(shù)組 amounts 中。創(chuàng)建兩個(gè)包含 5 個(gè) long 元素的數(shù)組 dollars 和 cents。將 amounts 數(shù)組元素的整數(shù)部分存儲(chǔ)到 dollars 的對(duì)應(yīng)元素中,amounts 數(shù)組元素的小數(shù)部分存儲(chǔ)到 cents 中,只保存兩位數(shù)字(例如:amounts[1] 的值是 2.75,則把 2 存儲(chǔ)到 dollars[1] 中,把 75 存儲(chǔ) cents[1]中)。以貨幣格式輸出這兩個(gè) long 類型數(shù)組的值(如$2.75)。

#include <stdio.h>

int main()
{
    float amounts[5] = {0.0f};
    long dollars[5] = {0L};
    long cents[5] = {0L};
    
    for (int i = 0; i < 5; i++)
    {
        printf("%d -> ", i + 1);
        scanf("%f", &amounts[i]);
    }
    
    for (int i = 0; i < 5; i++)
    {
        dollars[i] = (long) amounts[i];
        cents[i] = (long)(amounts[i] * 100) % 100;
    }
    
    for (int i = 0; i < 5; i++)
    {
        printf("$%ld.%ld\n", dollars[i], cents[i]);
    }
    return 0;
}

習(xí)題5.4 定義一個(gè) double 類型的二維數(shù)組 data[11][5]。用 2.0~3.0 的值初始化第一列元素(每步增加 0.1)。如果行中的第一個(gè)元素值是 x,改行的其它元素值分別是 1/x,x2,x3 和 x?。輸出數(shù)組中的值,每一行放在一行上,每一列要有標(biāo)題。

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

int main()
{
    double data[11][5] = {0.0};
    
    for (int i = 0; i < 11; i++)
    {
        data[i][0] = (1 + 0.1 * i);
    }
    
    for (int i = 0; i < 11; i++)
    {
        data[i][1] = 1 / data[i][0];
        for (int j = 2; j < 5; j++)
        {
            data[i][j] = pow(data[i][0], i);
        }
    }
    
    printf("        ");
    for (int i = 0; i < 5; i++)
    {
        printf("   %02d   ", i + 1);
    }
    printf("\n");
    
    for (int i = 0; i < 11; i++)
    {
        printf("   %02d   ", i + 1);
        for (int j = 0; j < 5; j++)
        {
            printf(" %6.2lf ", data[i][j]);
        }
        printf("\n");
    }
    
    return 0;
}

習(xí)題5.5 編寫(xiě)一個(gè)程序,計(jì)算任意多個(gè)班級(jí)的學(xué)生的平均分。該程序應(yīng)讀取所有班級(jí)里學(xué)生的所有成績(jī),再計(jì)算平均值。給每個(gè)班級(jí)輸出每個(gè)學(xué)生的平均分,以及班級(jí)的平均分。

#include <stdio.h>
#define CLASS_NUM 2
#define STUDENT_NUM 2
#define COURSE_NUM 2

int main()
{
    int score[CLASS_NUM][STUDENT_NUM][COURSE_NUM] = {0};
    int average_class = 0;
    int average_student = 0;
    
    for (int i = 0; i < CLASS_NUM; i++)
    {
        for (int j = 0; j < STUDENT_NUM; j++)
        {
            for (int k = 0; k < COURSE_NUM; k++)
            {
                printf("Class %02d  Student %02d  Course %02d  -> ", i, j, k);
                scanf("%d", &score[i][j][k]);
            }
        }
    }
    
    for (int i = 0; i < CLASS_NUM; i++)
    {
        average_class = 0;
        for (int j = 0; j < STUDENT_NUM; j++)
        {
            average_student = 0;
            for (int k = 0; k < COURSE_NUM; k++)
            {
                average_class += score[i][j][k];
                average_student += score[i][j][k];
            }
            printf("Class %02d Student %02d 的平均分是 %.2f\n", i, j, average_student * 1.0 / COURSE_NUM);
        }
        printf("Class %02d 的平均分是 %.2f\n", i, average_class * 1.0 / STUDENT_NUM / COURSE_NUM);
    }
    return 0;
}

第6章 字符串和文本的應(yīng)用

習(xí)題6.1 編寫(xiě)一個(gè)程序,從鍵盤(pán)上讀入一個(gè)小于1000的正整數(shù),然后創(chuàng)建并輸出一個(gè)字符串,說(shuō)明該整數(shù)的值。例如,輸入941,程序產(chǎn)生的字符串是“Nine hundred and forty one”。

#include <stdio.h>

void one2nineteen(int n)
{
    switch (n)
    {
        case 1:
            printf("one");
            break;
        case 2:
            printf("two");
            break;
        case 3:
            printf("three");
            break;
        case 4:
            printf("four");
            break;
        case 5:
            printf("five");
            break;
        case 6:
            printf("six");
            break;
        case 7:
            printf("seven");
            break;
        case 8:
            printf("eight");
            break;
        case 9:
            printf("nine");
            break;
        case 10:
            printf("ten");
            break;
        case 11:
            printf("eleven");
            break;
        case 12:
            printf("twelve");
            break;
        case 13:
            printf("thirteen");
            break;
        case 14:
            printf("fourteen");
            break;
        case 15:
            printf("fifteen");
            break;
        case 16:
            printf("sixteen");
            break;
        case 17:
            printf("seventeen");
            break;
        case 18:
            printf("eighteen");
            break;
        case 19:
            printf("nineteen");
            break;
            
        default:
            printf("one2nineteen操作失敗");
            break;
    }
}

void fun(int n)
{
    switch (n) {
        case 20:
            printf("twenty");
            break;
        case 30:
            printf("thirty");
            break;
        case 40:
            printf("fourty");
            break;
        case 50:
            printf("fifty");
            break;
        case 60:
            printf("sixty");
            break;
        case 70:
            printf("seventy");
            break;
        case 80:
            printf("eighty");
            break;
        case 90:
            printf("ninety");
            break;
        default:
            printf("fun執(zhí)行出錯(cuò)");
            break;
    }
}

void fun2(int n)
{
    if (n < 20)
    {
        one2nineteen(n);
    }
    else if (n < 100)
    {
        if (n % 10 == 0)
        {
            fun(n);
        }
        else
        {
            fun(n - n % 10);
            printf("-");
            one2nineteen(n % 10);
        }
    }
}

void int2str(int n)
{
    if (n < 100)
    {
        fun2(n);
    }
    else if (n < 1000)
    {
        if (n % 100 == 0)
        {
            one2nineteen(n / 100);
            printf(" hundred");
        }
        else
        {
            one2nineteen(n / 100);
            printf(" hundred and ");
            fun2(n % 100);
        }
    }
}

int main()
{
    for (int i = 1; i < 1000; i++)
    {
        printf("%3d -> ", i);
        int2str(i);
        printf("\n");
    }
    return 0;
}

習(xí)題6.2 編寫(xiě)一個(gè)程序,輸入一系列單詞,單詞之間以逗號(hào)分割,然后提取這些單詞,并將它們分行輸出,刪除頭尾的空格。例如,如果輸入是

John , Jack , Jill

輸出將是:

John

Jack

Jill

#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>

int main()
{
    char sequence[100] = { 0 };
    bool first = true;
    
    printf("請(qǐng)輸入一系列單詞,單詞之間以逗號(hào)分隔:\n");
    if (fgets(sequence, sizeof(sequence), stdin) == NULL)
    {
        printf("輸入過(guò)程出錯(cuò)\n");
        return 1;
    }
    else
    {
        for (int i = 0; i < 100 && sequence[i] != '\0'; i++)
        {
            if (isalpha(sequence[i])) {
                first = true;
                printf("%c", sequence[i]);
            }
            else
            {
                if (first)
                {
                    first = false;
                    printf("\n");
                }
            }
        }
        printf("\n");
    }
    return 0;
}

習(xí)題6.3 編寫(xiě)一個(gè)程序,從一組至少有5個(gè)字符串的數(shù)組里,輸出任意挑選的一個(gè)字符串。

#include <stdio.h>

int main()
{
    char arr[][50] = {
        "Hello",
        "Hello World",
        "Hello World, Hello World!"
    };
    
    printf("%s\n", arr[2]);
    return 0;
}

習(xí)題6.4 回文是正讀反讀均相同的句子,忽略空白和標(biāo)點(diǎn)符號(hào)。例如,“Madam, I'm Adam”和“Are we no drawn onward, we few? Drawn onward to new era?”都是回文。編寫(xiě)一個(gè)程序,確定從鍵盤(pán)輸入的字符串是否是回文。

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

int main()
{
    char sequence[100] = { 0 };
    unsigned long head = 0;
    unsigned long last = 0;
    bool flag = true;
    
    printf("請(qǐng)輸入一個(gè)字符串:\n");
    if (gets(sequence) == NULL)
    {
        printf("輸入過(guò)程出錯(cuò)\n");
        return 1;
    }
    else
    {
        last = strlen(sequence);
        
        for (; head < last; )
        {
            for (;!isalpha(sequence[head]);)
            {
                head++;
            }
            
            for (; !isalpha(sequence[last]);)
            {
                last--;
            }
            
            if (toupper(sequence[head]) == toupper(sequence[last]))
            {
                head++;
                last--;
            }
            else
            {
                flag = false;
                break;
            }
        }
        
        if (flag)
        {
            printf("是回文\n");
        }
        else
        {
            printf("不是回文\n");
        }
    }
    return 0;
}

第7章 指針

習(xí)題7.1 編寫(xiě)一個(gè)程序,計(jì)算從鍵盤(pán)輸入的任意個(gè)浮點(diǎn)數(shù)的平均值。將所有的數(shù)存儲(chǔ)到動(dòng)態(tài)分配的內(nèi)存中,之后計(jì)算并顯示平均值。用戶不需要事先指定要輸入多少個(gè)數(shù)。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    float number = 0.0f;
    float *pNumber = NULL;
    int count = 0;
    float sum = 0.0f;

    pNumber = (float *)malloc(sizeof(float));
    if (pNumber == NULL)
    {
        printf("內(nèi)存分配失敗\n");
        return 1;
    }

    do
    {
        scanf("%f", &number);
        count++;
        pNumber = realloc(pNumber, count * sizeof(float));

        *(pNumber + count - 1) = number;
    } while(number != 0.0f);

    for (int i = 0; i < count - 1; i++)
    {
        sum += *(pNumber + i);
    }

    printf("平均值是 %f\n", sum / (count - 1));

    free(pNumber);
    return 0;
}

習(xí)題7.2 編寫(xiě)一個(gè)程序,從鍵盤(pán)讀入任意個(gè)諺語(yǔ),并將它們存儲(chǔ)到執(zhí)行期間分配的內(nèi)存中。然后,將它們以字長(zhǎng)順序由短到長(zhǎng)地輸出。

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

int main()
{
    char **pStr = NULL;
    char *pBuffer = NULL;
    int count = 0;

    pStr = malloc(sizeof(char *));

    do
    {
        pBuffer = malloc(100 * sizeof(char));
        gets(pBuffer);
        count++;
        pStr = realloc(pStr, count * sizeof(char *));
        *(pStr + count - 1) = pBuffer;
    }while(strlen(pBuffer) != 0);

    for (int i = 0; i < count - 2; i++)
    {
        for (int j = 0; j < count - 2 - i; j++)
        {
            if (strlen(*(pStr + j)) > strlen(*(pStr + j + 1)))
            {
                pBuffer = *(pStr + j);
                *(pStr + j) = *(pStr + j + 1);
                *(pStr + j + 1) = pBuffer;
            }
        }
    }

    for (int i = 0; i < count - 1; i++)
    {
        printf("%s\n", *(pStr + i));
    }
    return 0;
}

習(xí)題7.3 編寫(xiě)一個(gè)程序,從鍵盤(pán)讀入一個(gè)字符串,顯示刪除了所有空格和標(biāo)點(diǎn)符號(hào)的字符串。所有的操作都使用指針完成。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main()
{
    char *pStr = NULL;

    pStr = malloc(100*sizeof(char));

    gets(pStr);

    while(*pStr)
    {
        if (isalpha(*pStr))
        {
            putchar(*pStr);
        }
        pStr++;
    }

    putchar('\n');

    return 0;
}

習(xí)題7.4 編寫(xiě)一個(gè)程序,讀入任意天數(shù)的浮點(diǎn)溫度記錄值,每天有6個(gè)記錄。溫度記錄存儲(chǔ)在動(dòng)態(tài)分配內(nèi)存的數(shù)組中,數(shù)組的大小剛好等于輸入的溫度數(shù)。計(jì)算出每天的平均溫度,然后輸出每天的記錄,在單獨(dú)一行上輸出平均值,該平均值精確到小數(shù)點(diǎn)后一位。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    float **pTemp = NULL;
    float sum = 0.0f;
    int count = 0;
    
    pTemp = malloc(sizeof(float));
    
    do
    {
        count++;
        pTemp = realloc(pTemp, count * sizeof(float *));
        *(pTemp + count - 1) = malloc(6 * sizeof(float));
        
        printf("Day %d :\n", count);
        for (int i = 0; i < 6; i++)
        {
            printf("%d -> ", i + 1);
            scanf("%f", (*(pTemp + count - 1) + i));
        }
    }while(**(pTemp + count - 1) != 0.0f);
    
    for (int i = 0; i < count - 1; i++)
    {
        printf("Day %d :\n", i + 1);
        sum = 0;
        for (int j = 0; j < 6; j++)
        {
            sum += *(*(pTemp+i) + j);
            printf("%d -> %f\n", j + 1, *(*(pTemp+i) + j));
        }
        printf("average = %.1f\n", sum / 6);
    }
    return 0;
}

第8章 程序的結(jié)構(gòu)

習(xí)題8.1 定義一個(gè)函數(shù),給函數(shù)傳送任意多個(gè)浮點(diǎn)數(shù),計(jì)算出這些數(shù)的平均值。從鍵盤(pán)輸入任意個(gè)值,并輸出平均值,以說(shuō)明這個(gè)函數(shù)的執(zhí)行過(guò)程。

#include <stdio.h>
#include <stdlib.h>

float average(float *, int);

int main()
{
    float *pNum = NULL;
    int count = 0;
    pNum = malloc(count * sizeof(float));

    do
    {
        count++;
        pNum = realloc(pNum, count * sizeof(float));
        scanf("%f", pNum + count - 1);
    } while(*(pNum + count - 1) != 0.0f);

    printf("average = %f\n", average(pNum, count - 1));

    return 0;
}

float average(float *pNum, int count)
{
    float sum = 0.0f;
    for (int i = 0; i < count; i++)
    {
        sum += *(pNum + i);
    }
    return sum / count;
}

習(xí)題8.2 定義一個(gè)函數(shù),返回其整數(shù)變?cè)淖址硎?。例如,如果這個(gè)變?cè)?5,函數(shù)就返回"25"。如果變?cè)?98,函數(shù)就返回"-98"。用適當(dāng)?shù)膍ain()版本說(shuō)明函數(shù)的執(zhí)行過(guò)程。

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

char *intToString(int);

int main()
{
    printf("%s\n", intToString(-32768));
    return 0;
}

char *intToString(int number)
{
    char *pStr = malloc(7 * sizeof(char));
    int var = 10000;
    int weishu = 5;
    int count = 0;
    if (number < 0)
    {
        *(pStr + 0) = '-';
        count = 1;
        number = -number;
    }

    while (number / var == 0) {
        weishu--;
        var /= 10;
    }

    for (; count < 7; count++)
    {
        *(pStr + count) = '0' + number / (int)(pow(10, weishu - 1));
        number %= (int)(pow(10, weishu - 1));
        weishu--;
        if (weishu <= 0) {
            break;
        }
    }
    *(pStr + count + 1) = '\0';

    return pStr;
}

習(xí)題8.3 擴(kuò)展為上一題定義的函數(shù),使函數(shù)接受第二個(gè)變?cè)?,以指定結(jié)果的字段寬度,使返回的字符串表示右對(duì)齊。例如,如果第一個(gè)變?cè)闹凳?98,字段寬度變?cè)?,返回的字符串就應(yīng)該是" -98"。用適當(dāng)?shù)膍ain()版本說(shuō)明函數(shù)的執(zhí)行過(guò)程。

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

char *intToString(int, int);

int main()
{
    printf("%s\n", intToString(-98, 5));
    return 0;
}

char *intToString(int number, int width)
{
    char *pStr = malloc(7 * sizeof(char));
    int var = 10000;
    int weishu = 5;
    int count = 0;
    int len = 0;
    if (number < 0)
    {
        *(pStr + 0) = '-';
        count = 1;
        number = -number;
    }

    while (number / var == 0) {
        weishu--;
        var /= 10;
    }

    for (; count < 7; count++)
    {
        *(pStr + count) = '0' + number / (int)(pow(10, weishu - 1));
        number %= (int)(pow(10, weishu - 1));
        weishu--;
        if (weishu <= 0) {
            break;
        }
    }
    *(pStr + count + 1) = '\0';

    len = (int)strlen(pStr);
    if (len < width)
    {
        pStr = realloc(pStr, (width + 1) * sizeof(char));
        *(pStr + width) = '\0';
        int j = width - 1;
        for (int i = len; i > 0; i--, j--)
        {
            *(pStr + j) = *(pStr + i - 1);
        }
        for (;j >= 0; j--)
        {
            *(pStr + j) = ' ';
        }
    }

    return pStr;
}

習(xí)題8.4 定義一個(gè)函數(shù),其參數(shù)是一個(gè)字符串,返回該字符串中的單詞數(shù)(單詞以空格或標(biāo)點(diǎn)符號(hào)來(lái)分隔。假設(shè)字符串不包含單雙引號(hào),也就是數(shù)沒(méi)有像isn't這樣的單詞)。定義第二個(gè)函數(shù),它的第一個(gè)參數(shù)是一個(gè)字符串,第二個(gè)參數(shù)是一個(gè)數(shù)組,該函數(shù)將第一個(gè)字符串變?cè)指舫蓡卧~,把這些單詞存儲(chǔ)在第二個(gè)數(shù)組變?cè)?,最后返回存?chǔ)在數(shù)組中的單詞。定義第三個(gè)函數(shù),其參數(shù)是一個(gè)字符串,返回該字符串中的字母數(shù)。使用這些函數(shù)實(shí)現(xiàn)一個(gè)程序,從鍵盤(pán)讀入含有文本的字符串,輸出文本中的所有單詞,輸出順序是按照單詞中的字母數(shù),由短到長(zhǎng)。

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>

int wordCount(const char *);
void stringToArray(char *, char **);
int alphaCount(char *);

int main()
{
    char buffer[100] = "";
    char *pStr = buffer;
    char **pWord = NULL;
    char *pTemp = NULL;
    int words = 0;
    pWord = malloc(20 * sizeof(char *));
    gets(buffer);
    words = wordCount(pStr);
    stringToArray(pStr, pWord);

    for (int i = 0; i < words - 1; i++)
    {
        for (int j = 0; j < words - 1 - i; j++)
        {
            if (strlen(*(pWord + j)) > strlen(*(pWord + j + 1)))
            {
                pTemp = *(pWord + j);
                *(pWord + j) = *(pWord + j + 1);
                *(pWord + j + 1) = pTemp;
            }
        }
    }

    for (int i = 0; i < words; i++)
    {
        printf("%s\n", *(pWord + i));
    }

    return 0;
}

int wordCount(const char *pStr)
{
    int count = 0;
    bool isFirst = true;
    while (*pStr) {
        if (isalpha(*pStr)) {
            if (isFirst) {
                isFirst = false;
                count++;
            }
        }
        else
        {
            isFirst = true;
        }
        pStr++;
    }
    return count;
}

void stringToArray(char *pStr, char **pWord)
{
    char *pBuffer = malloc(20 * sizeof(char));
    int wordCount = 0;
    int i = 0;

    while (*pStr) {
        if (isalpha(*pStr))
        {
            while (isalpha(*pStr)) {
                *(pBuffer + i) = *pStr;
                i++;
                pStr++;
            }
            *(pBuffer + i) = '\0';
            *(pWord + wordCount) = pBuffer;
            wordCount++;
            pBuffer = malloc(20 * sizeof(char));
            i = 0;
        }
        else
        {
            pStr++;
        }
    }
}

int alphaCount(char *pStr)
{
    int count = 0;
    while (*pStr++) {
        count++;
    }
    return count;
}

第9章 函數(shù)再探

習(xí)題9.1 函數(shù)原型:

double power(doulbe x, int n);

會(huì)計(jì)算并返回xn。因此power(5.0, 4)會(huì)計(jì)算5.0*5.0*5.0*5.0,它的結(jié)果是625.0。將power()函數(shù)實(shí)現(xiàn)為遞歸函數(shù),再用適當(dāng)?shù)膍ain版本演示它的操作。

#include <stdio.h>

double power(double, int);

int main()
{
    printf("power(5.0, 4) = %lf\n", power(5.0, 4));
    return 0;
}

double power(double x, int n)
{
    if (n == 1)
    {
        return x;
    }
    else
    {
        return x * power(x, n - 1);
    }
}

習(xí)題9.2 函數(shù)原型:

double add(double a, double b); // returns a + b
double subtract(double a, double b);  // returns a - b
double multiply(double a, double b);  // returns a * b
double array_op(double array[], int size, double (\*pfun) (double, double));

array_op()函數(shù)的參數(shù)是:要運(yùn)算的數(shù)組、數(shù)組元素?cái)?shù)目以及一個(gè)函數(shù)指針,該函數(shù)指針指向的函數(shù)定義了在連續(xù)幾個(gè)元素上進(jìn)行的操作。在實(shí)現(xiàn)array_op()函數(shù)時(shí),將subtract()函數(shù)傳送為第三個(gè)參數(shù),subtract()函數(shù)會(huì)用交替符號(hào)組合這些元素。因此,對(duì)于有4個(gè)元素x1、x2、x3、x4的數(shù)組,subtract()函數(shù)會(huì)計(jì)算x1-x2+x3-x4的值。

用適當(dāng)?shù)膍ain()版本演示這些函數(shù)的運(yùn)作。

#include <stdio.h>

double add(double, double);
double subtract(double, double);
double multiply(double, double);
double array_op(double[], int, double (*) (double, double));

int main()
{
    double array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    printf("array_op() = %lf\n", array_op(array, 5, subtract));
    return 0;
}

double add(double a, double b)
{
    return a + b;
}

double subtract(double a, double b)
{
    return a - b;
}

double multiply(double a, double b)
{
    return a * b;
}

double array_op(double array[], int size, double (*pfun) (double, double))
{
    double sum = 0.0;
    for (int i = 0; i < size / 2; i++)
    {
        sum += subtract(array[i * 2], array[i * 2 + 1]);
    }
    if (size % 2 != 0) {
        sum += array[size - 1];
    }
    return sum;
}

習(xí)題9.3 定義一個(gè)函數(shù),它的參數(shù)是字符串?dāng)?shù)組指針,返回一個(gè)將所有字符串合并起來(lái)的字符串指針,每個(gè)字符串都用換行符來(lái)終止。如果輸入數(shù)組中的原字符串將換行符作為最后一個(gè)字符,函數(shù)就不能給字符串添加另一個(gè)換行符。編寫(xiě)一個(gè)程序,從鍵盤(pán)讀入幾個(gè)字符串,用這個(gè)函數(shù)輸出合并后的字符串。

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

#define ARR_LEN 5
#define BUF_LEN 100

char *custom_concat(char *[]);

int main()
{
    char *pStr[ARR_LEN] = { NULL };
    for (int i = 0; i < ARR_LEN; i++)
    {
        pStr[i] = malloc(BUF_LEN * sizeof(char));
        gets(pStr[i]);
    }

    printf("%s\n", custom_concat(pStr));
    return 0;
}

char *custom_concat(char *pStr[])
{
    char *pResult = NULL;
    char *pTemp = NULL;
    int totalLen = 0;
    for (int i = 0; i < ARR_LEN; i++)
    {
        totalLen += strlen(pStr[i]);
    }
    pResult = malloc((totalLen + 1) * sizeof(char));
    pTemp = pResult;
    for (int i = 0; i < ARR_LEN; i++)
    {
        strncpy(pTemp, pStr[i], strlen(pStr[i]));
        pTemp += strlen(pStr[i]);
    }

    return pResult;
}

習(xí)題9.4 一個(gè)函數(shù)的原型是:

char *to_string(int count, double first, ...);

這個(gè)函數(shù)返回一個(gè)字符串,這個(gè)字符串含有第二及其后參數(shù)的字符串表示,每個(gè)參數(shù)都有兩位小數(shù),參數(shù)間用逗號(hào)隔開(kāi)。第一個(gè)參數(shù)是從第二個(gè)參數(shù)算起的參數(shù)個(gè)數(shù)。編寫(xiě)一個(gè)main()函數(shù),演示這個(gè)函數(shù)的運(yùn)作。

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

char *to_string(int , double, ...);

int main()
{
    printf("%s\n", to_string(4, 1.0, 2.0, 3.0, 4.0));
    return 0;
}

char *to_string(int count, double first, ...)
{
    char *pStr = malloc(100 * sizeof(char));
    char buffer[100] = "";
    va_list parg;

    va_start(parg, first);
    sprintf(buffer, "%.2f", first);
    strcat(pStr, buffer);

    for (int i = 1; i < count; i++) {
        sprintf(buffer, ", %.2f", va_arg(parg, double));
        strcat(pStr, buffer);
    }

    va_end(parg);
    return pStr;
}

第10章 基本輸入輸出操作

習(xí)題10.1 編寫(xiě)一個(gè)程序,讀入、存儲(chǔ)以及輸出下列5種類型的字符串,每個(gè)字符串占一行,字符串間不能有空格。

  • 類型1:一串小寫(xiě)字母,后跟一個(gè)數(shù)字(如 number1)
  • 類型2:兩個(gè)單詞,每個(gè)單詞的第一個(gè)字母大寫(xiě),單詞間用-分隔(如Seven-Up)
  • 類型3:小數(shù)(如7.35)
  • 類型4:一串大小寫(xiě)字母以及空格(如Oliver Hardy)
  • 類型5:一串除了空格及數(shù)字外的任何字符(如floating-point)

以下是這5種輸入類型的例子,要分開(kāi)讀入這些字符串:

baby1on5Jhon-Boy3.14159Stan Laurel'Winner!'

#include <stdio.h>

int main()
{
    char str[5][100] = {""};
    for (int i = 0; i < 5; i++)
    {
        printf("%d -> ", i + 1);
        gets(str[i]);
    }

    for (int i = 0;i < 5; i++)
    {
        printf("%s", str[i]);
    }
    printf("\n");
    return 0;
}

習(xí)題10.2 編寫(xiě)一個(gè)程序,讀入以下數(shù)值,并輸出它們的和:

$3.50, $ 0.75, %9.95, %2. 50

#include <stdio.h>

int main()
{
    float number[4] = { 0.0f };
    float sum = 0.0f;
    char str[100] = "";
    int i = 0;
    for ( ; i < 99; )
    {
        str[i] = getchar();
        if (('0' <= str[i] && str[i] <= '9') || str[i] == '.')
        {
            i++;
        }
        else if (str[i] == '\n')
        {
            break;
        }
    }
    str[i] = '\0';

    sscanf(str, "%4f%4f%4f%4f", &number[0], &number[1], &number[2], &number[3]);

    for (int i = 0;i < 4; i++)
    {
        sum += number[i];
    }

    printf("average = %.2f\n", sum / 4);
    return 0;
}

習(xí)題10.3 定義一個(gè)函數(shù),其參數(shù)是一個(gè)double類型的數(shù)組,輸出該數(shù)組和數(shù)組中的元素個(gè)數(shù)。這個(gè)函數(shù)的原型如下:

void show(double array[], int array_size, int field_width);

輸出的值5個(gè)一行,每個(gè)值有兩位小數(shù),字符寬度是12。在程序中使用這個(gè)函數(shù)輸出從1.5到4.5的值,每次增加0.3(如:1.5、1.8、2.1、...、4.5)。

#include <stdio.h>

void show(double[], int, int);

int main()
{
    double array[] = {1.5, 1.8, 2.1, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.2, 4.5};
    show(array, 11, 12);

    return 0;
}

void show(double array[], int array_size, int field_width)
{
    char buffer[10] = "";
    sprintf(buffer, "%%%d.2f", field_width);
    for (int i = 0; i < array_size; i++)
    {
        if (i % 5 == 0) {
            printf("\n");
        }
        printf(buffer, array[i]);
    }
    printf("\n");
}

習(xí)題10.4 定義一個(gè)函數(shù),使用getchar()函數(shù)從stdin中讀入一個(gè)字符串,這個(gè)字符串用特定的字符終止,這個(gè)特定的終止字符作為第二個(gè)變?cè)獋鹘o這個(gè)函數(shù)。因此,函數(shù)的原型如下:

char *getString(char *buffer, char end_char);

返回值是一個(gè)指針,它是這個(gè)函數(shù)的第一個(gè)變?cè)>帉?xiě)一個(gè)程序,使用這個(gè)函數(shù)從鍵盤(pán)上讀取并輸出5個(gè)以冒號(hào)終止的字符串。

#include <stdio.h>

char *getString(char *, char);

int main()
{
    char buffer[5][100];
    for (int i = 0; i < 5; i++)
    {
        getString(buffer[i], ':');
    }

    for (int i = 0; i < 5; i++)
    {
        printf("%s\n", buffer[i]);
    }

    return 0;
}

char *getString(char *buffer, char end_char)
{
    char *pStr = buffer;
    char ch = '\0';
    for (;;)
    {
        ch = getchar();
        if (ch != end_char) {
            *pStr++ = ch;
        }
        else
        {
            *pStr = '\0';
            break;
        }
    }
    return buffer;
}

第11章 結(jié)構(gòu)化數(shù)據(jù)

習(xí)題11.1 定義一個(gè)結(jié)構(gòu)類型Length,它用碼、英尺和英寸表示長(zhǎng)度。定義一個(gè)add()函數(shù),它相加兩個(gè)Length變?cè)祷豅ength類型的總和。定義第二個(gè)函數(shù)show(),顯示其Length變?cè)闹?。編?xiě)一個(gè)程序,從鍵盤(pán)輸入任意個(gè)單位的碼、英尺以及英寸的長(zhǎng)度,使用Length類型、add()、和show()函數(shù)去匯總這些長(zhǎng)度,并輸出總長(zhǎng)。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

struct Length
{
    int yard;
    int foot;
    int inch;
};

struct Length *add(struct Length *, struct Length *);
void show(struct Length *);

int main()
{
    struct Length *pSum = NULL;
    struct Length **pLength = NULL;
    int count = 0;
    char ch = '\0';

    pSum = malloc(sizeof(struct Length));
    pSum->yard = 0;
    pSum->foot = 0;
    pSum->inch = 0;
    pLength = (struct Length **) malloc(sizeof(struct Length *));
    do
    {
        count++;
        pLength = (struct Length **) realloc(pLength, count * sizeof(struct Length *));
        *(pLength + count - 1) = malloc(sizeof(struct Length));
        printf("請(qǐng)輸入Length:\n");
        printf("Length.yard -> ");
        scanf("%d", &(*(pLength + count - 1))->yard);
        printf("Length.foot -> ");
        scanf("%d", &(*(pLength + count - 1))->foot);
        printf("Length.inch -> ");
        scanf("%d", &(*(pLength + count - 1))->inch);
        getchar();
        ch = getchar();
    } while(tolower(ch) == 'y');

    for (int i = 0; i < count; i++)
    {
        pSum = add(pSum, *(pLength + i));
    }

    show(pSum);
    return 0;
}

struct Length *add(struct Length *a, struct Length *b)
{
    struct Length *pLength = (struct Length *)malloc(sizeof(struct Length));

    pLength->yard = a->yard + b->yard;
    pLength->foot = a->foot + b->foot;
    pLength->inch = a->inch + b->inch;

    return pLength;
}

void show(struct Length *length)
{
    printf("yard=%d, foot=%d, inch=%d\n", length->yard, length->foot, length->inch);
}

習(xí)題11.2 定義一個(gè)結(jié)構(gòu)類型,它含有一個(gè)人的姓名及電話號(hào)碼。在程序中使用這個(gè)結(jié)構(gòu),輸入一個(gè)或多個(gè)姓以及對(duì)應(yīng)的電話號(hào)碼,將輸入的數(shù)據(jù)存儲(chǔ)到一個(gè)結(jié)構(gòu)數(shù)組中。程序允許輸入姓氏,輸出對(duì)應(yīng)于該姓氏的所有電話號(hào)碼,可以選擇是否要輸出所有的姓名及他們的電話號(hào)碼。

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

struct Contacts
{
    char *name;
    int phoneCount;
    char **phone;
};

struct Contacts *newContacts();
void printContacts(struct Contacts *);

int main()
{
    struct Contacts **pContacts = NULL;
    char isContinue = '\0';
    int count = 0;
    char buffer[100] = "";

    pContacts = malloc(sizeof(struct Contacts *));
    do
    {
        count++;
        pContacts = realloc(pContacts, count * sizeof(struct Contacts *));
        *(pContacts + count - 1) = newContacts();
        printf("是否繼續(xù)輸入聯(lián)系人信息(y/n):");
        isContinue = getchar();
        getchar();
    } while (tolower(isContinue) == 'y');

    printf("請(qǐng)輸入姓名:");
    gets(buffer);
    for (int i = 0; i < count; i++)
    {
        if (strcmp(buffer, (*(pContacts + i))->name) == 0) {
            printContacts(*(pContacts + i));
        }
    }

    return 0;
}

struct Contacts *newContacts()
{
    struct Contacts *pContacts = NULL;
    char buffer[100] = "";
    int count = 0;
    char isContinue = '\0';
    pContacts = malloc(sizeof(struct Contacts));

    printf("請(qǐng)輸入姓名:");
    gets(buffer);
    pContacts->name = malloc((strlen(buffer) + 1) * sizeof(char));
    strcpy(pContacts->name, buffer);

    pContacts->phone = malloc(sizeof(char *));
    do
    {
        count++;
        pContacts->phone = realloc(pContacts->phone, count * sizeof(char *));
        printf("請(qǐng)輸入電話號(hào)碼:");
        gets(buffer);
        *(pContacts->phone + count - 1) = malloc((strlen(buffer) + 1) * sizeof(char));
        strcpy(*(pContacts->phone + count - 1), buffer);
        printf("是否繼續(xù)輸入電話號(hào)碼(y/n):");
        isContinue = getchar();
        getchar();
    } while(tolower(isContinue) == 'y');
    pContacts->phoneCount = count;
    return pContacts;
}

void printContacts(struct Contacts *pContacts)
{
    printf("==========\n");
    printf("name = %s\n", pContacts->name);
    for (int i = 0; i < pContacts->phoneCount; i++)
    {
        printf("phone = %s\n", *(pContacts->phone + i));
    }
    printf("==========\n");
}

習(xí)題11.3 修改上一題的程序,將數(shù)據(jù)存儲(chǔ)到鏈表中,按照姓名的字母順序由小到大排序。

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

struct Contacts
{
    char *name;
    int phoneCount;
    char **phone;
    struct Contacts *next;
};

struct Contacts *newContacts();
void printContacts(struct Contacts *);

int main()
{
    struct Contacts *pHead = NULL;
    struct Contacts *pCurrent = NULL;
    struct Contacts *p = NULL;
    struct Contacts *q = NULL;
    char isContinue = '\0';
    int count = 0;

    pHead = malloc(sizeof(struct Contacts));
    do
    {
        count++;
        pCurrent = newContacts();
        if (count == 1) {
            pHead->next = pCurrent;
        }
        else
        {
            p = pHead;
            q = pHead->next;
            while (q) {
                if (strcmp(pCurrent->name, q->name) > 0) {
                    p = q;
                    q = q->next;
                }
                else
                {
                    break;
                }
            }
            pCurrent->next = q;
            p->next = pCurrent;
        }
        printf("是否繼續(xù)輸入聯(lián)系人信息(y/n):");
        isContinue = getchar();
        getchar();
    } while (tolower(isContinue) == 'y');

    pCurrent = pHead;
    for (int i = 0; i < count; i++)
    {
        printContacts(pCurrent->next);
        pCurrent = pCurrent->next;
    }

    return 0;
}

struct Contacts *newContacts()
{
    struct Contacts *pContacts = NULL;
    char buffer[100] = "";
    int count = 0;
    char isContinue = '\0';
    pContacts = malloc(sizeof(struct Contacts));

    printf("請(qǐng)輸入姓名:");
    gets(buffer);
    pContacts->name = malloc((strlen(buffer) + 1) * sizeof(char));
    strcpy(pContacts->name, buffer);

    pContacts->phone = malloc(sizeof(char *));
    do
    {
        count++;
        pContacts->phone = realloc(pContacts->phone, count * sizeof(char *));
        printf("請(qǐng)輸入電話號(hào)碼:");
        gets(buffer);
        *(pContacts->phone + count - 1) = malloc((strlen(buffer) + 1) * sizeof(char));
        strcpy(*(pContacts->phone + count - 1), buffer);
        printf("是否繼續(xù)輸入電話號(hào)碼(y/n):");
        isContinue = getchar();
        getchar();
    } while(tolower(isContinue) == 'y');
    pContacts->phoneCount = count;
    pContacts->next = NULL;
    return pContacts;
}

void printContacts(struct Contacts *pContacts)
{
    printf("==========\n");
    printf("name = %s\n", pContacts->name);
    for (int i = 0; i < pContacts->phoneCount; i++)
    {
        printf("phone = %s\n", *(pContacts->phone + i));
    }
    printf("==========\n");
}

習(xí)題11.4 編寫(xiě)一個(gè)程序,從鍵盤(pán)上輸入一段文本,然后使用結(jié)構(gòu)計(jì)算每個(gè)單詞的出現(xiàn)次數(shù)。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>

struct WordUnit
{
    int count;
    char *word;
    struct WordUnit *next;
};

void statistics(struct WordUnit *, char *);
void printWordUnit(struct WordUnit *);

int main()
{
    char buffer[100] = "";
    char temp[10] = "";
    struct WordUnit *pHead = NULL;
    struct WordUnit *pCurrent = NULL;

    pHead = malloc(sizeof(struct WordUnit));
    pHead->next = NULL;
    gets(buffer);

    for (int i = 0, j = 0; i < strlen(buffer) && j < strlen(buffer);)
    {
        for (int i = 0; i < 10; i++)
        {
            temp[i] = '\0';
        }

        if (isalpha(buffer[i]))
        {
            for (j = i; j < strlen(buffer) && isalpha(buffer[j]); j++)
                ;

            for (int k = i; k < j; k++)
            {
                temp[k - i] = buffer[k];
            }
            statistics(pHead, temp);
            i = j;
        }
        else
        {
            i++;
        }
    }

    printWordUnit(pHead->next);

    return 0;
}

void statistics(struct WordUnit *head, char *word)
{
    bool isNewWord = true;
    struct WordUnit *p = head->next;
    struct WordUnit *q = head;
    while (p) {
        if (strcmp(p->word, word) == 0) {
            p->count++;
            isNewWord = false;
            break;
        }
        q = p;
        p = p->next;
    }
    if (isNewWord) {
        p = malloc(sizeof(struct WordUnit));
        p->count = 1;
        p->word = malloc((strlen(word) + 1) * sizeof(char));
        strcpy(p->word, word);
        q->next = p;
    }
}

void printWordUnit(struct WordUnit *p)
{
    while (p) {
        printf("%10s %2d\n", p->word, p->count);
        p = p->next;
    }
}

習(xí)題11.5 編寫(xiě)一個(gè)程序,讀取任意多個(gè)姓名。用一個(gè)二叉樹(shù)按升序輸出所有的姓名,排序時(shí)先排姓氏,后排名字(例如 Ann Choosy 在 Bill Champ 的后面,在 Arthur Choosy 的前面)。

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

struct Name
{
    char *firstName;
    char *lastName;
    struct Name *leftChild;
    struct Name *rightChild;
};

struct Name *readName();
void printName(struct Name *);
void insertName(struct Name *, struct Name *);

int main()
{
    struct Name *root = NULL;
    char isContinue = '\0';
    int count = 0;
    do
    {
        if (count == 0) {
            root = readName();
        }
        else
        {
            insertName(root, readName());
        }
        count++;
        printf("是否繼續(xù)輸入姓名:");
        isContinue = getchar();
        getchar();
    } while(tolower(isContinue) == 'y');

    printName(root);

    return 0;
}

struct Name *readName()
{
    struct Name *p = malloc(sizeof(struct Name));
    char buffer[20] = "";
    printf("請(qǐng)輸入姓氏:");
    gets(buffer);
    p->lastName = malloc((strlen(buffer) + 1) * sizeof(char));
    strcpy(p->lastName, buffer);
    printf("請(qǐng)輸入名字:");
    gets(buffer);
    p->firstName = malloc((strlen(buffer) + 1) *sizeof(char));
    strcpy(p->firstName, buffer);
    p->leftChild = NULL;
    p->rightChild = NULL;

    return p;
}

void printName(struct Name *p)
{
    if (p != NULL) {
        printName(p->leftChild);
        printf("%s %s\n", p->lastName, p->firstName);
        printName(p->rightChild);
    }
    return;
}

void insertName(struct Name *root, struct Name *p)
{
    if (root != NULL) {
        if (strcmp(root->lastName, p->lastName) >= 0)
        {
            if (root->leftChild != NULL) {
                insertName(root->leftChild, p);
            }
            else{
                root->leftChild = p;
            }
        }
        else
        {
            if (root->rightChild != NULL) {
                insertName(root->rightChild, p);
            }
            else
            {
                root->rightChild = p;
            }
        }
    }
    return ;
}

第12章 處理文件

習(xí)題12.1 編寫(xiě)一個(gè)程序,將任意數(shù)目的字符串寫(xiě)入文件。字符串由鍵盤(pán)輸入,程序不能刪除這個(gè)文件,因?yàn)橄乱活}還要使用這個(gè)文件。

#include <stdio.h>
#include <stdbool.h>

int main()
{
    char buffer[100] = "";
    const char fileName[10] = "data.txt";
    FILE *pFile = NULL;

    pFile = fopen(fileName, "a");
    if (!pFile) {
        printf("打開(kāi)文件失敗\n");
        return 1;
    }
    do {
        fgets(buffer, 100, stdin);
        if (buffer[0] == '\n')
        {
            break;
        }
        fputs(buffer, pFile);
    } while (true);

    fclose(pFile);
    return 0;
}

習(xí)題12.2 編寫(xiě)一個(gè)程序,讀取上一題創(chuàng)建的文件。每次都以反向的順序讀取一個(gè)字符串,然后按照讀取順序?qū)⑺鼈儗?xiě)入一個(gè)新文件。例如,程序讀取最后一個(gè)字符串,將它寫(xiě)入新文件,再讀取倒數(shù)第二個(gè)字符串,將它寫(xiě)入新文件,依次類推。

#include <stdio.h>
#include <stdbool.h>

int count(char *);

int main()
{
    char buffer[100] = "";
    char fileName[10] = "data.txt";
    char fileNameNew[10] = "data2.txt";
    FILE *pFile = NULL;
    FILE *pFileNew = NULL;

    pFile = fopen(fileName, "a");
    if (!pFile) {
        printf("打開(kāi)文件失敗\n");
        return 1;
    }
    do {
        fgets(buffer, 100, stdin);
        if (buffer[0] == '\n')
        {
            break;
        }
        fputs(buffer, pFile);
    } while (true);

    fclose(pFile);

    pFile = fopen(fileName, "r");
    if (!pFile) {
        printf("打開(kāi)文件失敗\n");
        return 1;
    }
    fclose(pFile);

    pFileNew = fopen(fileNameNew, "a");
    for (int i = count(fileName) - 1; i >= 0; i--)
    {
        pFile = fopen(fileName, "r");
        for (int j = 0; j < i; j++)
        {
            fgets(buffer, 100, pFile);
        }

        fgets(buffer, 100, pFile);
        fclose(pFile);
        fputs(buffer, pFileNew);
    }
    fclose(pFileNew);

    return 0;
}

int count(char *pName)
{
    FILE *pFile = NULL;
    pFile = fopen(pName, "r");
    int count = 0;
    char buffer[100] = "";
    while (fgets(buffer, 100, pFile)) {
        count++;
    }
    fclose(pFile);
    return count;
}

習(xí)題12.3 編寫(xiě)一個(gè)程序,從鍵盤(pán)讀入姓名和電話號(hào)碼,將它們寫(xiě)入一個(gè)文件。如果這個(gè)文件不存在,就寫(xiě)入一個(gè)新文件。如果文件已存在,就將它們寫(xiě)入該文件。這個(gè)程序需要提供列出所有數(shù)據(jù)的選項(xiàng)。

#include <stdio.h>

struct Contacts
{
    char name[20];
    char phone[3][15];
};

char fileName[20] = "contacts.txt";

void add();

int main()
{
    add();
    return 0;
}

void add()
{
    struct Contacts con;
    FILE *pFile = NULL;
    pFile = fopen(fileName, "a");
    printf("\n請(qǐng)輸入姓名:");
    fgets(con.name, 20, stdin);
    for (int i = 0; i < 3; i++)
    {
        printf("請(qǐng)輸入第 %d 個(gè)電話號(hào)碼:", i + 1);
        fgets(con.phone[i], 15, stdin);
    }

    fprintf(pFile, "%20s%15s%15s%15s", con.name, con.phone[0], con.phone[1], con.phone[2]);
    fclose(pFile);
}

習(xí)題12.4 擴(kuò)展上一題的程序,提取對(duì)應(yīng)指定的姓名的所有電話號(hào)碼。這個(gè)程序允許進(jìn)一步查詢,添加新的姓名和電話號(hào)碼,刪除已有的項(xiàng)。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdbool.h>

struct Contacts
{
    char name[20];
    char phone[3][15];
};

char fileName[20] = "contacts.txt";

void add();
void printContacts(struct Contacts *);
bool searchByContactsName(char *, struct Contacts *, char *);
void printAll(char *);
void deleteByContactsName(char *fileName, char *contactsName);

int main()
{
    // 此處省略了函數(shù)的調(diào)用
    return 0;
}

void add()
{
    struct Contacts con;
    FILE *pFile = NULL;
    pFile = fopen(fileName, "a");
    printf("\n請(qǐng)輸入姓名:");
    fgets(con.name, 20, stdin);
    for (int i = 0; i < 3; i++)
    {
        printf("請(qǐng)輸入第 %d 個(gè)電話號(hào)碼:", i + 1);
        fgets(con.phone[i], 15, stdin);
    }

    fprintf(pFile, "%20s%15s%15s%15s", con.name, con.phone[0], con.phone[1], con.phone[2]);
    fclose(pFile);
}

void printContacts(struct Contacts *p)
{
    printf("姓名:%s\n\t電話1:%s\n\t電話2:%s\n\t電話3:%s\n", p->name, p->phone[0], p->phone[1], p->phone[2]);
}

void deleteByContactsName(char *fileName, char *name)
{
    FILE *pFileOld = NULL;
    FILE *pFileNew = NULL;
    struct Contacts c;
    char tempFileName[20] = "temp.txt";
    if (!searchByContactsName(fileName, &c, name))
        return;

    pFileOld = fopen(fileName, "r");
    pFileNew = fopen(tempFileName, "a");

    while(fscanf(pFileOld, "%20s%15s%15s%15s", c.name, c.phone[0], c.phone[1], c.phone[2]) != EOF)
    {
        if (strcmp(name, c.name)) {
            fprintf(pFileNew, "%20s%15s%15s%15s", c.name, c.phone[0], c.phone[1], c.phone[2]);
        }
    }

    fclose(pFileOld);
    fclose(pFileNew);

    remove(fileName);
    rename(tempFileName, fileName);
}

bool searchByContactsName(char *fileName, struct Contacts *c, char *name)
{
    FILE *pFile = fopen(fileName, "r");
    while(fscanf(pFile, "%20s%15s%15s%15s", c->name, c->phone[0], c->phone[1], c->phone[2]) != EOF)
    {
        if (strcmp(c->name, name) == 0) {
            return true;
        }
    }
    return false;

}

void printAll(char *fileName)
{
    struct Contacts c;
    FILE *pFile = NULL;
    pFile = fopen(fileName, "r");
    while(fscanf(pFile, "%20s%15s%15s%15s", c.name, c.phone[0], c.phone[1], c.phone[2]) != EOF)
    {
        printContacts(&c);
    }
    fclose(pFile);
}

第13章 支持功能

習(xí)題13.1 定義一個(gè)COMPARE(x, y)宏。如果x<y,就返回-1,如果x==y,就返回0,如果x>y就返回1.編寫(xiě)一個(gè)例子,說(shuō)明這個(gè)宏可以正常工。這個(gè)宏會(huì)優(yōu)于完成相同任務(wù)的函數(shù)碼?

#include <stdio.h>

#define COMPARE(x, y) (x) > (y) ? 1 : ((x) == (y) ? 0 : -1)

int main()
{
    printf("%d\n", COMPARE(5, 3));
    return 0;
}

習(xí)題13.2 定義一個(gè)函數(shù),返回含有當(dāng)前時(shí)間的字符串,如果變?cè)?,它的格式就是12小時(shí)制(a.m./p.m.),如果變?cè)?,它的格式就是24小時(shí)制。編寫(xiě)一個(gè)程序,說(shuō)明這個(gè)函數(shù)可以正常工作。

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

char *getTimeString(int format);

int main()
{
    printf("%s\n%s\n", getTimeString(0), getTimeString(1));
    return 0;
}

char *getTimeString(int format)
{
    char *pStr = NULL;
    char buffer[20] = "";
    struct tm *t = NULL;
    time_t val = time(NULL);
    t = localtime(&val);
    if (format == 0) {
        sprintf(buffer, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec);
    }
    else
    {
        sprintf(buffer, "%02d:%02d:%02d", t->tm_hour > 12 ? t->tm_hour - 12 : t->tm_hour, t->tm_min, t->tm_sec);
    }

    pStr = (char *)malloc((strlen(buffer) + 1) * sizeof(char));
    strcpy(pStr, buffer);
    return pStr;
}

習(xí)題13.3 定義一個(gè)print_value(expr)宏,在新的一行上輸出 exp = result,其中result的值由expr算出。編寫(xiě)一個(gè)例子,說(shuō)明這個(gè)宏可以正常工作。

#include <stdio.h>

#define print_value(expr) printf("exp = %d\n", expr)

int main()
{
    print_value(3 + 2);
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容