home *** CD-ROM | disk | FTP | other *** search
/ C++ for Dummies (3rd Edition) / C_FD.iso / WORKOUT / PART2.TXT < prev    next >
Text File  |  1996-09-06  |  4KB  |  113 lines

  1. 25-Minute Workout
  2. Part II Answers
  3. 1
  4.     a.    This is the list that I came up with:
  5.     *    If the argument is an expression with an operator of lower precedence than 
  6. multiplication, the results will be wrong because x is not surrounded by parentheses. 
  7. For example:
  8. TWO_MAX(3 + a, b) ==> 3 + a > b ? (2 * 3 + a) : (2 * b)
  9.         which, given the precedence of the operators, is interpreted as
  10. TWO_MAX(3 + a, b) ==> ((3 + a) > b) ? ((2 * 3) + a) : (2 * b)
  11.         Notice the appearance of (2*3)+a instead of the intended 2*(3+a).
  12.     *    If the macro is involved in an expression with operators of the same or higher 
  13. precedence, the results will be wrong because the expression is not surrounded by 
  14. parentheses. Consider the following example:
  15. a = 2 * TWO_MAX(b, c); ==> a = 2 * b > c ? b : c;
  16.         which is interpreted as
  17. a = (2 * b) > c ? b : c;
  18.     *    If the macro is invoked with an argument that has side effects, the side effects will 
  19. ôtake effectö twice because x appears more than once. This is demonstrated in the 
  20. following snippet
  21. a = TWO_MAX(b++, c) ==> a = b++ > c ? b++ : c;
  22.         If b++ is greater than c, b is actually incremented twice.
  23.     b.    These problems can be corrected by making the macro an inline function:
  24.     //twoMax - implement as an inline function
  25.     inline twoMax(int x, int y)
  26.     {
  27.         return x > y ? 2 * x; 2 * y;
  28.     }
  29.         This inline version does not suffer from any of the problems mentioned previously.
  30. 2
  31. As with most profound questions of our time, the answer is in the question. It is possible to overload the 
  32. function with another function of the same name, which can then turn around and call our function with the 
  33. default value. You can even make this ersatz function inline if youÆre really worried about performance 
  34. overhead:
  35. #include <iostream.h>
  36. void aFunc(int x, float y, char z)
  37. {
  38.    cout << ôx = ô << x << ô, y = ô << y << ô, z = ô << z << ô\nö;
  39. }
  40. inline void aFunc(int x, char z)
  41. {
  42.    aFunc(x, 0.0, z);
  43. }
  44. int main()
  45. {
  46.    aFunc(1, 2.0, æ3Æ );   //calls the function
  47. aFunc(4, æ5Æ );        //calls the ersatz function
  48.    return 0;
  49. }
  50. Executing the simple test program generates the following results:
  51. x = 1, y = 2.0, z = 3
  52. x = 4, y = 0.0, z = 5
  53. 3
  54. Here are how the calls match up:
  55.     a.    Calls 1; this is straightforward
  56.     b.    Calls 2; a constant character string is of type char*
  57.     c.    Calls 3; any pointer type can be converted to void*
  58.     d.    Calls 1; a character can be promoted to an int
  59.    e.    Ambiguous between 4 and 5; the int could be converted to either
  60. 4
  61. Without a declaration to tell it otherwise, C++ would assume that printf() is a C++ function and attempt to 
  62. mangle the name. The stdio.h include file includes extern ôCö declarations to make sure that C++ knows 
  63. that this is a C function.
  64. 5
  65. My solution using printf() and scanf() I/O follows:
  66. #include <stdio.h>
  67. void fn(int &x, int &y)
  68. {
  69.    printf(ôEnter x & y:ö);
  70.    scanf(ô%d%dö, &x, &y);
  71. }
  72. void main() {
  73.    int i, j;
  74.    fn(i, j);
  75.   printf(ôi = %d, j = %d\nö, i, j);
  76. }
  77. Notice that you still have to pass the address of x and y to scanf() because it knows nothing about 
  78. referential arguments. The remainder of both the calling and called functions are simpler.
  79. The stream I/O solution makes no direct reference to pointers:
  80. #include <iostream.h>
  81. void fn(int &x, int &y) {
  82.    cout << ôEnter x & y:ö;
  83.    cin  >> x >> y;
  84. }
  85. void main() {
  86.    int i, j;
  87.    fn(i, j);
  88.    cout << ôi = ô << I
  89.         << ô, j = ô << j
  90.         << ô\nö;
  91. }
  92. 6
  93. Here is my solution:
  94. Davis multiply(Davis&, Davis &);
  95. Davis multiply(Davis &, float);
  96. Davis multiply(float, Davis &);
  97. float   multiply(float, float);
  98. Notice that Davis, float must be listed twice: the first time with Davis first and the second time with float 
  99. first. There is no association between the two functions. (One of the functions can be an inline function that 
  100. calls the other, so itÆs not a big deal.)
  101. 7
  102. My solution is as follows:
  103. #include <iostream.h>
  104. int main()
  105. {
  106.    cout << ôHello, world\nö;
  107.    return 0;
  108. }
  109. Notice that stdio.h has been replaced by iostream.h. This is critically important. Without iostream.h, C++ 
  110. will not recognize << as the insertion operator.
  111.  
  112.  
  113.