*********/
#include
#include
#include
#define MAXWORD 10 /* * 定义结构体类型 key * 该类型结构体中存储一个 字符串(关键字) 和 int 数据(关键字出现次数) * 同时声明一个结构体数组 * 对结构体数组进行初始化 * * */ struct key { char *word; int count; }key_count[] = { auto, 0, break, 0, case, 0, char, 0, const, 0, continue, 0, default, 0, void, 0, volatitle, 0, while, 0 }; int main(int argc, char **argv) { int n; char word[MAXWORD]; /*循环接收字符串, 如果字符串与结构体数组中匹配, 结构体的count ++*/ while(getword(word, MAXWORD) != EOF) if(isalpha(word[0])) if((n = binsearch(word, key_count, 10)) >= 0) key_count[n].count++; /*打印大于0的关键字 及 个数*/ for (n = 0; n < 10; n ++) if(key_count[n].count > 0) printf(%2d %s , key_count[n].count, key_count[n].word); return 0; } /* * 重要api解析 : * int getc(FILE *stream) 从标准输入流中读取字符 * int ungetc(int c, FILE *stream) 将字符退回到标准输入流中 * int isspace(int c) 判断字符是否是 空格 ' ' ' ' ' ' ' ' '' * int isalpha(int c) 判断是否是字母 */ int getword(char *word, int lim) { int c, getc(FILE*), ungetc(int, FILE*); char *wp = word; /*过滤空格, 如果输入的不是 空, 就继续向下执行*/ while(isspace(c = getc(stdin))); /*如果输入的不是结束符, 那么 wp指针, 先取值, 之后地址自增*/ if(c != EOF) *wp++ = c; /*如果输入的不是字母, 直接返回, 关键字里面没有数字开头的*/ if(!isalpha(c)) { *wp = ''; return c; } /* * 循环条件 a. 接收的最大字符个数 lim, 每读取一个字符, 该变量自减 * 当该变量自减为0时停止循环接收字符串 * 循环条件 b. 当读取到的字符 不是 字母 或者数字的时候, 停止循环 */ for(; --lim > 0; wp++) { if(!isalnum(*wp = getc(stdin))) { ungetc(*wp, stdin); break; } } *wp = ''; return word[0]; } /* * 参数解析 : word 是要查找的字符串 tab 字符串数组 n 字符串大小 */ int binsearch(char *word, struct key tab[], int n) { /* * cond 判断 查找的字符串 是在mid 坐标之前 (<0) 之后(>0) 或者就是mid坐标 * * 如果查找的不是正好中间的变量符合, 就返回 -1 失败 */ int cond, low, high, mid; low = 0; high = n - 1; /* * 要找的值的下标在low 和 high之间 * mid 是 low 和 high 的中值 * 如果 word 小于中值下标 将比较范围 缩小 */ while(low <= high) { mid = (low + high) / 2; if((cond = strcmp(word, tab[mid].word)) < 0) high = mid - 1; else if(cond > 0) low = mid + 1; else return mid; } return -1; }
执行结果 :
[root@ip28 struct]# gcc word_count.c
[root@ip28 struct]# ./a.out
auto
break
break
char
1 auto
2 break
1 char
宏定义方法 : 获取结构体数组大小;
-- sizeof 方法 : sizeof (对象) | sizeof (类型名称) 可以获取对象 或者 类型占用的存储空间, 其返回值是 size_t 类型的, 定义在stddef.h 头文件中;
-- 使用类型测量 :
#define KEYS (sizeof(key_count) / sizeof(struct key))
--
使用对象测量 :
#define KEYS (sizeof(key_count) / sizeof(struct key_count[0])
4. 指向结构体指针
(1) 使用指针方式实现上面的关键字统计程序
使用指针进行二分查找 :
-- 使用下标找中值 : 在之前找中值时通过 mid = (low + high)方法, 这样做可行是因为 low 从0开始的;
-- 如果是指针情况 : mid low high 都是指针, 那么就不能使用上面的那种方法了, 使用 mid = low + (high - low) / 2;.
-- 指针操作情况的 high 和 low : 其中 low 是首元素的 首地址, high 是 尾元素的尾地址, 只有这样 它们的差的 0.5 倍才是准确的中值的首地址;
指针指向数组注意点 : 不要生成非法的指针, 指针不能指向数组之外的元素;
-- &key_count[-1] : 这个指针时非法的;
-- &key_count[n] : 对数组的最后一个元素后面的第一个元素进行 & 运算时合法的, 其它操作都是非法的;
示例程序 :
/*************************************************************************
> File Name: pointer_struct.c
> Author: octopus
> Mail: octopus_work.163.com
> Created Time: Tue 25 Mar 2014 12:31:08 AM CST
************************************************************************/
#include
#include
#include
#define MAXWORD 20 /*计算结构体数组的大小*/ #define KEYS (int)(sizeof(key_count) / sizeof(struct key)) struct key { char *word; int count; } key_count[] = { auto, 0, break, 0, case, 0, char, 0, const, 0 }; int getword(char *, int); struct key *binsearch(char*, struct key*, int); int main(int argc, char **argv) { char word[MAXWORD]; struct key *p; /*存放查找方法返回的结构体指针, 该指针指向数组中查找到元素的下标*/ while(getword(word, MAXWORD) != EOF) if(isalpha(word[0])) if((p = binsearch(word, key_count, KEYS)) != NULL) p->count++; for(p = key_count; p < key_count + KEYS; p++) if(p->count > 0) printf(%2d %s , p->count, p->word); return 0; } /* * 没有循环控制变量的 for 循环, 在内部通过条件 break */ int getword(char *word, int max) { int c, getc(