Skip to content

Commit 5728c0d

Browse files
committed
Add the epilogue sample code
1 parent 313121f commit 5728c0d

File tree

8 files changed

+958
-0
lines changed

8 files changed

+958
-0
lines changed

code/index.php

+37
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ function chapter_title($pageno) {
7575
<li class="active"><a href="#krbook" data-toggle="tab" aria-expanded="true">K&R Textbook Code</a></li>
7676
<li><a href="#chapter" data-toggle="tab" aria-expanded="false">K&R Lecture Code</a></li>
7777
<li><a href="#lectures" data-toggle="tab" aria-expanded="false">CC4E Lecture Code</a></li>
78+
<li><a href="#epilogue" data-toggle="tab" aria-expanded="false">Epilogue Code</a></li>
7879
</ul>
7980
<div id="myTabContent" class="tab-content" style="margin-top:10px;">
8081
<div class="tab-pane fade active in" id="krbook">
@@ -274,6 +275,42 @@ function chapter_title($pageno) {
274275
}
275276
?>
276277

278+
</div>
279+
<div class="tab-pane fade" id="epilogue">
280+
<p>
281+
This page contains the sample code from the "C Programming
282+
for Everybody" extra topics by Dr. Chuck.
283+
</p>
284+
<?php
285+
286+
$chapter = 0;
287+
$files = scandir("../epilogue/");
288+
289+
$chap_title = "Catch Phrase";
290+
// echo("<pre>\n"); var_dump($files); echo("</pre>\n");
291+
292+
echo("<ul>\n");
293+
294+
$inchapter = false;
295+
foreach($files as $file ) {
296+
$text = @file_get_contents("../epilogue/".$file);
297+
if ( strlen($text) < 1 ) continue;
298+
$id = str_replace(".", "_", $file);
299+
300+
echo("<li>\n");
301+
echo(htmlentities($file));
302+
?>
303+
<button style="margin:0.5em;" onclick="myToggle('<?= $id ?>');return false;" id="toggle_<?= $id ?>" >Show</button>
304+
<button style="margin:0.5em;" onclick="myCopy('<?= $id ?>');return false;">Copy</button>
305+
<pre class="code" id="pre_<?= $id ?>" style="display:none;"><code class="language-c" id="<?= $id ?>"><?php
306+
echo(htmlentities($text));
307+
?></code></pre>
308+
</li>
309+
<?php
310+
echo("</li>\n");
311+
}
312+
echo("</ul>\n"); // End of the files
313+
?>
277314
</div>
278315
</div>
279316
<?php

epilogue/p1dict.c

+193
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
5+
struct dnode {
6+
char *key;
7+
char *value;
8+
};
9+
10+
struct p1dict {
11+
int alloc;
12+
int length;
13+
struct dnode *items;
14+
};
15+
16+
int getBucket(char *str, int buckets)
17+
{
18+
unsigned int hash = 123456;
19+
if ( str == NULL ) return 0;
20+
for( ; *str ; str++) {
21+
hash = ( hash << 3 ) ^ *str;
22+
}
23+
return hash % buckets;
24+
}
25+
26+
/* Constructor - dct = dict() */
27+
struct p1dict * p1dict_new() {
28+
int i;
29+
struct p1dict *p = malloc(sizeof(*p));
30+
p->length = 0;
31+
p->alloc = 2;
32+
p->items = malloc(p->alloc * sizeof(struct dnode));
33+
for(i=0; i < p->alloc; i++) {
34+
p->items[i].key = NULL;
35+
p->items[i].value = NULL;
36+
}
37+
return p;
38+
}
39+
40+
/* Destructor - del(dct) */
41+
void p1dict_del(struct p1dict* self) {
42+
int i;
43+
for(i=0; i < self->alloc; i++) {
44+
if ( self->items[i].key != NULL ) free(self->items[i].key);
45+
if ( self->items[i].value != NULL ) free(self->items[i].value);
46+
}
47+
free((void *) self->items);
48+
free((void *) self);
49+
}
50+
51+
/* print(dct) */
52+
/* {'z': 'W', 'y': 'B', 'c': 'C', 'a': 'D'} */
53+
void p1dict_print(struct p1dict* self)
54+
{
55+
int first = 1;
56+
int i;
57+
printf("{");
58+
for(i=0; i < self->alloc; i++) {
59+
if ( self->items[i].key == NULL ) continue;
60+
if ( ! first ) printf(", ");
61+
printf("'%s': ", self->items[i].key);
62+
printf("'%s'", self->items[i].value);
63+
first = 0;
64+
printf(" [%d]", i);
65+
}
66+
printf("} [%d, %d]\n", self->length, self->alloc);
67+
}
68+
69+
int p1dict_len(const struct p1dict* self)
70+
{
71+
return self->length;
72+
}
73+
74+
/* find a node - used in get and put */
75+
struct dnode *p1dict_find(struct p1dict* self, char *key)
76+
{
77+
int i, bucket, offset;
78+
if ( key == NULL ) return NULL;
79+
bucket = getBucket(key, self->alloc);
80+
for(offset=0; offset < self->alloc; offset++) {
81+
i = (offset + bucket) % self->alloc;
82+
if ( self->items[i].key == NULL ) {
83+
return &(self->items[i]);
84+
}
85+
if(strcmp(key, self->items[i].key) == 0 ) {
86+
return &(self->items[i]);
87+
}
88+
}
89+
90+
/* This should never happen as long as the resize is implemented */
91+
92+
printf("Could not find slot for key %s\n", key);
93+
return NULL;
94+
}
95+
96+
/* x.get(key) - Returns NULL if not found */
97+
char* p1dict_get(struct p1dict* self, char *key)
98+
{
99+
struct dnode *retval = p1dict_find(self, key);
100+
if ( retval == NULL || retval->key == NULL ) return NULL;
101+
return retval->value;
102+
}
103+
104+
/* x[key] = value; Insert or replace the value associated with a key */
105+
void p1dict_put(struct p1dict* self, char *key, char *value) {
106+
107+
int i, old_alloc, bucket;
108+
struct dnode *old, *new_item, *old_items;
109+
110+
if ( key == NULL || value == NULL ) return;
111+
112+
/* First look up */
113+
old = p1dict_find(self, key);
114+
if ( old != NULL && old->key != NULL ) {
115+
free(old->value);
116+
old->value = malloc(strlen(value)+1);
117+
strcpy(old->value, value);
118+
return;
119+
}
120+
121+
/* TODO: Check if we need to re-hash the items */
122+
if ( self->length >= (self->alloc*0.7) ) {
123+
printf("We are making space for %s\n", key);
124+
old_alloc = self->alloc;
125+
old_items = self->items;
126+
127+
/* make new "empty items" */
128+
self->alloc = self->alloc * 2;
129+
self->items = malloc(self->alloc * sizeof(struct dnode));
130+
for(i=0; i < self->alloc; i++) {
131+
self->items[i].key = NULL;
132+
self->items[i].value = NULL;
133+
}
134+
135+
/* We need to loop through old items and add them */
136+
for(i=0; i<old_alloc; i++) {
137+
if ( old_items[i].key == NULL ) continue;
138+
new_item = p1dict_find(self, old_items[i].key);
139+
if ( new_item == NULL || new_item->key != NULL ) {
140+
printf("Very bad news new_item=%p\n", new_item);
141+
}
142+
new_item->key = old_items[i].key;
143+
new_item->value = old_items[i].value;
144+
}
145+
free(old_items);
146+
old = p1dict_find(self, key);
147+
if ( old == NULL || old->key != NULL ) {
148+
printf("Very very bad news!!!!\n");
149+
}
150+
}
151+
152+
/* Not found - time to insert */
153+
old->value = malloc(strlen(value)+1);
154+
strcpy(old->value, value);
155+
old->key = malloc(strlen(key)+1);
156+
strcpy(old->key, key);
157+
158+
self->length++;
159+
}
160+
161+
int main(void)
162+
{
163+
struct dnode * cur;
164+
struct p1dict * dct = p1dict_new();
165+
p1dict_print(dct);
166+
p1dict_put(dct, "z", "Catch phrase");
167+
p1dict_print(dct);
168+
p1dict_put(dct, "z", "W");
169+
p1dict_print(dct);
170+
p1dict_put(dct, "SAKAI", "B");
171+
p1dict_print(dct);
172+
p1dict_put(dct, "sally", "C");
173+
p1dict_print(dct);
174+
p1dict_put(dct, "a", "D");
175+
p1dict_print(dct);
176+
printf("Length=%d\n",p1dict_len(dct));
177+
178+
printf("z=%s\n", p1dict_get(dct, "z"));
179+
printf("x=%s\n", p1dict_get(dct, "x"));
180+
181+
/*
182+
printf("\nDump\n");
183+
for(cur = dct->head; cur != NULL ; cur = cur->next ) {
184+
printf("%s=%s\n", cur.key, cur.value);
185+
}
186+
*/
187+
188+
p1dict_del(dct);
189+
}
190+
191+
// rm -f a.out ; gcc p1dict.c; a.out ; rm -f a.out
192+
193+

epilogue/p1list.c

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
5+
struct p1list {
6+
int alloc;
7+
int length;
8+
char **items;
9+
};
10+
11+
/* Constructor - lst = list() */
12+
struct p1list * p1list_new() {
13+
struct p1list *p = malloc(sizeof(*p));
14+
p->length = 0;
15+
p->alloc = 2;
16+
p->items = malloc(p->alloc * sizeof(char *));
17+
return p;
18+
}
19+
20+
/* Destructor - del(lst) */
21+
void p1list_del(struct p1list* self) {
22+
int i;
23+
for(i=0; i< self->length; i++ ) {
24+
free(self->items[i]);
25+
}
26+
free((void *)self->items);
27+
free((void *)self);
28+
}
29+
30+
/* print(lst) */
31+
void p1list_print(struct p1list* self)
32+
{
33+
int i;
34+
int first = 1;
35+
printf("[");
36+
for(i=0; i< self->length; i++ ) {
37+
if ( ! first ) printf(", ");
38+
printf("'%s'", self->items[i]);
39+
first = 0;
40+
}
41+
printf("]\n");
42+
}
43+
44+
/* len(lst) */
45+
int p1list_len(const struct p1list* self)
46+
{
47+
return self->length;
48+
}
49+
50+
/* lst.append("Hello world") */
51+
void p1list_append(struct p1list* self, char *str) {
52+
53+
// Extend if necessary
54+
if ( self->length >= self->alloc ) {
55+
printf("Extending from %d to %d\n", self->alloc, self->alloc + 10);
56+
self->alloc = self->alloc + 10;
57+
self->items = (char **) realloc(self->items, (self->alloc * sizeof(char *)));
58+
}
59+
60+
char *saved = malloc(strlen(str)+1);
61+
strcpy(saved, str);
62+
self->items[self->length] = saved;
63+
self->length++;
64+
}
65+
66+
/* lst.index("Hello world") - if not found -1 */
67+
int p1list_index(struct p1list* self, char *str)
68+
{
69+
int i;
70+
if ( str == NULL ) return -1;
71+
for(i=0; i< self->length; i++ ) {
72+
if ( strcmp(str, self->items[i]) == 0 ) return i;
73+
}
74+
return -1;
75+
}
76+
77+
int main(void)
78+
{
79+
struct p1list * lst = p1list_new();
80+
p1list_append(lst, "Hello world");
81+
p1list_print(lst);
82+
p1list_append(lst, "Catch phrase");
83+
p1list_print(lst);
84+
p1list_append(lst, "Brian");
85+
p1list_print(lst);
86+
printf("Length=%d\n", p1list_len(lst));
87+
printf("Brian? %d\n", p1list_index(lst, "Brian"));
88+
printf("Bob? %d\n", p1list_index(lst, "Bob"));
89+
p1list_del(lst);
90+
}
91+
92+
// rm -f a.out ; gcc p1list.c; a.out ; rm -f a.out
93+

0 commit comments

Comments
 (0)