📄 chapter08.html
字号:
Rectangle box = { corner, 100.0, 200.0 };</PRE><P>This code creates a new <TT>Rectangle</TT> structure and initializes theinstance variables. The figure shows the effect of this assignment.</P><P CLASS=1><IMG SRC="images/rectangle.png" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/images/rectangle.png" ALT="Rectangle Image"></P><P>We can access the <TT>width</TT> and <TT>height</TT> in the usual way:</P><PRE> box.width += 50.0; cout << box.height << endl;</PRE><P>In order to access the instance variables of <TT>corner</TT>, we can use atemporary variable:</P><PRE> Point temp = box.corner; double x = temp.x;</PRE><P>Alternatively, we can compose the two statements:</P><PRE> double x = box.corner.x;</PRE><P>It makes the most sense to read this statement from right to left: ``Extract <TT>x</TT> from the <TT>corner</TT> of the <TT>box</TT>, and assign it to the local variable <TT>x</TT>.''</P><P>While we are on the subject of composition, I should point out that you can,in fact, create the <TT>Point</TT> and the <TT>Rectangle</TT> at the same time:</P><PRE> Rectangle box = { { 0.0, 0.0 }, 100.0, 200.0 };</PRE><P>The innermost squiggly braces are the coordinates of the corner point; together they make up the first of the three values that go into the new <TT>Rectangle</TT>. This statement is an example of <B>nested structure</B>.</P><BR><BR><H3>8.9 Structures as return types</H3><P>You can write functions that return structures. For example, <TT>findCenter</TT> takes a <TT>Rectangle</TT> as an argument and returns a <TT>Point</TT> that contains the coordinates of the center of the <TT>Rectangle</TT>:</P><PRE>Point findCenter (Rectangle& box){ double x = box.corner.x + box.width/2; double y = box.corner.y + box.height/2; Point result = {x, y}; return result;}</PRE><P>To call this function, we have to pass a box as an argument (notice that it is being passed by reference), and assign the return value to a <TT>Point</TT> variable:</P><PRE> Rectangle box = { {0.0, 0.0}, 100, 200 }; Point center = findCenter (box); printPoint (center);</PRE><P>The output of this program is <TT>(50, 100)</TT>.</P><BR><BR><H3>8.10 Passing other types by reference</H3><P>It's not just structures that can be passed by reference. All the other types we've seen can, too. For example, to swap two integers, we could write something like:</P><PRE>void swap (int& x, int& y){ int temp = x; x = y; y = temp;}</PRE><P>We would call this function in the usual way:</P><PRE> int i = 7; int j = 9; swap (i, j); cout << i << j << endl;</PRE><P>The output of this program is <TT>97</TT>. Draw a stack diagram for this program to convince yourself this is true. If the parameters <TT>x</TT> and <TT>y</TT> were declared as regular parameters (without the <TT>&</TT>s), <TT>swap</TT> would not work. It would modify <TT>x</TT> and <TT>y</TT> and have no effect on <TT>i</TT> and <TT>j</TT>.</P><P>When people start passing things like integers by reference, they often try to use an expression as a reference argument. For example:</P><PRE> int i = 7; int j = 9; swap (i, j+1); // WRONG!!</PRE><P>This is not legal because the expression <TT>j+1</TT> is not a variable---itdoes not occupy a location that the reference can refer to. It is a little tricky to figure out exactly what kinds of expressions can be passed by reference. For now a good rule of thumb is that reference arguments have to bevariables.</P><BR><BR><H3>8.11 Getting user input</H3><P>The programs we have written so far are pretty predictable; they do the samething every time they run. Most of the time, though, we want programs that takeinput from the user and respond accordingly.</P><P>There are many ways to get input, including keyboard input, mouse movements and button clicks, as well as more exotic mechanisms like voice control and retinal scanning. In this text we will consider only keyboard input.</P><P>In the header file <TT>iostream.h</TT>, C++ defines an object named <TT>cin</TT> that handles input in much the same way that <TT>cout</TT> handlesoutput. To get an integer value from the user:</P><PRE> int x; cin >> x;</PRE><P>The <TT>>></TT> operator causes the program to stop executing and wait for the user to type something. If the user types a valid integer, the program converts it into an integer value and stores it in <TT>x</TT>.</P><P>If the user types something other than an integer, C++ doesn't report an error, or anything sensible like that. Instead, it puts some meaningless value in <TT>x</TT> and continues.</P><P>Fortunately, there is a way to check and see if an input statement succeeds.We can invoke the <TT>good</TT> function on <TT>cin</TT> to check what is called the <B>stream state</B>. <TT>good</TT> returns a <TT>bool</TT>: if true,then the last input statement succeeded. If not, we know that some previous operation failed, and also that the next operation will fail.</P><P>Thus, getting input from the user might look like this:</P><PRE>int main (){ int x; // prompt the user for input cout << "Enter an integer: "; // get input cin >> x; // check and see if the input statement succeeded if (cin.good() == false) { cout << "That was not an integer." << endl; return -1; } // print the value we got from the user cout << x << endl; return 0;}</PRE><P><TT>cin</TT> can also be used to input an <TT>apstring</TT>:</P><PRE> apstring name; cout << "What is your name? "; cin >> name; cout << name << endl;</PRE><P>Unfortunately, this statement only takes the first word of input, and leaves the rest for the next input statement. So, if you run this program and type your full name, it will only output your first name.</P><P>Because of these problems (inability to handle errors and funny behavior), Iavoid using the <TT>>></TT> operator altogether, unless I am reading datafrom a source that is known to be error-free.</P><P>Instead, I use a function in the <TT>apstring</TT> called <TT>getline</TT>.</P><PRE> apstring name; cout << "What is your name? "; getline (cin, name); cout << name << endl;</PRE><P>The first argument to <TT>getline</TT> is <TT>cin</TT>, which is where the input is coming from. The second argument is the name of the <TT>apstring</TT>where you want the result to be stored.</P><P><TT>getline</TT> reads the entire line until the user hits Return or Enter.This is useful for inputting strings that contain spaces.</P><P>In fact, <TT>getline</TT> is generally useful for getting input of any kind.For example, if you wanted the user to type an integer, you could input a string and then check to see if it is a valid integer. If so, you can convert it to an integer value. If not, you can print an error message and ask the userto try again.</P><P>To convert a string to an integer you can use the <TT>atoi</TT> function defined in the header file <TT>stdlib.h</TT>. We will get to that in Section 15.4.</P><BR><BR><H3>8.12 Glossary</H3><DL> <DT>structure:</DT><DD> A collection of data grouped together and treated as a single object.</DD> <DT>instance variable:</DT><DD> One of the named pieces of data that make up a structure.</DD> <DT>reference:</DT><DD> A value that indicates or refers to a variable or structure. In a state diagram, a reference appears as an arrow.</DD> <DT>pass by value:</DT><DD> A method of parameter-passing in which the value provided as an argument is copied into the corresponding parameter, but the parameter and the argument occupy distinct locations.</DD <DT>pass by reference:</DT><DD> A method of parameter-passing in which the parameter is a reference to the argument variable. Changes to the parameter also affect the argument variable.</DD></DL><BR><DIV CLASS=navigation><HR> <TABLE ALIGN=center WIDTH="100%" CELLPADDING=0 CELLSPACING=2> <TR> <TD><A HREF="chapter09.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/chapter09.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="chapter07.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/chapter07.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 8</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="chapter09.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/chapter09.html">Chapter 9</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="chapter07.html" tppabs="http://rocky.wellesley.edu/downey/ost/thinkCS/c++_html/chapter07.html">Chapter 7</A></SPAN> <HR></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -