📄 chapter06.html
字号:
generalizes it to print multiples of <TT>n</TT>.</P><PRE>void printMultiples (int n){ int i = 1; while (i <= 6) { cout << n*i << " "; i = i + 1; } cout << endl;}</PRE><P>To encapsulate, all I had to do was add the first line, which declares the name, parameter, and return type. To generalize, all I had to do was replacethe value 2 with the parameter <TT>n</TT>.</P><P>If we call this function with the argument 2, we get the same output as before. With argument 3, the output is:</P><PRE>3 6 9 12 15 18</PRE><P>and with argument 4, the output is</P><PRE>4 8 12 16 20 24 </PRE><P>By now you can probably guess how we are going to print a multiplication table: we'll call <TT>printMultiples</TT> repeatedly with different arguments.In fact, we are going to use another loop to iterate through the rows.</P><PRE> int i = 1; while (i <= 6) { printMultiples (i); i = i + 1; } </PRE><P>First of all, notice how similar this loop is to the one inside <TT>printMultiples</TT>. All I did was replace the print statement with afunction call.</P><P>The output of this program is</P><PRE>1 2 3 4 5 6 2 4 6 8 10 12 3 6 9 12 15 18 4 8 12 16 20 24 5 10 15 20 25 30 6 12 18 24 30 36 </PRE><P>which is a (slightly sloppy) multiplication table. If the sloppiness bothersyou, try replacing the spaces between columns with tab characters and see what you get.</P><BR><BR><H3>6.7 Functions</H3><P>In the last section I mentioned ``all the things functions are good for.''About this time, you might be wondering what exactly those things are. Here are some of the reasons functions are useful:</P><OL> <LI>By giving a name to a sequence of statements, you make your program easier to read and debug.</LI> <LI>Dividing a long program into functions allows you to separate parts of the program, debug them in isolation, and then compose them into a whole.</LI> <LI>Functions facilitate both recursion and iteration.</LI> <LI>Well-designed functions are often useful for many programs. Once you write and debug one, you can reuse it.</LI></OL><BR><BR><H3>6.8 More encapsulation</H3><P>To demonstrate encapsulation again, I'll take the code from the previous section and wrap it up in a function:</P><PRE>void printMultTable () { int i = 1; while (i <= 6) { printMultiples (i); i = i + 1; }}</PRE><P>The process I am demonstrating is a common development plan. You develop code gradually by adding lines to main} or someplace else, and then when you get it working, you extract it and wrap it up in a function.</P><P>The reason this is useful is that you sometimes don't know when you start writing exactly how to divide the program into functions. This approach lets you design as you go along.</P><BR><BR><H3>6.9 Local variables</H3><P>About this time, you might be wondering how we can use the same variable <TT>i</TT> in both <TT>printMultiples</TT> and <TT>printMultTable</TT>. Didn't I say that you can only declare a variable once? And doesn't it cause problemswhen one of the functions changes the value of the variable?</P><P>The answer to both questions is ``no,'' because the <TT>i</TT> in <TT>printMultiples</TT> and the <TT>i</TT> in <TT>printMultTable</TT> are<I>not the same variable</I>. They have the same name, but they do not refer tothe same storage location, and changing the value of one of them has no effecton the other.</P><P>Remember that variables that are declared inside a function definition are local. You cannot access a local variable from outside its ``home'' function, and you are free to have multiple variables with the same name, as long as theyare not in the same function.</P><P>The stack diagram for this program shows clearly that the two variables named <TT>i</TT> are not in the same storage location. They can have different values, and changing one does not affect the other.</P><P CLASS=1><IMG SRC="images/stack4.png" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/images/stack4.png" ALT="Stack4 Image"></P><P>Notice that the value of the parameter <TT>n</TT> in <TT>printMultiples</TT>ihas to be the same as the value of <TT>i</TT> in <TT>printMultTable</TT>. On the other hand, the value of <TT>i</TT> in <TT>printMultiple</TT> goes from 1 up to <TT>n</TT>. In the diagram, it happens to be 3. The next time through theloop it will be 4.</P><P>It is often a good idea to use different variable names in different functions, to avoid confusion, but there are good reasons to reuse names. For example, it is common to use the names <TT>i</TT>, <TT>j</TT> and <TT>k</TT> asloop variables. If you avoid using them in one function just because you used them somewhere else, you will probably make the program harder to read.</P><BR><BR><H3>6.10 More generalization</H3><P>As another example of generalization, imagine you wanted a program that would print a multiplication table of any size, not just the 6x6 table. You could add a parameter to <TT>printMultTable</TT>:</P><PRE>void printMultTable (int high) { int i = 1; while (i <= high) { printMultiples (i); i = i + 1; }}</PRE><P>I replaced the value 6 with the parameter <TT>high</TT>. If I call <TT>printMultTable</TT> with the argument 7, I get</P><PRE>1 2 3 4 5 6 2 4 6 8 10 12 3 6 9 12 15 18 4 8 12 16 20 24 5 10 15 20 25 30 6 12 18 24 30 36 7 14 21 28 35 42 </PRE><P>which is fine, except that I probably want the table to be square (same number of rows and columns), which means I have to add another parameter to <TT>printMultiples</TT>, to specify how many columns the table should have.</P><P>Just to be annoying, I will also call this parameter <TT>high</TT>, demonstrating that different functions can have parameters with the same name (just like local variables):</P><PRE>void printMultiples (int n, int high) { int i = 1; while (i <= high) { cout << n*i << " "; i = i + 1; } cout << endl;}void printMultTable (int high) { int i = 1; while (i <= high) { printMultiples (i, high); i = i + 1; }}</PRE><P>Notice that when I added a new parameter, I had to change the first line of the function (the interface or prototype), and I also had to change the place where the function is called in <TT>printMultTable</TT>. As expected, this program generates a square 7x7 table:</P><PRE>1 2 3 4 5 6 7 2 4 6 8 10 12 14 3 6 9 12 15 18 21 4 8 12 16 20 24 28 5 10 15 20 25 30 35 6 12 18 24 30 36 42 7 14 21 28 35 42 49</PRE><P>When you generalize a function appropriately, you often find that the resulting program has capabilities you did not intend. For example, you might notice that the multiplication table is symmetric, because $ab = ba$, so all the entries in the table appear twice. You could save ink by printing onlyhalf the table. To do that, you only have to change one line of <TT>printMultTable</TT>. Change</P><PRE> printMultiples (i, high);</PRE>to<PRE> printMultiples (i, i);</PRE>and you get<PRE>1 2 4 3 6 9 4 8 12 16 5 10 15 20 25 6 12 18 24 30 36 7 14 21 28 35 42 49 </PRE><P>I'll leave it up to you to figure out how it works.</P><BR><BR><H3>6.11 Glossary</H3><DL> <DT>loop:</DT><DD> A statement that executes repeatedly while a condition is true or until some condition is satisfied.</DD> <DT>infinite loop:</DT><DD> A loop whose condition is always true.</DD> <DT>body:</DT><DD> The statements inside the loop.</DD> <DT>iteration:</DT><DD> One pass through (execution of) the body of the loop, including the evaluation of the condition.</DD> <DT>tab:</DT><DD> A special character, written as <TT>\t</TT> in C++, that causes the cursor to move to the next tab stop on the current line.</DD> <DT>encapsulate:</DT><DD> To divide a large complex program into components (like functions) and isolate the components from each other (for example, by using local variables).</DD> <DT>local variable:</DT><DD> A variable that is declared inside a function and that exists only within that function. Local variables cannot be accessed from outside their home function, and do not interfere with any other functions.</DD> <DT>generalize:</DT><DD> To replace something unnecessarily specific (like a constant value) with something appropriately general (like a variable or parameter). Generalization makes code more versatile, more likely to be reused, and sometimes even easier to write.</DD> <DT>development plan:</DT><DD> A process for developing a program. In this chapter, I demonstrated a style of development based on developing code to do simple, specific things, and then encapsulating and generalizing.</DD></DL><BR><DIV CLASS=navigation><HR> <TABLE ALIGN=center WIDTH="100%" CELLPADDING=0 CELLSPACING=2> <TR> <TD><A HREF="chapter07.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/chapter07.html"> <IMG WIDTH=32 HEIGHT=32 ALIGN=bottom BORDER=0 ALT="next" SRC="images/next.gif" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/images/next.gif"></A> </TD> <TD><A HREF="index.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/index.html"> <IMG WIDTH=32 HEIGHT=32 ALIGN=bottom BORDER=0 ALT="up" SRC="images/up.gif" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/images/up.gif"></A> </TD> <TD><A HREF="chapter05.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/chapter05.html"> <IMG WIDTH=32 HEIGHT=32 ALIGN=bottom BORDER=0 ALT="previous" SRC="images/previous.gif" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/images/previous.gif"></A> </TD> <TD ALIGN=center BGCOLOR="#99CCFF" WIDTH="100%"> <B CLASS=title>How to Think Like a Computer Scientist: Chapter 6</B> </TD> <TD><A HREF="index.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/index.html"> <IMG WIDTH=32 HEIGHT=32 ALIGN=bottom BORDER=0 ALT="contents" SRC="images/contents.gif" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/images/contents.gif"></A> </TD> <TD> <IMG WIDTH=32 HEIGHT=32 ALIGN=bottom BORDER=0 ALT="" SRC="images/blank.gif" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/images/blank.gif"> </TD> <TD> <IMG WIDTH=32 HEIGHT=32 ALIGN=bottom BORDER=0 ALT="" SRC="images/blank.gif" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/images/blank.gif"> </TD> </TR> </TABLE> <B CLASS=navlabel>Next:</B> <SPAN CLASS=sectref><A HREF="chapter07.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/chapter07.html">Chapter 7</A></SPAN> <B CLASS=navlabel>Up:</B> <SPAN CLASS=sectref><A HREF="index.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/index.html">Index</A></SPAN> <B CLASS=navlabel>Previous:</B> <SPAN CLASS=sectref><A HREF="chapter05.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/chapter05.html">Chapter 5</A></SPAN> <HR></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -