forked from zedz/lcthw-cn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ex10.tex
124 lines (100 loc) · 5 KB
/
ex10.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
\chapter{Exercise 10: Arrays Of Strings, Looping}
You can make an array of various types, and have the idea down that a
"string" and an "array of bytes" are the same thing. The next thing is
to take this one step further and do an array that has strings in it.
We'll also introduce your first looping construct, the \ident{for-loop}
to help print out this new data structure.
The fun part of this is that there's been an array of strings hiding in
your programs for a while now, the \ident{char *argv[]} in the \ident{main}
function arguments. Here's code that will print out any command line
arguments you pass it:
\begin{code}{ex10.c}
<< d['code/ex10.c|pyg|l'] >>
\end{code}
The format of a \ident{for-loop} is this:
\begin{Verbatim}
for(INITIALIZER; TEST; INCREMENTER) {
CODE;
}
\end{Verbatim}
Here's how the \ident{for-loop} works:
\begin{enumerate}
\item The \ident{INITIALIZER} is code that is run to setup the loop, in this
case \verb|i = 0|.
\item Next the \ident{TEST} boolean expression is checked, and if it's false (0)
then \ident{CODE} is skipped, doing nothing.
\item The \ident{CODE} runs, does whatever it does.
\item After the \ident{CODE} runs, the \ident{INCREMENTER} part is run, usually
incrementing something, like in \verb|i++|.
\item And it continues again with Step 2 until the \ident{TEST} is false (0).
\end{enumerate}
This \ident{for-loop} is going through the command line arguments
using \ident{argc} and \ident{argv} like this:
\begin{enumerate}
\item The OS passes each command line argument as a string in the \ident{argv}
array. The program's name (./ex10) is at 0, with the rest coming after it.
\item The OS also sets \ident{argc} to the number of arguments in the \ident{argv}
array so you can process them without going past the end. Remember that if you
give one argument, the program's name is the first, so argc is 2.
\item The \ident{for-loop} sets up with \verb|i = 1| in the initializer.
\item It then tests that \ident{i} is less than \ident{argc} with the
test \verb|i < argc|. Since initially $1 < 2$ it will pass.
\item It then runs the code which just prints out the \ident{i} and
uses \ident{i} to index into \ident{argv}.
\item The incrementer is then run using the \verb|i++| syntax, which is
a handy way of writing \verb|i = i + 1|.
\item This then repeats until \verb|i < argc| is finally false (0) when
the loop exits and the program continues on.
\end{enumerate}
\section{What You Should See}
To play with this program you have to run it two ways. The first way is to
pass in some command line arguments so that \ident{argc} and \ident{argv}
get set. The second is to run it with no arguments so you can see that
the first \ident{for-loop} doesn't run since \verb|i < argc| will be false.
\begin{code}{ex10 output}
\begin{lstlisting}
<< d['code/ex10.out'] >>
\end{lstlisting}
\end{code}
\subsection{Understanding Arrays Of Strings}
From this you should be able to figure out that in C you make an "array of
strings" by combining the \verb|char *str = "blah"| syntax with the
\verb|char str[] = {'b','l','a','h'}| syntax to construct a 2-dimensional
array. The syntax \verb|char *states[] = {...}| on line 14 is this
2-dimension combination, with each string being one element, and each
character in the string being another.
Confusing? The concept of multiple dimensions is something most
people never think about so what you should do is build this
array of strings on paper:
\begin{enumerate}
\item Make a grid with the index of each \emph{string} on the left.
\item Then put the index of each \emph{character} on the top.
\item Then, fill in the squares in the middle with what single character
goes in that cell.
\item Once you have the grid, trace through the code manually
using this grid of paper.
\end{enumerate}
Another way to figure this is out is to build the same structure
in a programming language you are more familiar with like Python or
Ruby.
\section{How To Break It}
\begin{enumerate}
\item Take your favorite other language, and use it to run this program, but
with as many command line arguments as possible. See if you can bust it
by giving it way too many arguments.
\item Initialize \ident{i} to 0 and see what that does. Do you have to adjust
\ident{argc} as well or does it just work? Why does 0-based indexing work
here?
\item Set \ident{num\_states} wrong so that it's a higher value and see what
it does.
\end{enumerate}
\section{Extra Credit}
\begin{enumerate}
\item Figure out what kind of code you can put into the parts of a \ident{for-loop}.
\item Look up how to use the \verb|','| (comma) character to separate multiple
statements in the parts of the \ident{for-loop}, but between the \verb|';'| (semicolon) characters.
\item Read what a \ident{NULL} is and try to use it in one of the elements of the
\ident{states} array to see what it'll print.
\item See if you can assign an element from the \ident{states} array to the
\ident{argv} array before printing both. Try the inverse.
\end{enumerate}