【原创】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
版权声明:本文为博主原创文章,未经博主允许不得转载。

浙公网安备 33010602011771号