1 <!DOCTYPE HTML PUBLIC
"-//W3O//DTD W3 HTML 2.0//EN">
2 <!-- This collection of hypertext pages is Copyright 1995-7 by Steve Summit. -->
3 <!-- This material may be freely redistributed and used -->
4 <!-- but may not be republished or sold without permission. -->
7 <link rev=
"owner" href=
"mailto:scs@eskimo.com">
8 <link rev=
"made" href=
"mailto:scs@eskimo.com">
9 <title>Assignment #
6 Answers
</title>
12 <H1>Assignment #
6 Answers
</H1>
18 <B>Introductory C Programming
21 UW Experimental College
31 </TT>then what is
<TT>ip
</TT>?
33 </I><p><TT>ip
</TT> is a variable which can point to an
<TT>int
</TT>
34 (that is, its value will be a pointer to an
<TT>int
</TT>;
35 or informally, we say that
<TT>ip
</TT> <em>is
</em>
36 ``a pointer to an
<TT>int
</TT>'').
37 Its value is a pointer which points to the variable
<TT>i
</TT>.
39 <I>If ip is a pointer to an int, what does
<TT>ip++
</TT> mean?
43 </I><p><TT>ip++
</TT> means about the same as it does for any other variable:
46 as if we had written
<TT>ip = ip +
1</TT>.
48 the case of a pointer,
50 make it point to the object (the
<TT>int
</TT>)
51 one past the one it used to.
52 <TT>*ip++ =
0</TT> sets the
<TT>int
</TT> variable pointed to
54 and then increments
<TT>ip
</TT>
55 to point to the next
<TT>int
</TT>.
57 <I>How much memory does the call
<TT>malloc(
10)
</TT> allocate?
58 What if you want enough memory for
10 <TT>int
</TT>s?
59 </I><p><TT>malloc(
10)
</TT> allocates
10 bytes,
61 enough space for
10 <TT>char
</TT>s.
62 To allocate space for
10 <TT>int
</TT>s,
63 you could call
<TT>malloc(
10 * sizeof(int))
</TT>
66 <I>If
<TT>char
</TT> and
<TT>int
</TT> pointers are different,
67 how is it possible to write
69 char *cp = malloc(
10);
70 int *ip = malloc(sizeof(int));
72 <I>without error on either line?
73 </I><p><TT>malloc
</TT> is declared as returning the special,
74 ``generic'' pointer type
<TT>void *
</TT>,
77 automatically converted to different pointer types,
80 <I>Write a program to read lines
81 and print only those containing a certain word.
85 #include
<stdio.h
>
86 #include
<string.h
>
88 extern int getline(char [], int);
95 while(getline(line,
100) != EOF)
97 if(strstr(line, pat) != NULL)
104 <I>Rewrite the checkbook-balancing program
105 to use the
<TT>getwords
</TT> function
106 to make it easy to take the word ``check'' or ``deposit'',
107 and the amount, from a single line.
111 #include
<stdio.h
>
112 #include
<stdlib.h
> /* for atof() */
117 extern int getline(char [], int);
118 extern int getwords(char *, char *[], int);
122 double balance =
0.0;
124 char *words[MAXWORDS];
127 while (getline(line, MAXLINE)
> 0)
129 nwords = getwords(line, words, MAXWORDS);
131 if(nwords ==
0) /* blank line */
134 if(strcmp(words[
0],
"deposit") ==
0)
138 printf(
"missing amount\n");
141 balance += atof(words[
1]);
143 else if(strcmp(words[
0],
"check") ==
0)
147 printf(
"missing amount\n");
150 balance -= atof(words[
1]);
153 printf(
"bad data line: \"%s\
"\n", words[
0]);
157 printf(
"balance: %.2f\n", balance);
163 <I>Rewrite the line-reversing function to use pointers.
164 </I><p>Here is one way:
166 int reverse(char *string)
168 char *lp = string; /* left pointer */
169 char *rp =
&string[strlen(string)-
1]; /* right pointer */
183 <I>Rewrite the character-counting function to use pointers.
187 int countnchars(char *string, int ch)
191 for(p = string; *p != '\
0'; p++)
200 <I>Rewrite the string concatenation program
201 to call
<TT>malloc
</TT> to allocate memory
202 for the concatenated result.
204 #include
<stdio.h
>
205 #include
<stdlib.h
> /* for malloc */
206 #include
<string.h
> /* for strcpy and strcat */
210 extern int getline(char [], int);
214 char string1[MAXLINE], string2[MAXLINE];
218 printf(
"enter first string:\n");
219 len1 = getline(string1,
100);
220 printf(
"enter second string:\n");
221 len2 = getline(string2,
100);
223 if(len1 == EOF || len2 == EOF)
226 newstring = malloc(len1 + len2 +
1); /* +
1 for \
0 */
228 if(newstring == NULL)
230 printf(
"out of memory\n");
234 strcpy(newstring, string1);
235 strcat(newstring, string2);
237 printf(
"%s\n", newstring);
242 <I>Rewrite the string-replacing function to use pointers.
243 </I><p>Here is one way:
245 void replace(char string[], char *from, char *to)
247 char *start, *p1, *p2;
248 for(start = string; *start != '\
0'; start++)
261 for(p1 = to; *p1 != '\
0'; p1++)
268 The bulk of this code is a copy of
269 the
<TT>mystrstr
</TT>
271 in the notes, chapter
10, section
10.4, p.
8.
272 (Since
<TT>strstr
</TT>'s job is to find one string within
273 another, it's a natural for the first half of
<TT>replace
</TT>.)
274 We could also call
<TT>strstr
</TT> directly, simplifying
<TT>replace
</TT>:
276 #include
<string.h
>
278 void replace(char string[], char *from, char *to)
281 char *start = strstr(string, from);
284 for(p1 = to; *p1 != '\
0'; p1++)
291 we might wonder about the case when the string to be
292 edited contains multiple occurrences of the
<TT>from
</TT> string,
293 and ask whether
<TT>replace
</TT> should replace the first one,
295 The problem statement didn't make this detail clear.
297 two implementations have
298 replaced only the first occurrence.
299 It happens, though, that it's trivial to rewrite our first version
300 to make it replace all occurrences--just omit the
301 <TT>return
</TT> after the first string has been replaced:
303 void replace(char string[], char *from, char *to)
305 char *start, *p1, *p2;
306 for(start = string; *start != '\
0'; start++)
319 for(p1 = to; *p1 != '\
0'; p1++)
325 Rewriting the second version wouldn't be much harder.
327 <I>Write a program to read lines of text up to EOF,
328 and then print them out in reverse order.
329 </I><p>One of the reasons this program is harder
330 is that it uses pointers to pointers.
331 When we used pointers to simulate an array of integers,
332 we used pointers to integers.
333 In this program, we want to simulate an array of strings,
334 or an array of pointers to characters.
335 Therefore, we use
<em>pointers
</em> to pointers to characters,
338 #include
<stdio.h
>
339 #include
<stdlib.h
>
341 extern int getline(char [], int);
353 lines = malloc(nalloc * sizeof(char *));
356 printf(
"out of memory\n");
362 while(getline(line, MAXLINE) != EOF)
364 if(nitems
>= nalloc)
368 newp = realloc(lines, nalloc * sizeof(char *));
371 printf(
"out of memory\n");
377 lines[nitems] = malloc(strlen(line) +
1);
378 strcpy(lines[nitems], line);
382 for(i = nitems -
1; i
>=
0; i--)
383 printf(
"%s\n", lines[i]);
388 Notice that for each line we read,
389 we call
<TT>malloc
</TT> to allocate space for a copy of it,
390 and then use
<TT>strcpy
</TT> to make the copy.
391 We could not simply set
393 lines[nitems++] = line;
396 because
<TT>line
</TT> is a single array,
397 which can only hold one line,
398 and it gets overwritten with the contents of each input line.
400 if we didn't call
<TT>malloc
</TT> and make a copy,
401 we'd end up at the end with only the last line.
402 You might try it to see what happens.)
404 remove the restriction imposed by the fixed-size array;
405 allow the program to accept
406 arbitrarily-long lines.
407 </I><p>First we will write another version of
<TT>getline
</TT>,
408 called
<TT>mgetline
</TT>.
409 <TT>mgetline
</TT> calls
<TT>malloc
</TT> and
<TT>realloc
</TT>
410 to get enough memory for the line it's currently reading,
411 regardless of how long that line is.
412 <TT>mgetline
</TT> returns a pointer to the allocated memory;
414 the caller does not have to pass an array for
415 <TT>mgetline
</TT> to read into.
416 (It will be the caller's responsibility to
<TT>free
</TT> the
417 memory when it doesn't need the line of text any more.)
419 #include
<stdio.h
>
420 #include
<stdlib.h
>
429 line = malloc(nalloc +
1);
432 printf(
"out of memory\n");
436 while((c = getchar()) != EOF)
445 newp = realloc(line, nalloc +
1);
448 printf(
"out of memory\n");
456 if(c == EOF
&& nch ==
0)
467 Now we can rewrite the line-reversing program to call
<TT>mgetline
</TT>.
468 Note that we no longer need the local
<TT>line
</TT> array.
469 Instead, we use a pointer,
<TT>linep
</TT>,
470 which holds the return value from
<TT>mgetline
</TT>.
471 Since
<TT>mgetline
</TT> returns a new pointer to a new block
472 of memory each time we call it,
474 (unlike the previous one)
477 lines[nitems++] = linep;
479 without overwriting anything.
481 #include
<stdio.h
>
482 #include
<stdlib.h
>
484 extern char *mgetline();
494 lines = malloc(nalloc * sizeof(char *));
497 printf(
"out of memory\n");
503 while((linep = mgetline()) != NULL)
505 if(nitems
>= nalloc)
509 newp = realloc(lines, nalloc * sizeof(char *));
512 printf(
"out of memory\n");
518 lines[nitems++] = linep;
521 for(i = nitems -
1; i
>=
0; i--)
522 printf(
"%s\n", lines[i]);
530 This page by
<a href=
"http://www.eskimo.com/~scs/">Steve Summit
</a>
531 //
<a href=
"copyright.html">Copyright
</a> 1995-
9
532 //
<a href=
"mailto:scs@eskimo.com">mail feedback
</a>