⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch21.htm

📁 Why C++ is the emerging standard in software development. The steps to develop a C++ program. How
💻 HTM
📖 第 1 页 / 共 4 页
字号:
0011</TT>, the complement of that number is <TT>0101 1100</TT>.<CENTER><H4><A NAME="Heading24"></A><FONT COLOR="#000077">Setting Bits</FONT></H4></CENTER><P>When you want to set or clear a particular bit, you use masking operations. Ifyou have a 4-byte flag and you want to set bit 8 TRUE, you need to <TT>OR</TT> theflag with the value <TT>128</TT>. Why? <TT>128</TT> is <TT>1000 0000</TT> in binary;thus the value of the eighth bit is <TT>128</TT>. Whatever the current value of thatbit (<TT>set</TT> or <TT>clear</TT>), if you <TT>OR</TT> it with the value <TT>128</TT>you will set that bit and not change any of the other bits. Let's assume that thecurrent value of the 8 bits is <TT>1010 0110 0010 0110</TT>. <TT>OR</TT>ing 128 toit looks like this:</P><PRE><FONT COLOR="#0066FF">9 8765 43211010 0110 0010 0110   // bit 8 is clear|   0000 0000 1000 0000   // 128----------------------1010 0110 1010 0110   // bit 8 is set</FONT></PRE><P>There are a few things to note. First, as usual, bits are counted from right toleft. Second, the value <TT>128</TT> is all zeros except for bit 8, the bit you wantto set. Third, the starting number <TT>1010 0110 0010 0110</TT> is left unchangedby the <TT>OR</TT> operation, except that bit 8 was set. Had bit 8 already been set,it would have remained set, which is what you want.<CENTER><H4><A NAME="Heading25"></A><FONT COLOR="#000077">Clearing Bits</FONT></H4></CENTER><P>If you want to clear bit 8, you can <TT>AND</TT> the bit with the complement of128. The complement of 128 is the number you get when you take the bit pattern of128 (1000 0000), set every bit that is <TT>clear</TT>, and clear every bit that is<TT>set</TT> (0111 1111). When you <TT>AND</TT> these numbers, the original numberis unchanged, except for the eighth bit, which is forced to zero.</P><PRE><FONT COLOR="#0066FF">1010 0110 1010 0110  // bit 8 is set&amp; 1111 1111 0111 1111  // ~128----------------------1010 0110 0010 0110  // bit 8 cleared</FONT></PRE><P>To fully understand this solution, do the math yourself. Each time both bits are<TT>1</TT>, write 1 in the answer. If either bit is <TT>0</TT>, write 0 in the answer.Compare the answer with the original number. It should be the same except that bit8 was cleared.<CENTER><H4><A NAME="Heading26"></A><FONT COLOR="#000077">Flipping Bits</FONT></H4></CENTER><P>Finally, if you want to flip bit 8, no matter what its state, you exclusive <TT>OR</TT>the number with 128. Thus:</P><PRE><FONT COLOR="#0066FF">1010 0110 1010 0110  // number^ 0000 0000 1000 0000  // 128----------------------1010 0110 0010 0110  // bit flipped^ 0000 0000 1000 0000  // 128----------------------1010 0110 1010 0110  // flipped back</FONT></PRE><BLOCKQUOTE>	<P><HR><B>DO</B> set bits by using masks and the <TT>OR</TT> operator. <B>DO</B> clear bits	by using masks and the <TT>AND</TT> operator.<B> DO </B>flip bits using masks and	the exclusive <TT>OR</TT> operator. <HR></BLOCKQUOTE><CENTER><H4><A NAME="Heading27"></A><FONT COLOR="#000077">Bit Fields</FONT></H4></CENTER><P>There are circumstances under which every byte counts, and saving six or eightbytes in a class can make all the difference. If your class or structure has a seriesof Boolean variables, or variables that can have only a very small number of possiblevalues, you may save some room using bit fields.</P><P>Using the standard C++ data types, the smallest type you can use in your classis a type <TT>char</TT>, which is one byte. You will usually end up using an <TT>int</TT>,which is two, or more often four, bytes. By using bit fields, you can store eightbinary values in a <TT>char</TT> and 32 such values in a <TT>long</TT>.</P><P>Here's how bit fields work: bit fields are named and accessed like any class member.Their type is always declared to be <TT>unsigned</TT> <TT>int</TT>. After the bitfield name, write a colon followed by a number. The number is an instruction to thecompiler as to how many bits to assign to this variable. If you write 1, the bitwill represent either the value <TT>0</TT> or <TT>1</TT>. If you write 2, the bitcan represent <TT>0</TT>, <TT>1</TT>, <TT>2</TT>, or <TT>3</TT>, a total of fourvalues. A three-bit field can represent eight values, and so forth. Appendix C reviewsbinary numbers. Listing 21.8 illustrates the use of bit fields.</P><P><A NAME="Heading28"></A><FONT SIZE="4" COLOR="#000077"><B>Listing 21.8. Usingbit fields.</B></FONT><PRE><FONT COLOR="#0066FF">0:        #include &lt;iostream.h&gt;1:        #include &lt;string.h&gt;2:    3:        enum STATUS { FullTime, PartTime } ;4:        enum GRADLEVEL { UnderGrad, Grad } ;5:        enum HOUSING { Dorm, OffCampus };6:        enum FOODPLAN { OneMeal, AllMeals, WeekEnds, NoMeals };7:    8:        class student9:        {10:        public:11:        student():12:            myStatus(FullTime),13:            myGradLevel(UnderGrad),14:            myHousing(Dorm),15:            myFoodPlan(NoMeals)16:            {}17:            ~student(){}18:            STATUS GetStatus();19:            void SetStatus(STATUS);20:            unsigned GetPlan() { return myFoodPlan; }21:    22:        private:23:           unsigned myStatus : 1;24:           unsigned myGradLevel: 1;25:           unsigned myHousing : 1;26:           unsigned myFoodPlan : 2;27:        };28:    29:        STATUS student::GetStatus()30:        {31:           if (myStatus)32:              return FullTime;33:           else34:              return PartTime;35:        }36:        void student::SetStatus(STATUS theStatus)37:        {38:           myStatus = theStatus;39:        }40:    41:    42:        int main()43:        {44:           student Jim;45:    46:           if (Jim.GetStatus()== PartTime)47:              cout &lt;&lt; &quot;Jim is part time&quot; &lt;&lt; endl;48:           else49:              cout &lt;&lt; &quot;Jim is full time&quot; &lt;&lt; endl;50:    51:           Jim.SetStatus(PartTime);52:    53:           if (Jim.GetStatus())54:              cout &lt;&lt; &quot;Jim is part time&quot; &lt;&lt; endl;55:           else56:              cout &lt;&lt; &quot;Jim is full time&quot; &lt;&lt; endl;57:    58:           cout &lt;&lt; &quot;Jim is on the &quot; ;59:    60:           char Plan[80];61:           switch (Jim.GetPlan())62:           {63:              case  OneMeal: strcpy(Plan,&quot;One meal&quot;); break;64:              case  AllMeals: strcpy(Plan,&quot;All meals&quot;); break;65:              case WeekEnds: strcpy(Plan,&quot;Weekend meals&quot;); break;66:              case NoMeals: strcpy(Plan,&quot;No Meals&quot;);break;67:              default : cout &lt;&lt; &quot;Something bad went wrong!\n&quot;; break;68:           }69:           cout &lt;&lt; Plan &lt;&lt; &quot; food plan.&quot; &lt;&lt; endl;70:         return 0;<TT>71: }</TT></FONT><FONT COLOR="#0066FF">Output: Jim is part timeJim is full timeJim is on the No Meals food plan.</FONT></PRE><P><FONT COLOR="#000077"><B>Analysis:</B></FONT><B> </B>On lines 3 to 7, severalenumerated types are defined. These serve to define the possible values for the bitfields within the student class.<BR><TT><BR>Student</TT> is declared in lines 8-27. While this is a trivial class, it is interestingin that all the data is packed into five bits. The first bit represents the student'sstatus, full-time or part-time. The second bit represents whether or not this isan undergraduate. The third bit represents whether or not the student lives in adorm. The final two bits represent the four possible food plans.</P><P>The class methods are written as for any other class, and are in no way affectedby the fact that these are bit fields and not integers or enumerated types.</P><P>The member function <TT>GetStatus()</TT> reads the Boolean bit and returns anenumerated type, but this is not necessary. It could just as easily have been writtento return the value of the bit field directly. The compiler would have done the translation.</P><PRE>To prove that to yourself, replace the <TT>GetStatus()</TT> implementation with this code:</PRE><PRE><FONT COLOR="#0066FF">STATUS student::GetStatus(){return myStatus;}</FONT></PRE><P>There should be no change whatsoever to the functioning of the program. It isa matter of clarity when reading the code; the compiler isn't particular.</P><P>Note that the code on line 46 must check the status and then print the meaningfulmessage. It is tempting to write this:</P><PRE><FONT COLOR="#0066FF">cout &lt;&lt; &quot;Jim is &quot; &lt;&lt; Jim.GetStatus() &lt;&lt; endl;</FONT></PRE><P>That will simply print this:</P><PRE><FONT COLOR="#0066FF">Jim is 0</FONT></PRE><P>The compiler has no way to translate the enumerated constant <TT>PartTime</TT>into meaningful text.</P><P>On line 61, the program switches on the food plan, and for each possible valueit puts a reasonable message into the buffer, which is then printed on line 69. Noteagain that the <TT>switch</TT> statement could have been written as follows:</P><PRE><FONT COLOR="#0066FF">case  0: strcpy(Plan,&quot;One meal&quot;); break;case  1: strcpy(Plan,&quot;All meals&quot;); break;case  2: strcpy(Plan,&quot;Weekend meals&quot;); break;case  3: strcpy(Plan,&quot;No Meals&quot;);break;</FONT></PRE><P>The most important thing about using bit fields is that the client of the classneed not worry about the data storage implementation. Because the bit fields areprivate, you can feel free to change them later and the interface will not need tochange.<CENTER><H3><A NAME="Heading30"></A><FONT COLOR="#000077">Style</FONT></H3></CENTER><P>As stated elsewhere in this book, it is important to adopt a consistent codingstyle, though in many ways it doesn't matter which style you adopt. A consistentstyle makes it easier to guess what you meant by a particular part of the code, andyou avoid having to look up whether you spelled the function with an initial capor not the last time you invoked it.</P><P>The following guidelines are arbitrary; they are based on the guidelines usedin projects I've worked on in the past, and they've worked well. You can just aseasily make up your own, but these will get you started.</P><P>As Emerson said, &quot;Foolish consistency is the hobgoblin of small minds,&quot;but having some consistency in your code is a good thing. Make up your own, but thentreat it as if it were dispensed by the programming gods.<CENTER><H4><A NAME="Heading31"></A><FONT COLOR="#000077">Indenting</FONT></H4></CENTER><P>Tab size should be four spaces. Make sure your editor converts each tab to fourspaces.<CENTER><H4><A NAME="Heading32"></A><FONT COLOR="#000077">Braces</FONT></H4></CENTER><P>How to align braces can be the most controversial topic between C and C++ programmers.Here are the tips I suggest:<UL>	<LI>Matching braces should be aligned vertically.	<P>	<LI>The outermost set of braces in a definition or declaration should be at the left	margin. Statements within should be indented. All other sets of braces should be	in line with their leading statements.	<P>	<LI>No code should appear on the same line as a brace. For example:</UL><PRE><FONT COLOR="#0066FF">if (condition==true){j = k;SomeFunction();}m++;</FONT></PRE><CENTER><H4><A NAME="Heading33"></A><FONT COLOR="#000077">Long Lines</FONT></H4></CENTER><P>Keep lines to the width displayable on a single screen. Code that is off to theright is easily overlooked, and scrolling horizontally is annoying. When a line isbroken, indent the following lines. Try to break the line at a reasonable place,and try to leave the intervening operator at the end of the previous line (as opposedto the beginning of the following line) so that it is clear that the line does notstand alone and that there is more coming.</P><P>In C++, functions tend to be far shorter than they were in C, but the old, soundadvice still applies. Try to keep your functions short enough to print the entirefunction on one page.<CENTER><H4><A NAME="Heading34"></A><FONT COLOR="#000077">switch Statements</FONT></H4></CENTER><P>Indent switches as follows to conserve horizontal space:</P><PRE><FONT COLOR="#0066FF">switch(variable){case ValueOne:ActionOne();break;case ValueTwo:ActionTwo();break;default:assert(&quot;bad Action&quot;);break;}</FONT></PRE><CENTER><H4><A NAME="Heading35"></A><FONT COLOR="#000077">Program Text</FONT></H4></CENTER><P>There are several tips you can use to create code that is easy to read. Code thatis easy to read is easy to maintain.<UL>	<LI>Use whitespace to help readability.	<P>	<LI>Objects and arrays are really referring to one thing. Don't use spaces within	object references (<TT>.</TT>, <TT>-&gt;</TT>, <TT>[]</TT>).	<P>	<LI>Unary operators are associated with their operands, so don't put a space between	them. Do put a space on the side away from the operand. Unary operators include <TT>!</TT>,	<TT>~</TT>, <TT>++</TT>, <TT>--</TT>, <TT>-</TT>, <TT>*</TT> (for pointers), <TT>&amp;</TT>	(casts), <TT>sizeof</TT>.	<P>	<LI>Binary operators should have spaces on both sides: <TT>+</TT>, <TT>=</TT>, <TT>*</TT>,	<TT>/</TT>, <TT>%</TT>, <TT>&gt;&gt;</TT>, <TT>&lt;&lt;</TT>, <TT>&lt;</TT>, <TT>&gt;</TT>,	<TT>==</TT>, <TT>!=</TT>, <TT>&amp;</TT>, <TT>|</TT>, <TT>&amp;&amp;</TT>, <TT>||</TT>,	<TT>?:</TT>, <TT>=</TT>, <TT>+=</TT>, and so on.	<P>	<LI>Don't use lack of spaces to indicate precedence (<TT>4+ 3*2</TT>).	<P>	<LI>Put a space after commas and semicolons, not before.	<P>	<LI>Parentheses should not have spaces on either side.	<P>	<LI>Keywords, such as <TT>if</TT>, should be set off by a space: <TT>if (a == b)</TT>.	<P>	<LI>The body of a comment should be set off from the <TT>//</TT> with a space.	<P>	<LI>Place the pointer or reference indicator next to the type name, not the variable	name:</UL><PRE><FONT COLOR="#0066FF">char* foo;int&amp; theInt;</FONT></PRE><UL>	<LI>rather than</UL><PRE><FONT COLOR="#0066FF">char *foo;int &amp;theInt;</FONT></PRE><UL>	<LI>Do not declare more than one variable on the same line.</UL><CENTER><H4><A NAME="Heading36"></A><FONT COLOR="#000077">Identifier Names</FONT></H4></CENTER><P>Here are some guidelines for working with identifiers.<UL>	<LI>Identifier names should be long enough to be descriptive.	<P>	<LI>Avoid cryptic abbreviations.	<P>	<LI>Take the time and energy to spell things out.	<P>	<LI>Do not use Hungarian notation. C++ is strongly typed and there is no reason to

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -