knking.com -- Programming Language Books and Training

 C C++ Java

Books by K. N. King

Home
Books by K. N. King
Short courses
Recommended books
Recommended links
FAQ

C Programming: A Modern Approach (Second Edition)

Chapter 14

Answers to Selected Exercises

2. [was #2] #define NELEMS(a) ((int) (sizeof(a) / sizeof(a[0])))

4. [was #4]

(a) One problem stems from the lack of parentheses around the replacement list. For example, the statement

a = 1/AVG(b, c);

will be replaced by

a = 1/(b+c)/2;

Even if we add the missing parentheses, though, the macro still has problems, because it needs parentheses around x and y in the replacement list. The preprocessor will turn the statement

a = AVG(b<c, c>d);

into

a = ((b<c+c>d)/2);

which is equivalent to

a = ((b<(c+c)>d)/2);

Here's the final (corrected) version of the macro:

#define AVG(x,y) (((x)+(y))/2)

(b) The problem is the lack of parentheses around the replacement list. For example,

a = 1/AREA(b, c);

becomes

a = 1/(b)*(c);

Here's the corrected macro:

#define AREA(x,y) ((x)*(y))

5. [was #6]

(a) The call of putchar expands into the following statement:

putchar(('a'<=(s[++i])&&(s[++i])<='z'?(s[++i])-'a'+'A':(s[++i])));

The character a is less than or equal to s[1] (which is b), yielding a true condition. The character s[2] (which is c) is less than or equal to z, which is also true. The value printed is s[3]-'a'+'A', which is D (assuming that the character set is ASCII).

(b) The character a is not less than or equal to s[1] (which is 1) so the test condition is false. The value printed is s[2], which is 2.

7. [was #8]

(a)

long long_max(long x, long y)
{
  return x > y ? x : y;
}

The preprocessor would actually put all the tokens on one line, but this version is more readable.

(b) The problem with types such as unsigned long is that they require two words, which prevents GENERIC_MAX from creating the desired function name. For example, GENERIC_MAX(unsigned long) would expand into

unsigned long unsigned long_max(unsigned long x, unsigned long y)
{
  return x > y ? x : y;
}

(c) To make GENERIC_MAX work with any basic type, use a type definition to rename the type:

typedef unsigned long ULONG;

We can now write GENERIC_MAX(ULONG).

12. [was #10] (c) and (e) will fail, since M is defined.

14. [was #12; modified] Here's what the program will look like after preprocessing:

Blank line
Blank line
Blank line
Blank line
Blank line
Blank line
Blank line

int main(void)
{
  int a[= 10], i, j, k, m;

Blank line
  i = j;
Blank line
Blank line
Blank line

  i = 10 * j+1;
  i = (x,y) x-y(j, k);
  i = ((((j)*(j)))*(((j)*(j))));
  i = (((j)*(j))*(j));
  i = jk;
  puts("i" "j");

Blank line
  i = SQR(j);
Blank line
  i = (j);

  return 0;
}

Some preprocessors delete white-space characters at the beginning of a line, so your results may vary. Three lines will cause errors when the program is compiled. Two contain syntax errors:

int a[= 10], i, j, k, m;
i = (x,y) x-y(j, k);

The third refers to an undefined variable:

i = jk;

Copyright © 2008, 1996 W. W. Norton & Company, Inc. All rights reserved.

Google
 
Web knking.com