【原創】C程序設計語言(2版KR) - C語言基礎知識(2)數組
教材答案:函數
/************************************************************************* > File Name: 1_13.c > Author: Geng > Mail: genglut@163.com > Created Time: Tue 18 Nov 2014 11:17:57 PM CST ************************************************************************/ /************************************************************** 直方圖定義: n:某個長度單詞出現的次數(長度爲4的單詞出現了9次,則n = 9) M:出現最頻繁的長度的次數 H:定義的直方圖的最大長度(本例中爲MAXHIST) **************************************************************/ #include <stdio.h> #define MAXHIST 15 //直方圖的最大長度 #define MAXWORD 11 //單詞的最大長度 #define IN 1 //在單詞中 #define OUT 0 //在單詞外 int main() { int c, i, nc, state; //nc:單詞的長度 int len; //直方圖中每一個直方條的長度 int maxvalue; //wl數組的最大值 int ovflow; //長度大於或等於MAXWORD的單詞的數量 int wl[MAXWORD]; //按單詞長度值0~11,統計輸入中各長度的單詞數,存放在wl數組中 state = OUT; nc = 0; ovflow = 0; for(i = 0; i < MAXWORD; ++i) wl[i] = 0; while((c = getchar()) != EOF) { if(c == ' ' || c == '\n' || c == '\t') { state = OUT; if(nc > 0) if(nc < MAXWORD) ++wl[nc]; else ++ovflow; nc = 0; } else if(state == OUT) { state = IN; nc = 1; } else ++nc; } maxvalue = 0; for(i = 1; i < MAXWORD; ++i) if(wl[i] > maxvalue) maxvalue = wl[i]; for(i = 1; i < MAXWORD; ++i) { printf("%5d - %5d : ", i, wl[i]); if(wl[i] > 0) { if((len = wl[i] * MAXHIST / maxvalue) <= 0) len = 1; } else len = 0; while(len > 0) { putchar('*'); --len; } putchar('\n'); } if(ovflow > 0) printf("there are %d words >= %d/n", ovflow, MAXWORD); return 0; }
函數的默認返回類型爲int型。spa
int power(int, int);
extern int max; extern char longest[];
C語言中註釋分爲如下幾種
1) /* hello world */
2) // hello world
3) #if 0
hello world
#endif
表面上看起來很簡單,其實實現起來比較複雜,有不少細節須要處理,好比註釋和引號互相嵌套的問題,/* "hello */ " world */, "/* hello */"。還有好比刪除註釋後須要適當調整格式使其整齊美觀。
目前C語言中的主流注釋方式爲第一種,故暫時只實現了第一種,其實原理都是同樣的。核心原理即爲狀態機,讀入一個字符,根據當前狀態和讀入的字符轉入下一個狀態,每個狀態都有相應的動做處理讀入的字符,如忽略或寫入輸出文件或退出上一個字符等等。
共有如下幾個狀態
#define STATUS_OUTTE 0 /* 在註釋和引號外面 */
#define STATUS_DOTTE 1 /* 在引號內部 */
#define STATUS_STIN1 2 /* 讀入 /,等待 * */
#define STATUS_STIN2 3 /* 讀入 /* , 準備進入註釋 */
#define STATUS_STINN 4 /* 在註釋內部 */
#define STATUS_STOU1 5 /* 讀入 * , 等待 / */
#define STATUS_STOU2 6 /* 讀入 */, 準備離開註釋 */
#define STATUS_STACT 7 /* 僞狀態,表示狀態機動做 */
狀態機有如下幾種動做
#define STFLAG_NOACT 0 /* 沒動做,忽略字符 */
#define STFLAG_FPUTC 1 /* 將字符寫入輸出文件 */
#define STFLAG_UNPUT 2 /* 將上一個字符退出 */
完整實現以下.net
/* comment.h */ #ifndef _comment_h #define _comment_h void comment(char *inpath, char *outpath); #endif
/* comment.c */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include "comment.h" #define STATUS_OUTTE 0 #define STATUS_DOTTE 1 #define STATUS_STIN1 2 #define STATUS_STIN2 3 #define STATUS_STINN 4 #define STATUS_STOU1 5 #define STATUS_STOU2 6 #define STATUS_STACT 7 #define STFLAG_NOACT 0 #define STFLAG_FPUTC 1 #define STFLAG_UNPUT 2 static FILE *fpin, *fpout; static int status_table[8][128]; static int status = STATUS_OUTTE; #define st(i, j) status_table[(i)][(j)] static void set_status_table(int i, int j, int s) { if (j != -1) st(i, j) = s; else { for (j = 0; j < 128; j++) status_table[i][j] = s; } } static void init_status(void) { set_status_table(STATUS_OUTTE, -1 , STATUS_OUTTE); set_status_table(STATUS_OUTTE, '/', STATUS_STIN1); set_status_table(STATUS_OUTTE, '"', STATUS_DOTTE); set_status_table(STATUS_DOTTE, -1 , STATUS_DOTTE); set_status_table(STATUS_DOTTE, '"', STATUS_OUTTE); set_status_table(STATUS_STIN1, -1 , STATUS_OUTTE); set_status_table(STATUS_STIN1, '/', STATUS_STIN1); set_status_table(STATUS_STIN1, '*', STATUS_STIN2); set_status_table(STATUS_STIN1, '"', STATUS_DOTTE); set_status_table(STATUS_STIN2, -1 , STATUS_STINN); set_status_table(STATUS_STIN2, '*', STATUS_STOU1); set_status_table(STATUS_STINN, -1 , STATUS_STINN); set_status_table(STATUS_STINN, '*', STATUS_STOU1); set_status_table(STATUS_STOU1, -1 , STATUS_STINN); set_status_table(STATUS_STOU1, '*', STATUS_STOU1); set_status_table(STATUS_STOU1, '/', STATUS_STOU2); set_status_table(STATUS_STOU2, -1 , STATUS_OUTTE); set_status_table(STATUS_STOU2, '"', STATUS_DOTTE); set_status_table(STATUS_STOU2, '/', STATUS_STIN1); set_status_table(STATUS_STACT, STATUS_OUTTE, STFLAG_FPUTC); set_status_table(STATUS_STACT, STATUS_DOTTE, STFLAG_FPUTC); set_status_table(STATUS_STACT, STATUS_STIN1, STFLAG_FPUTC); set_status_table(STATUS_STACT, STATUS_STIN2, STFLAG_UNPUT); set_status_table(STATUS_STACT, STATUS_STINN, STFLAG_NOACT); set_status_table(STATUS_STACT, STATUS_STOU1, STFLAG_NOACT); set_status_table(STATUS_STACT, STATUS_STOU2, STFLAG_NOACT); } #define file_noact ((status_handler_t)0) typedef void (*status_handler_t)(char); static void file_putc(char c); static void file_unputc(char c); static void status_handler(char c) { const status_handler_t handler_a[] = { file_noact, file_putc, file_unputc }; int actidx = st(STATUS_STACT, status); status_handler_t handler = handler_a[actidx]; if (handler != NULL) handler(c); } static void show_status(char c); void comment(char *inpath, char *outpath) { char c; init_status(); fpin = fopen(inpath, "r"); fpout = fopen(outpath, "w"); assert(fpin && fpout != NULL); while ((c = fgetc(fpin)) != EOF) { show_status(c); if (c == '\r') continue; status = st(status, (int)c); status_handler(c); } } /////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// static char *c_str(char c, char *buf, int size) { if (c == ' ') return "_"; else if (c == '\t') return "\\t"; else if (c == '\n') return "\\n"; else if (c == '\r') return "\\r"; else if (c == '\0') return "\\0"; snprintf(buf, size, "%c", c); return buf; } #define RET_STATUS_STRING(s) \ if (status == (s)) return #s static char *status_str(void) { RET_STATUS_STRING(STATUS_OUTTE); RET_STATUS_STRING(STATUS_DOTTE); RET_STATUS_STRING(STATUS_STIN1); RET_STATUS_STRING(STATUS_STIN2); RET_STATUS_STRING(STATUS_STINN); RET_STATUS_STRING(STATUS_STOU1); RET_STATUS_STRING(STATUS_STOU2); return "invalid status"; } static void show_status(char c) { char t[4]; fprintf(stdout, ">>> %s, %s\n", status_str(), c_str(c, t, sizeof t)); } #define MAXLINE 128 static char linebuf[MAXLINE]; static char *lineptr = linebuf; static void init_line_buf(void) { memset(linebuf, 0, sizeof linebuf); lineptr = linebuf; } #define isblank(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') /* is writable */ static int is_wrt(void) { char c, *ptr = linebuf; for ( ; (c = *ptr); ptr++) { if (isblank(c) == 0) return 1; } return 0; } static void file_puts(void) { static int lines; /* empty lines */ if (is_wrt()) lines = 0; else lines++; if (lines > 1) return; int len = strlen(linebuf); fwrite(linebuf, len, 1, fpout); } static void file_putc(char c) { *lineptr++ = c; if (c == '\n') { file_puts(); init_line_buf(); } } static void file_unputc(char c) { *--lineptr = 0; }
/* main.c */ #include <assert.h> #include "comment.h" int main(int argc, char *argv[]) { assert(argc == 3); comment(argv[1], argv[2]); return 0; }
http://blog.csdn.net/geng823/article/details/41356193
設計
版權聲明:本文爲博主原創文章,未經博主容許不得轉載。code