统计关键字出现的次数(结构数组&指向结构的指针)

前言

学习K&RC语言中的一些例子和问题。
该实例为编写一个程序,用来统计输出中各个C语言关键字出现的次数。用了一个字符串数组存放关键名,一个整型数组存放相应的关键字。书中用到结构数组以及变式为指向结构的指针。
引入概念:结构数组,数组内的每个元素都是一个结构。
例如

struct key{
char *word;
int count;
}keytab [NKEYS];

正文

结构数组

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAXWORD 100
#define NKEYS ( sizeof keytab / sizeof(struct key))/* 关键字个数等于数组长度除以单个元素的长度*/
#define NUMBER '0'
#define BUFSIZE 100
//关键字列表必须升序排列(和折半查找有关)
struct key {
    char *word;
    int count;
} keytab[] ={
    "auto", 0,
    "break", 0,
    "case", 0,
    "char", 0,
    "const", 0,
    "continue", 0,
    "default", 0,
    "main", 0,
    "unsigned", 0,
    "void", 0,
    "volatile", 0,
    "while", 0,
};
/* getword函数:从输入中读取下一个单词或字符*/
int getword(char *word, int lim){
    int c, getch(void);
    void ungetch(int);
    char *w = word;
    
    while (isspace(c = getch()))
        ;
    if (c != EOF)
        *w++ = c;
    if (!isalpha(c)) {
        *w = '\0';
        return c;
    }
    for ( ; --lim > 0; w++)
        if (!isalnum(*w = getch())){
            ungetch(*w);/**/ 
            break;
        }
    *w = '\0';
    return word[0];
} 
char buf[BUFSIZE]; /* buffer for ungetch */
int bufp = 0; /* next free position in buf */

int getch(void) /* get a (possibly pushed-back) character */
{
    return (bufp > 0) ? buf[--bufp] : getchar();
}
void ungetch(int c) /* push character back on input */
{
    if (bufp >= BUFSIZE)
        printf("ungetch: too many characters\n");
    else
        buf[bufp++] = c;
}
//通过折半查找在Keytab中进行查找
int binsearch(char *word, struct key tab[], int n){
    int cond;
    int low, high, mid;
    
    low = 0;
    high = n - 1;
    while (low <= high){
        mid = (high+low) / 2;
        if ((cond = strcmp(word, tab[mid].word)) < 0)//strcmp 按顺序对参数ASCII码进行比较大小
            high = mid - 1;
        else if (cond > 0)
            low = mid + 1;
        else    /*找到了匹配的值*/
            return mid; 
    }
    return -1;  /*没有匹配的值*/
}
/*统计输入中c语言关键字的出现次数*/
main(){
    int n;
    char word[MAXWORD];
    printf("请输入关键字如:%s %s %s", keytab[0].word, keytab[1].word, keytab[2].word);
    while (getword(word,MAXWORD) != EOF)/*因为EOF而不易调试*/
        if (isalpha(word[0]))
            if ((n = binsearch(word, keytab, NKEYS)) >= 0)
                keytab[n].count++;
    for (n = 0; n < NKEYS; n++)
        if (keytab[n].count > 0)
            printf("%4d %s\n",
                keytab[n].count, keytab[n].word);
    return 0;
} 

有关getch 和ungetch 函数,书中第一次提到是在“逆波兰计算器”程序中,一直没大弄明白,贴一个有详细解释的,供参考。
https://www.cnblogs.com/roma823/archive/2011/06/08/2101262.html

指向结构的指针

//通过折半查找在Keytab中进行查找
struct key *binsearch(char *word, struct key *tab, int n){
    int cond;
    struct key *low=&tab[0];
    struct key *high=&tab[n];
    struct key *mid;
    while (low <= high){
        mid =low+(high-low) / 2;
        if ((cond = strcmp(word, mid->word)) < 0)//strcmp 按顺序对参数ASCII码进行比较大小
            high = mid;
        else if (cond > 0)
            low = mid + 1;
        else    /*找到了匹配的值*/
            return mid; 
    }
    return NULL;  /*没有匹配的值*/
}
/*统计输入中c语言关键字的出现次数*/
main(){
    int n;
    char word[MAXWORD];
    struct key *p;//用来接收返回的binsearch指针,也要命为结构类型。
    printf("请输入关键字如:%s %s %s", keytab[0].word, keytab[1].word, keytab[2].word);
    while (getword(word,MAXWORD) != EOF)/*因为EOF而不易调试*/
        if (isalpha(word[0]))
            if ((p = binsearch(word, keytab, NKEYS)) >= 0)
                p->count++;
    for (p = keytab; p < keytab+NKEYS; p++)
        if (p->count > 0)
            printf("%4d %s\n",p->count, p->word);
    return 0;
} 

注意
binsearch函数声明中必须标明它返回的值类型是一个指向struct key类型的指针,非整型!!!
两个指针只能相减不能相加!!!故原式中mid=(low+high)/2要改为mid=low+(high-low)/2

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值