对The C programming language一书第6.6节代码的理解
代码如下(基本与书中一致)
1 #include <stdio.h>
2 #include <string.h>
3 #include <ctype.h>
4 #include <stdlib.h>
5
6 #define HASHSIZE 101
7
8 struct nlist{
9 struct nlist *next;
10 char *name;
11 char *defn;
12 };
13
14 static struct nlist *hashtab[HASHSIZE];
15 struct nlist *lookup(char *s);
16 struct nlist *install(char *name,char *defn);
17
18 int main(int argc, const char * argv[]) {
19 struct nlist list[] = {
20 {NULL,"abc","123"},
21 {NULL,"bcd","234"},
22 {NULL,"cde","345"},
23 {NULL,"def","567"},
24 };
25 int count = sizeof(list)/sizeof(struct nlist);
26 for (int i = 0; i< count; i++) {
27 struct nlist * p = install(list[i].name, list[i].defn);
28 if (p) {
29 printf("将%s添加到了哈希表里,值为%s\n",p->name,p->defn);
30 }
31 }
32 struct nlist *p = lookup("bcd");
33 if (p) {
34 printf("找到key为bcd时对应的值,值为%s\n",p->defn);
35 }else{
36 printf("没有找到key为bcd时对应的值\n");
37 }
38 return 0;
39 }
40
41 unsigned hash(char *s)
42 {
43 unsigned hashval;
44 for (hashval = 0; *s!='\0'; s++) {
45 hashval = *s+31*hashval;
46 }
47 return hashval%HASHSIZE;
48 }
49
50 struct nlist *lookup(char *s)
51 {
52 struct nlist *np;
53 for (np = hashtab[hash(s)]; np!=NULL; np = np->next) {
54 if (strcmp(s, np->name) == 0) {
55 return np;
56 }
57 }
58 return NULL;
59 }
60
61 char *strsave(char *s)
62 {
63 char *p;
64 p = (char*)malloc(strlen(s)+1);
65 if (p!=NULL) {
66 strcpy(p, s);
67 }
68 return p;
69 }
70
71 struct nlist *install(char *name,char *defn)
72 {
73 struct nlist *np;
74 unsigned hashval;
75 if ((np=lookup(name))==NULL) {
76 np = (struct nlist*)malloc(sizeof(struct nlist));
77 if (np == NULL||(np->name = strsave(name))==NULL) {
78 return NULL;
79 }
80 hashval = hash(name);
81 np->next = hashtab[hashval];
82 hashtab[hashval] = np;
83 }else{
84 free((void*)np->defn);
85 }
86 if ((np->defn = strsave(defn))==NULL) {
87 return NULL;
88 }
89 return np;
90 }
先看下输出:

这一节就是讲了表查找,别的没啥想说的,主要看的时候卡在了install方法的这两句代码:
np->next = hashtab[hashval];
hashtab[hashval] = np;
其实这么做的原因是链表是从后向前添加的,当第一次执行install方法时,hashtab[hashval]这个值是NULL,也就是将np->next的值设为了NULL,然后hashtab[hashval] = np 这样,
当第二次执行到np->next = hashtab[hashval]时就是将第一次执行的那个节点添加到了这个节点的next上,换句话说,第一次执行install方法添加的节点是链表的最后一个节点,然后依次向前添加。
对The C programming language一书第6.6节代码的理解的更多相关文章
- The Swift Programming Language 中文翻译版(个人翻新随时跟新)
The Swift Programming Language --lkvt 本人在2014年6月3日(北京时间)凌晨起来通过网络观看2014年WWDC 苹果公司的发布会有iOS8以及OS X 10.1 ...
- [iOS翻译]《The Swift Programming Language》系列:Welcome to Swift-01
注:CocoaChina翻译小组已着手此书及相关资料的翻译,楼主也加入了,多人协作后的完整译本将很快让大家看到. 翻译群:291864979,想加入的同学请进此群哦.(本系列不再更新,但协作翻译的进度 ...
- the C programming language 阅读笔记1
读了一遍著名的<the C programming language>,果然如听说的一样,讲解基础透彻,案例简单典型,确实自己C语言还有很多细节点不是很清楚. 总结一下阅读的收获(部分原书 ...
- 不忘初心 --- 重读<<The C Programming Language>>
这篇文章应该发布在好几年前,2011年计算机界大师Dennis Ritchie仙逝,那时对大师的映象还停留在大一刚学编程时:Unix的合作开发者,C语言的发明人.通过网上的纪念文章<<Un ...
- The D Programming Language 书评
此书的作者 Andrei Alexandrescu 作为前 C++ 社区的一朵奇葩,因为实在是不满 C++ 标准委员会的官僚作风,跳槽到了 D 社区,成为了 D 发明人 Walt Brightman ...
- 《The C Programming Language》读书笔记(一)
1. 对这本书的印象 2011年进入大学本科,C语言入门书籍如果我没记错的话应该是谭浩强的<C程序设计>,而用现在的眼光来看,这本书只能算是一本可用的教材,并不能说是一本好书.在自学操作系 ...
- 转:从《The C Programming Language》中学到的那些编程风格和设计思想
这儿有一篇写的很好的读后感:http://www.cnblogs.com/xkfz007/articles/2566424.html 读书不是目的,关键在于思考. 很早就在水木上看到有人推荐& ...
- iOS Swift-元组tuples(The Swift Programming Language)
iOS Swift-元组tuples(The Swift Programming Language) 什么是元组? 元组(tuples)是把多个值组合成一个复合值,元组内的值可以使任意类型,并不要求是 ...
- iOS Swift-控制流(The Swift Programming Language)
iOS Swift-控制流(The Swift Programming Language) for-in 在Swift中for循环我们可以省略传统oc笨拙的条件和循环变量的括号,但是语句体的大括号使我 ...
随机推荐
- 【HTML】canvas学习小结
1. 绘制基本图形 -----上下文---------------------------------------------------------- canvas.getContext('2d') ...
- echarts_部分图表配置简介_横向柱状图
横向柱状图主要配置x位置x轴类型y轴类型(轴的类型分两种 1.category(类别)2.value(值)),代码简单(里面有注释)效果如下: var myChart = echarts.init(d ...
- Redux源码分析之基本概念
Redux源码分析之基本概念 Redux源码分析之createStore Redux源码分析之bindActionCreators Redux源码分析之combineReducers Redux源码分 ...
- C#设计模式(1)-单例模式
单例(Singleton)模式介绍 单例模式:也可以叫单件模式,官方定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一 ...
- Protocol Buffers与FlatBuffers效率对比
Protocol Buffers是Google跨语言.跨平台的通用序列化库.FlatBuffers同样出自Google,而且也跨语言跨平台,但更强调效率,专门为游戏开发打造.在游戏界混了几年,各种各样 ...
- Python 文件的处理
简单的读取文件 f.read() 是读取这个文件的所有内容 f.readline() 是读取文件的一行 .write() 会去检查这个文件是否存在,不存在则创建,存在的话,则以覆盖的方式将内容写 ...
- 由.Net类库提供的农历计算
由.Net类库提供的农历计算(C#农历) 2007-11-21 12:47:00 标签:.Net 类库 农历计算 C#农历 休闲 ...
- Open-Falcon第五步安装Query(小米开源互联网企业级监控系统)
安装Query query组件,绘图数据的查询接口,query组件收到用户的查询请求后,会从后端的多个graph,查询相应的数据,聚合后,再返回给用户. cd /usr/local/open-falc ...
- vue.js之组件(上篇)
本文的Demo和源代码已放到GitHub,如果您觉得本篇内容不错,请点个赞,或在GitHub上加个星星! https://github.com/zwl-jasmine95/Vue_test 以下所有知 ...
- mac corntab定期执行任务
mac corntab定期执行任务 crontab中的每一行代表一个定期执行的任务,分为6个部分.前5个部分表示何时执行命令,最后一个部分表示执行的命令.每个部分以空格分隔,除了最后一个部分(命令)可 ...