【原創】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型。spa



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 /* 將上一個字符退出   */
完整實現以下
.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

相關文章
相關標籤/搜索