C语言程序设计第五版谭浩强 第七章答案
C語言程序設計第五版譚浩強著 第七章答案
第七章 用函數實現模塊化程序設計
1、寫兩個函數,分別求兩個整數的最大公約數和最小公倍數,用主函數調用這兩個函數,并輸出結果。兩個整數由鍵盤輸人。
題目解析:
-
該題直接使用“輾轉相除法”來求解最大公約數和最小公倍數
-
最大公約數找出兩數中的最小值,然后直接相模,當能夠同時被兩數整除時,則為最大公約數。
-
最小公倍數找出兩數中的最大值,然后直接進入死循環,直到找到一個數能夠同時被兩數整除時,則為最小公倍數
【注】此題還有一些比較高級的解法,比如求最大公約數的相減法、歐幾里德輾轉相除法等,有興趣的同學可以查詢相關資料
代碼示例:
#include<stdio.h>//最大公約數 size_t GCD(size_t a, size_t b) { size_t gcd; gcd = a > b ? b : a;while(gcd > 1) {if((a % gcd == 0) && (b % gcd == 0)) return gcd; gcd--; }return gcd; }//最小公倍數 size_t LCM(size_t a, size_t b) {size_t lcm;lcm = a > b ? a : b;while(1){if((lcm % a==0) && (lcm % b==0))break;lcm++;}return lcm; }int main() {size_t a, b, result;printf("請輸入兩個整數:>");scanf("%d %d", &a, &b);result = GCD(a, b);printf("%d和%d的最大公約數為:%d\n", a, b, result);result = LCM(a, b);printf("%d和%d的最小公倍數為:%d\n", a, b, result);return 0; }運行結果:
2、求方程 ax2+bx+c=0{ax}^2+bx+c=0ax2+bx+c=0的根,用3個函數分別求當: b2?4acb^2-4acb2?4ac大于0、等于0和小于0時的根并輸出結果。從主函數輸入a,b,c的值。
題目解析
- 根據disc = b2?4acb^2-4acb2?4ac 的值來決定如何求根,題目本身編程不難,不過需要同學們復習一下高中的數學知識哦。
代碼示例
#include<stdio.h> #include<math.h>//x1為第一個根,x2為第二個根 float x1, x2, disc, p, q;void greater_than_zero(float a, float b) {float m = sqrt(disc);x1 = (-b + sqrt(disc)) / (2 * a);x2 = (-b - sqrt(disc)) / (2 * a); }void equal_to_zero(float a, float b) {x1 = x2 = (-b) / (2 * a); }void smaller_than_zero(float a, float b) {p = -b / (2 * a);q = sqrt(-disc) / (2 * a); }int main() {int a, b, c;printf("請輸入 a b c:");scanf("%d %d %d", &a, &b, &c);printf("表達式為: %d*x^2+%d*x+%d = 0\n", a, b, c);disc = b*b - 4 * a*c;if (disc > 0){greater_than_zero(a, b);printf("disc>0的根為: x1=%f x2=%f\n", x1, x2);}else if (disc == 0){equal_to_zero(a, b);printf("disc==0的根為:x1=%f x2=%f\n", x1, x2);}else{smaller_than_zero(a, b);printf("disc<0的根為:x1=%f+%f x2=%f-%f\n", p, q, p, q);}return 0; }運行結果:
3、寫一個判素數的函數,在主函數輸人一個整數,輸出是否為素數的信息。
題目解析:
-
素數是一個大于1的自然數,除了1和它自身外,不能被其他自然數整除的數叫做素數
-
該題可以使用概念直接判斷法求解,不過不需要判斷所有的數據,只需要判斷數據的一半即可,因為偶數不可能為素數(除了2),所以只需判斷該數的一半即可的到答案
代碼示例:
#include<stdio.h> #include<stdbool.h>bool IsPrime(int value) {for(int i=2; i<value/2; ++i){if(value % i == 0) //說明除了1和本身之外,還能被其他數整除return false;}return true; }int main() {int value;bool flag;printf("請輸入 value :>");scanf("%d", &value);flag = IsPrime(value);if(flag)printf("%d 是素數.\n", value);elseprintf("%d 不是素數.\n", value);return 0; }運行結果:
4、寫一個函數,使給定的一個3X3的二維整型數組轉置,即行列互換。
題目解析:
進行數組的行列互換,其關鍵在于數組互換的表達式 ar[i] [j] = ar[j] [i];其次在循環的時候,內層循環不能到達最大列,需要根據此時是第幾行的交換來決定循環的次數,否則有可能數組行列交換之后最后又交換回原來的形狀了。
代碼示例
#include<stdio.h>void PrintArray(int ar[3][3]) {for(int i=0; i<3; ++i){for(int j=0; j<3; ++j){printf("%d ", ar[i][j]);}printf("\n");} }void ReverseArray(int ar[3][3]) {int tmp;for(int i=0; i<3; ++i){for(int j=0; j<i; ++j){if(i != j) //中間數不發生變化{//交換兩個數tmp = ar[i][j];ar[i][j] = ar[j][i];ar[j][i] = tmp;}}} }int main() {int array[3][3] = {{1,2,3},{4,5,6},{7,8,9}};printf("轉置前:\n");PrintArray(array);//進行數組轉置ReverseArray(array);printf("轉置后:\n");PrintArray(array);return 0; }運行結果:
5、寫一個函數,使輸人的一個字符串按反序存放,在主函數中輸入和輸出字符串。
題目解析及答案:
- 要把一個字符串反序存放,其實就是對字符串做一個逆序操作,操作過程為收尾字符交換,直到把所有字符全部交換完畢。
示例代碼
#include<stdio.h>void ReverseString(char str[]) {int start, end;char tmp;start = 0;end = strlen(str)-1; //字符數組小標從0開始,所以-1while(start < end){tmp = str[start];str[start] = str[end];str[end] = tmp;start++;end--;} }int main() {char str[100] = {0};printf("請輸入一個字符串:>");scanf("%s", str);printf("原始字符串為:> %s\n", str);ReverseString(str);printf("反序字符串為:> %s\n", str);return 0; }運行結果:
6、寫一個函數,將兩個字符串連接。
題目解析及答案:
- 利用一個臨時數組,空間要保證能夠容納兩個字符串,先把第一個字符串進行拷貝到臨時數組,第二個字符串在臨時數組的尾部接著鏈接,最后記得加上字符串的結束標記\0即可
代碼示例:
#include<stdio.h>void ConcatStr(char string1[], char string2[], char string[]) {int i, j;for (i = 0; string1[i] != '\0'; i++)string[i] = string1[i];//找到字符串末尾,繼續往后面鏈接字符串for (j = 0; string2[j] != '\0'; j++)string[i + j] = string2[j];//字符串末尾加上結束符 \0string[i + j] = '\0'; }int main() {char s1[200] = {0}, s2[100]= {0}, s[100] = {0};printf("input string1:");scanf("%s", s1);printf("input string2:");scanf("%s", s2);ConcatStr(s1, s2, s);printf("\nThe new string is %s\n", s);return 0; }運行結果:
7、寫一個函數,將一個字符串中的元音字母復制到另一字符串,然后輸出。
題目解析:
- 該題的重點在于元音字母的判斷,通過或條件,凡是元音字母都進行拷貝
代碼示例:
#include<stdio.h>void cpy(char s[], char c[]) {int i, j;for (i = 0, j = 0; s[i] != '\0'; i++){//判斷元音字母if (s[i] == 'a' || s[i] == 'A' || s[i] == 'e' || s[i] == 'E' || s[i] == 'i' ||s[i] == 'I' || s[i] == 'o' || s[i] == 'O' ||s[i] == 'u' || s[i] == 'U'){c[j] = s[i];j++;}}c[j] = '\0'; }int main() {char str[80], c[80];printf("input string:");gets(str);cpy(str, c); //將str中的元音字母拷貝到c中printf("The vowel letters are:%s\n", c);return 0; }運行結果:
8、寫一個函數,輸人一個4位數字,要求輸出這4個數字字符,但每兩個數字間空一個空格。如輸人1990,應輸出“1 9 9 0”。
題目解析:
對字符串進行遍歷輸出,沒輸出一個字符,后面就跟著輸出一個空格,關鍵點在于如果輸出的是最后一個字符,則不能在輸出字符,所以要對是否是最后一個字符的輸出進行判斷。
代碼示例:
#include<stdio.h>void OutString(char str[]) {int i = 0;while(str[i] != '\0'){printf("%c", str[i]);if(str[i+1] == '\0') //清除最后一個空格不輸出break;printf("%c", ' ');i++;}printf("\n"); } int main() {char str[5] = {0};printf("input four digits:");scanf("%s", str);OutString(str);return 0; }運行結果:
9、編寫一個函數,由實參傳來一個字符串,統計此字符串中字母、數字、空格和其他字符的個數,在主函數中輸人字符串以及輸出上述的結果。
題目解析:
- 該題的關鍵在于要能夠寫出各種字符統計的條件
代碼示例:
#include<stdio.h>int letter, digit, space, others;void CountChar(char str[]) {int i;for (i = 0; str[i] != '\0'; i++){//統計字母if ((str[i] >= 'a'&& str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z')) letter++;else if (str[i] >= '0' && str[i] <= '9') //統計數字digit++;else if (str[i] == ' ')//統計空格space++;elseothers++; //統計其他字符} }int main() {char text[80];printf("input string:\n");gets(text);printf("string: %s\n", text);CountChar(text);printf("\nletter:%d\ndigit:%d\nspace:%d\nothers:%d\n", letter, digit, space, others);return 0; }運行結果:
10、寫一個函數,輸人一行字符,將此字符串中最長的單詞輸出。
題目解析及答案:
- 單詞以空格進行分隔,因此尋找空格出現的位置即為關鍵,每次從單詞的起始到空格出現的位置即為一個單詞,此時計算單詞的長度,如果比當前最大的還長,就進行跟新最長單詞信息,當整個字符串遍歷完成,word即保存最長字符串。
代碼示例:
#include<stdio.h> #include<string.h>void LongestWord(char str[], char word[]) {int max_len = 0;int len = 0;int i = 0;while(str[i] != '\0'){if(str[i] == ' '){str[i] = '\0';len = strlen(str);if(len > max_len){max_len = len;strcpy(word, str);str = str + len + 1;}}i++;} }int main() {char line[100] = {0};char word[100] = {0};printf("input one line:\n");gets(line);LongestWord(line, word);printf("The longest word is : %s\n", word);return 0; }運行結果:
11、寫一個函數,用“起泡法”對輸人的10個字符按由小到大順序排列。
題目解析及答案:
- 該題主要是對冒泡排序的理解,外層循環控制排序的趟數,內層循環主要是進行每一趟排序的比較,如果前面的字符大于后面的字符,就進行交換,每做一趟排序,就把一個最大字符排在最后,以及每做一趟排序就需要少比較一個字符。
代碼示例:
#include<stdio.h> #include<string.h>void BubbleSort(char str[]) {int i, j;char tmp;int len = strlen(str);for(i=0; i<len-1; ++i){for(j=0; j<len-i-1; ++j){if(str[j] > str[j+1]){tmp = str[j];str[j] = str[j+1];str[j+1] = tmp;}}} }int main() {int i;char str[11] = {0};printf("請輸入10個字符:>");for(i=0; i<10; ++i)scanf("%c", &str[i]);BubbleSort(str);printf("string sorted: %s\n", str);return 0; }運行結果:
12、用牛頓迭代法求根。方程為ax3+bx2+cx+d=0ax^3+bx^2 +cx+d=0ax3+bx2+cx+d=0,系數a,b,c,d的值依次為1,2,3,4,由主函數輸人。求x在1附近的一個實根。求出根后由主函數輸出。
題目解析及答案:
- 此題的難點并不是編程,主要是要理解數學公式的求解方法,理解之后代碼的實現并不困難。
代碼示例:
#include<stdio.h> #include<math.h>float solut(int a, int b, int c, int d) {float x = 1, x0, f, f1;do{x0 = x;f = ((a*x0 + b)*x0 + c)*x0 + d;f1 = (3 * a*x0 + 2 * b)*x0 + c;x = x0 - f / f1;} while (fabs(x - x0) >= 1e-3);return(x); }int main() {int a, b, c, d;printf("input a,b,c,d:");scanf("%d %d %d %d", &a, &b, &c, &d);printf("x=%10.7f\n", solut(a, b, c, d));return 0; }運行結果:
13.用遞歸方法求n階勒讓德多項式的值,遞歸公式為
題目解析及答案:
- 遞歸函數的設計,有一個點非常重要,那就是必須要有返回條件,,此題中的返回條件即為n0和n1時,因為當n為這兩值時,程序直接返回相應的值,只有n>=1時,才進行遞歸運算。
代碼示例:
#include<stdio.h>double polya(int n,int x) {double result; if(n == 0) result = 1; if(n == 1)result = x; if(n>1)result = ((2*n-1)*x*polya(n-1,x)-(n-1)*polya(n-2,x))/n; return result; }int main() { int x,n; scanf("%d %d", &n, &x); printf("%.2f\n", polya(n,x)); return 0; }運行結果:
14、輸人10個學生5門課的成績,分別用函數實現下列功能:
①計算每個學生的平均分;
②計算每門課的平均分;
③找出所有50個分數中最高的分數所對應的學生和課程;
④計算平均分方差:
其中,x;為某一學生的平均分。
題目解析及答案:
- 此題的關鍵是如何存儲某個學生對應某門課程的分數,這里利用了一個二維數組score,其中score[i] [j]就代表了第i個學生的第j門課程的分數,只要能夠理解這個存儲方式,其余的計算就是比較容易理解和實現的。
代碼示例:
#include<stdio.h>#define N 10 #define M 5 float score[N][M]; float a_stu[N], a_cour[M]; int r, c;//輸入學生成績信息函數 void input_stu(void) {int i, j;for (i = 0; i < N; i++){printf("\ninput score of student%2d:\n", i + 1);for (j = 0; j < M; j++)scanf("%f", &score[i][j]);} }//每個學生平均分 void aver_stu(void) {int i, j;float s;for (i = 0; i < N; i++){for (j = 0, s = 0; j < M; j++)s += score[i][j];a_stu[i] = s / 5.0;} }//每門課程平均分 void aver_cour(void) {int i, j;float s;for (j = 0; j < M; j++){s = 0;for (i = 0; i < N; i++)s += score[i][j];a_cour[j] = s / (float)N;} }//最高分函數 float highest() {float high;int i, j;high = score[0][0];for (i = 0; i < N; i++)for (j = 0; j<M; j++)if (score[i][j]>high){high = score[i][j];r = i + 1;c = j + 1;}return(high); }//方差函數 float s_var(void) {int i;float sumx, sumxn;sumx = 0.0;sumxn = 0.0;for (i = 0; i < N; i++){sumx += a_stu[i] * a_stu[i];sumxn += a_stu[i];}return(sumx / N - (sumxn / N)*(sumxn / N)); }int main() {int i, j;float h;input_stu();aver_stu();aver_cour();printf("\n NO. cour1 cour2 cour3 cour4 cour5 aver\n");for (i = 0; i < N; i++){printf("\n NO %2d ", i + 1);for (j = 0; j < M; j++)printf("%8.2f", score[i][j]);printf("%8.2f\n", a_stu[i]);}printf("\naverage:");for (j = 0; j < M; j++)printf("%8.2f", a_cour[j]);printf("\n");h = highest();printf("highest:%7.2f NO. %2d course %2d\n", h, r, c);printf("variance %8.2f\n", s_var());return 0; }運行結果:
15、寫幾個函數:
- ①輸人10個職工的姓名和職工號;
②按職工號由小到大順序排序,姓名順序也隨之調整;
③要求輸人一個職工號,用折半查找法找出該職工的姓名,從主函數輸人要查找的職工號,輸出該職工姓名。
題目解析及答案:
利用二分查找的關鍵在于數據一定要先有序,所以在查找前我們需要對數據進行排序。
代碼示例:
#include<stdio.h>#define N 10void input(int num[], char name[N][8]) {int i;for (i = 0; i < N; i++){printf("input NO.: ");scanf("%d", &num[i]);printf("input name: ");getchar();gets(name[i]);} }void sort(int num[], char name[N][8]) {int i, j, min, templ;char temp2[8];for (i = 0; i < N - 1; i++){min = i;for (j = i; j<N; j++)if (num[min]>num[j]) min = j;templ = num[i];strcpy(temp2, name[i]);num[i] = num[min];strcpy(name[i], name[min]);num[min] = templ;strcpy(name[min], temp2);}printf("\n result:\n");for (i = 0; i < N; i++)printf("\n %5d%10s", num[i], name[i]); }void search(int n, int num[], char name[N][8]) {int top, bott, mid, loca, sign;top = 0;bott = N - 1;loca = 0;sign = 1;if ((n<num[0]) || (n>num[N - 1]))loca = -1;while ((sign == 1) && (top <= bott)){mid = (bott + top) / 2;if (n == num[mid]){loca = mid;printf("NO. %d , his name is %s.\n", n, name[loca]);sign = -1;}else if (n < num[mid])bott = mid - 1;elsetop = mid + 1;}if (sign == 1 || loca == -1)printf("%d not been found.\n", n); }int main() {int num[N], number, flag = 1, c;char name[N][8];input(num, name);sort(num, name);while (flag == 1){printf("\ninput number to look for:");scanf("%d", &number);search(number, num, name);printf("continue ot not(Y/N)?");getchar();c = getchar();if (c == 'N' || c == 'n')flag = 0;}return 0; }運行結果:
16、寫一個函數,輸人一個十六進制數,輸出相應的十進制數。
題目解析及答案:
- 轉換的過程需要乘的基數為16,其次注意十六進制中的a~f的字母轉換,并且無論大小寫都要能夠轉換。
代碼示例:
#include<stdio.h>size_t HextoDec(char s[]) {size_t i, n;n = 0;for (i = 0; s[i] != '\0'; i++){if (s[i] >= '0'&& s[i] <= '9')n = n * 16 + s[i] - '0';if (s[i] >= 'a' && s[i] <= 'f')n = n * 16 + s[i] - 'a' + 10;if (s[i] >= 'A' && s[i] <= 'F')n = n * 16 + s[i] - 'A' + 10;}return n; }int main() {size_t result = 0;char hex[9] = {0}; printf("input a HEX number:");scanf("%s", hex);result = HextoDec(hex);printf("0x%s = %u\n", hex, result);return 0; }運行結果:
17、用遞歸法將一個整數n轉換成字符串。例如,輸人483,應輸出字符串”483”。n的位數不確定,可以是任意位數的整數。
題目解析及答案:
- 遞歸法求解主要要有結束條件,此題為n/10 == 0時就直接輸出,其次本題還要考慮如果整數位負數的情形,此時需要輸出一個字符串的負號。
運行結果:
18、給出年、月、日,計算該日是該年的第幾天。
題目解析:
- 此題采用枚舉法進行每月天數的累加,其中關鍵點注意需要判斷年份是否為閏年,如果是還需要多累加1天。
代碼示例:
#include <stdio.h> #include<stdio.h>/* 函數sum_day:計算日期 */ int sum_day(int month, int day) {int day_tab[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };int i;for (i = 1; i < month; i++)day += day_tab[i]; /* 累加所在月之前天數 */return day; } /* 函數leap:判斷是否為閏年 */ int leap(int year) {int leap;leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;return leap; }int main() {int year, month, day, days;printf("input date(year,month,day):");scanf("%d %d %d", &year, &month, &day);printf("%d/%d/%d ", year, month, day);days = sum_day(month, day); /* 調用函數sum_day */if (leap(year) && month >= 3) /* 調用函數leap */days = days + 1;printf("is the %dth day in this year.\n", days);return 0; }運行結果:
C語言程序設計第五版譚浩強 第七章答案
更多C語言程序設計譚浩強第五版課后答案
譚浩強C語言程序設計第五版 第六章答案
總結
以上是生活随笔為你收集整理的C语言程序设计第五版谭浩强 第七章答案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据缓冲区高速缓冲
- 下一篇: HFSS威尔金森(Wilkinson)功