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 #
5 Answers
</title>
12 <H1>Assignment #
5 Answers
</H1>
18 <B>Introductory C Programming
21 UW Experimental College
31 </I><p>The semicolon at the end of the line
32 will become part of
<TT>N
</TT>'s definition,
33 which is hardly ever what you want.
35 <I>Suppose you had the definition
38 What value would the declaration
40 </TT>initialize
<TT>x
</TT> to?
44 It sure looks like it should be
2, doesn't it?)
45 <p>The preprocessor performs a simple textual substitution;
46 it knows nothing about operator precedence,
47 or even much about the syntax of C.
48 After the preprocessor substitutes the value of the macro
50 the declaration looks like
54 Since multiplication and division ``group''
57 this is interpreted as
61 To guard against these ``surprises,''
62 it's a very good idea to parenthesize the values of macros which
63 are not simple constants.
64 In this case, a safer definition of the macro would have been
68 This way, when the preprocessor performs its simple textual substitution,
69 the resulting expression is automatically parenthesized
70 so that the compiler gives you the result you expect.
72 this hypothetical
<TT>SIX
</TT> macro is useless in any case,
73 but the point is that whenever a macro's value is an expression
75 it needs extra parentheses
78 <I>If the header file
<TT>x.h
</TT> contains
79 an external prototype declaration for a function
<TT>q()
</TT>,
80 where should
<TT>x.h
</TT> be included?
81 </I><p>It should be included in each source file where
<TT>q()
</TT>
82 is called, so that the compiler will see the prototype declaration
83 and be able to generate correct code.
84 It should
<em>also
</em> be included
85 in the source file where
<TT>q()
</TT> is
<em>defined
</em>,
86 so that the compiler will be able to notice, and complain about,
87 any mismatches between the prototype declaration and the actual definition.
88 (It's vital that the prototype
90 used where a function is called be accurate;
91 an incorrect prototype is worse than useless.)
93 <I>How many differences can you think of between
<TT>i
</TT> and
<TT>J
</TT></I>?
98 declares a conventional run-time variable, named
<TT>i
</TT>,
99 initially containing the value
10.
100 It will be possible to change
<TT>i
</TT>'s value at run time.
101 <TT>i
</TT> may appear in expressions
102 (i.e., its value may be fetched),
103 but since it is not constant,
104 it could not be used where C requires a constant,
105 such as in the dimension of an array declaration.
111 defines a preprocessor macro named
<TT>J
</TT> having the value
<TT>10</TT>.
112 For the rest of the current source file, anywhere you write a single
<TT>J
</TT>,
113 the preprocessor will replace it with
<TT>10</TT>.
114 An array declaration such as
119 it will be just as if you had written
123 However,
<TT>J
</TT> exists only at compile time.
124 It is not a run-time variable; if you tried to
125 ``change its value'' at run time by writing
129 it would be just as if you had written
133 and the compiler would complain.
134 <p>(One more little difference is that the line
136 </TT>ends in a semicolon,
141 <I>Write a program to read its input and write it out, double-spaced.
142 </I><p>This is easy if we realize that
144 read the input a character at a time,
145 copying each input character through to the output,
146 except that whenever we see a
<TT>'\n'
</TT> character,
147 write a second one out, too.
149 #include
<stdio.h
>
155 while((c = getchar()) != EOF)
165 The program won't be too interesting if you type text at it interactively.
166 If you're using a Unix or MS-DOS system,
167 you can run it on a file by typing
169 doublespace
< filename
171 The
<TT><</TT> mechanism indicates that
172 the program should be run
173 with its ``standard input''
174 (i.e. the stream of characters read by
<TT>getchar
</TT>)
175 connected to the file with the given
<TT>filename
</TT>,
176 rather than to the keyboard.
179 which counts the number of times a character appears in a string.
180 </I><p>Here is the function.
181 Notice that it is very similar to the
<TT>mystrlen
</TT> function in the notes,
182 except that rather than counting all characters in the string,
183 it only counts those matching the argument
<TT>c
</TT>.
185 int countnchars(char string[], int ch)
189 for(i =
0; string[i] != '\
0'; i++)
197 Here is a tiny little main program, to test it out:
199 #include
<stdio.h
>
201 extern int countnchars(char string[], int ch);
205 char string[] =
"Hello, world!";
208 printf(
"The letter %c appears in \"%s\
" %d times.\n",
209 c, string, countnchars(string, c));
214 <I>Write a short program to read two lines of text,
215 and concatenate them using
<TT>strcat
</TT>.
219 #include
<stdio.h
>
220 #include
<string.h
> /* for strcpy and strcat */
224 extern int getline(char [], int);
228 char string1[MAXLINE], string2[MAXLINE];
230 char newstring[MAXLINE*
2];
232 printf(
"enter first string:\n");
233 len1 = getline(string1,
100);
234 printf(
"enter second string:\n");
235 len2 = getline(string2,
100);
237 if(len1 == EOF || len2 == EOF)
240 strcpy(newstring, string1);
241 strcat(newstring, string2);
243 printf(
"%s\n", newstring);
249 to find a substring in a larger string
250 and replace it with a different substring.
251 </I><p>Here is one way.
252 (Since the function doesn't return anything,
253 I've defined it with a return type of
<TT>void
</TT>.)
255 void replace(char string[], char from[], char to[])
258 for(start =
0; string[start] != '\
0'; start++)
262 while(from[i1] != '\
0')
264 if(from[i1] != string[i2])
271 for(i1 =
0; to[i1] != '\
0'; i1++)
272 string[start++] = to[i1];
278 This code is very similar to
279 the
<TT>mystrstr
</TT>
281 in the notes, chapter
10, section
10.4, p.
8.
282 (Since
<TT>strstr
</TT>'s job is to find one string within
283 another, it's a natural for the first half of
<TT>replace
</TT>.)
285 Think about what
<TT>replace()
</TT> should do
286 if the
<TT>from
</TT> string appears multiple times
290 replaced only the first occurrence
292 of the
<TT>from
</TT> string.
293 It happens, though, that it's trivial to rewrite our first version
294 to make it replace all occurrences--just omit the
295 <TT>return
</TT> after the first string has been replaced:
297 void replace(char string[], char from[], char to[])
300 for(start =
0; string[start] != '\
0'; start++)
304 while(from[i1] != '\
0')
306 if(from[i1] != string[i2])
313 for(i1 =
0; to[i1] != '\
0'; i1++)
314 string[start++] = to[i1];
322 This page by
<a href=
"http://www.eskimo.com/~scs/">Steve Summit
</a>
323 //
<a href=
"copyright.html">Copyright
</a> 1995-
9
324 //
<a href=
"mailto:scs@eskimo.com">mail feedback
</a>