第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;
}