【原创】C程序设计语言(2版KR) - C语言基础知识(2) 分类: Linux --- C 2014-11-21 19:21 85人阅读 评论(0) 收藏
【原创】C程序设计语言(2版KR) - C语言基础知识(2)
5. 数组
教材答案:
/************************************************************************* > 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; }
6. 函数
函数的默认返回类型为int型。
int power(int, int);
7. 参数--传值调用
8. 字符数组
9. 外部变量与作用域
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 /* 将上一个字符退出 */
完整实现如下
/* 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
版权声明:本文为博主原创文章,未经博主允许不得转载。