c语言现代方法15章答案(自己做的,更新中)
15.1節
1.15.1
(a)優點:把相關的函數和變量分組放在一個文件中可以使程序的結構清晰。可以分別對每個源文件進行編譯,如果程序規模很大而且需要頻繁改變。把函數分組放在不同的源文件中更有利于復用。在示例中,吧stack.c和token.c從main函數中分離出來使得今后更容易復用棧函數和記號函數。
(b)缺點:某文件中的函數如何調用定義在其它文件中的函數呢?函數如何訪問其他文件中的外部變量呢?兩個文件如何共享同一個宏定義或類型定義呢?答案取決于#include指令,此指令使得在任何數量的源文件中共享信息稱為可能,這些信息可以是函數原型、宏定義、類型定義等。
15.2節
2下面哪個不應該放在頭文件中?為什么
function definations shouldn't be put in a header file.If a function defination appears in a header file that is included by two(or more) source files,the program cann't be linked,since the linker will see two copies of the function。
剛才網上看到一個帖子,說是分配內存的定義不要放在頭文件中,不分配內存的定義可以放在頭文件中,比如說類型定義不分配內存,可以放在頭文件中。
編程題自己坐做的答案:
1.line.c改成如下形式(主要是函數write_line改變了)
void write_line(void) { //如果extra_spaces可以平均分配到每個單詞間隔中,那么不調整。除非不能平均分配才調整 bool space_added = false;//記錄某個間隔是否增加了額外的一個空格 int extra_spaces,spaces_to_insert,i,j; extra_spaces = MAX_LINE_LEN - line_len; for(i = 0; i < line_len ; ++i){if(line[i] != ' ')putchar(line[i]);else{spaces_to_insert = extra_spaces / (num_words - 1);for(j = 1; j <= spaces_to_insert + 1 ; ++ j)putchar(' ');//只有當extra_spaces不能平均分配且上一個間隔沒增加過空格才可以增加空格if(extra_spaces % (num_words - 1) != 0 && space_added == false){putchar(' ');space_added = true;extra_spaces -= (spaces_to_insert + 1); }else{extra_spaces -=spaces_to_insert;space_added = false;}num_words --; }} putchar('\n'); }自己驗證還是可以的。
3.
//main.c #include <stdio.h> #include "quicksort.h"#define N 10 int main() { int a[N]; printf("Enter %d numbers:",N); for(int i = 0;i != N; ++i) {scanf("%d",&a[i]); } quicksort(a,0,N-1);printf("Sorted numbers:"); for(int i = 0;i != N ;++i) {printf("%d ",a[i]); }return 0; } //quicksort.h/****************************************************************** split:分割數組,把一個分割數放在正確的位置****************************************************************/ int split(int a[],int ,int );/****************************************************************** quicksort:快速排序算法(遞歸調用自己),每調用一次,產生一個分割* 數,并且把分割數放在正確的位置,然后遞歸調用本身,把分割數左側* 和右側的部分排序****************************************************************/ void quicksort(int a[],int ,int ); //quicksort.c#include "quicksort.h" #include <stdio.h>/****************************************************************1.算法總體是循環,每個循環包含一個左到右的迭代,另一個右到左迭代*2.算法必須能正確處理兩種情況:* 從左往右迭代時候遇到大于mid和遇不到大于mid都必須正確處理*3.循環結束的時候high和low相等的時候,必須先把mid拷貝到high(或者low的位置),然后才能返回mid結束程序。*4.split功能:把分割數mid放在正確的位置,并且返回這個位置.*5.根據數學中收斂的原理我們不難發現,總能通過有限次的運行,把數組*的全部元素通過調用split排序完畢。* ************************************************************/int split(int a[],int low,int high) { int tmp = a[low]; for( ; ; ) { int i; while(high > low) {if(a[high] < tmp){//此時high不能遞減,直接breaka[low] = a[high];break; }//為了在所有迭代都不遇到小于mid的極端情況下正確運行,每次--high-- high; }//為了能在所有迭代都不遇到大于mid的極端情況下正確運行,每次循環結束 //都++low for(i = low;i < high; ++i,++ low) {if(a[i] > tmp){a[high] = a[i];break; } } if(low == high){a[low] = tmp;return low;}} }/***************************************************************quicksort通過三步實現排序:*(1)首先把分割數(第i個位置)放在正確的位置*(2)通過遞歸地采用快速排序算法,對從0到i-1的元素進行排序*(3)通過遞歸滴采用快速排序算法,對從i+1到n的元素進行排序* ************************************************************///比較專業些的算法都需要從數學角度去理解,去證明然后才能徹底理解 void quicksort(int a[],int low,int high) { //函數的功能是把分割數放在正確的位置,且遞歸調用自身排序 if(low >= high)return; int middle; //第一步:把middle位置的元素(middle位置元素是分割數)放在正確的位置 middle = split(a,low,high); //第二步:把0到middle-1的元素遞歸調用自身排序 quicksort(a,low,middle-1); //第三步:把middle+1到n的元素通過遞歸調用自身排序 quicksort(a,middle+1,high);}?總體來說,我對快速排序算法的理解是,對于所有的有限數列,總能通過有限的如下步驟來進行排序:
1.把分割數(元素e,位置在middle)放在正確的位置
2.把0到middle-1位置的元素排序
3.把middle+1到n的元素排序
4題.
/main.cc#include <stdio.h> #include <string.h> #include "reminder.h"extern int number_remind;int main() { char reminders[MAX_REMIND][MSG_LEN + 3]; read_msg(reminders,MAX_REMIND);print(reminders,number_remind);return 0; } //reminder.c#include <string.h> #include <stdio.h> #include "reminder.h"int number_remind;void read_msg(char reminders[][MSG_LEN + 3],int n) { int day,i,j,num_remind = 0; char day_str[3]; char reminder[MSG_LEN + 1];for(;;) {if(num_remind == MAX_REMIND){puts("--No space left--");number_remind = num_remind;break; }printf("Enter day and reminder:");//這里%2d是指最多讀取2位整數,如果輸入整數多余2位,多余丟棄//但如果第二位是字符(比如說空格、回車、其它字符)也會停止讀入//這里%2d如果寫成%-2d,那么在調用strcmp比較日期的時候回出問題//因為%-2d會把單個數字的日期的數字放在左邊,這樣在比較日期的時候//將會首先按照各位數字進行比較,如果%2d就不一樣了,day_str左邊會//用' '補充,而空格的ASC11碼小于任何一個數字的,所以個位數日期是//最小的(strcmp函數比較時候)scanf("%2d",&day);if(day == 0){number_remind = num_remind;break;}//將整數轉換成字符串,如果位數不夠就用' '補齊.sprintf(day_str,"%2d",day);read_line(reminder,MSG_LEN + 1);for(i = 0;i != num_remind; ++ i){if(strcmp(reminders[i],day_str) > 0) break; }for(j = num_remind - 1; j >= i; --j){strcpy(reminders[j+1],reminders[j]);} strcpy(reminders[i],day_str);strcat(reminders[i],reminder);num_remind ++; }}void read_line(char *a,int n) { char ch; int i = 0; while((ch = getchar()) != '\n'){ a[i ++] = ch; } a[i] = '\0'; }void print(char reminders[][MSG_LEN + 3],int n) { puts(""); //輸出一個換行 for(int i = 0;i != n; ++ i){puts(reminders[i]); }} //reminder.h#ifndef REMINDER_H #define REMINDER_H#include <string.h> #include <stdio.h>#define MSG_LEN 60 #define MAX_REMIND 50extern int number_remind;/************************************************************** * read_msg:讀取日期和remind ***************************************************************/ void read_msg(char reminders[][MSG_LEN + 3],int n);/************************************************************** * read_reminder:讀取一條reminder ***************************************************************/ void read_line(char *,int );/*************************************************************** print:打印reminders* ***********************************************************/ void print(char reminders[][MSG_LEN + 3],int );#endif5.
//main.c #include <stdio.h> #include "stack.h" int main() { printf("%d\n",size()); push(123); printf("%d\n",is_empty()); int ret = pop(); printf("%d",ret);return 0; } //stack.c #include <stdio.h> #include <stdlib.h> #include "stack.h"#define STACK_SIZE 100int contents[STACK_SIZE]; int top = 0;void push(int i) { if(is_full()){printf("Fail to push,stack is full.");exit(EXIT_FAILURE);} contents[top ++] = i; }int pop(void) { if(is_empty()){printf("Error,pop from empty stack.");exit(EXIT_FAILURE);} return contents[--top]; }int size(void) { return top; }bool is_full(void) {return top == STACK_SIZE; } void make_empty(void) {top = 0; }bool is_empty(void) { return top == 0; } #ifndef SATCK_H #define STACK_H#include <stdio.h> #define bool int extern int contents[]; extern int top;/**/ void push(int s);/**/ int pop(void);/**/ bool is_empty(void);/**/int size(void);/**/ bool is_full(void);/**/ void make_empty(void);#endif總結
以上是生活随笔為你收集整理的c语言现代方法15章答案(自己做的,更新中)的全部內容,希望文章能夠幫你解決所遇到的問題。