这本是原文的一部分,每个答案的解析分别在原文对应的题目下面,这里单独列出,方便参考。
原文链接:http://stevenkobes.com/ctest.html
本博客内转载的原文:http://www.cnblogs.com/bloog/articles/2091042.html
解析:
1.
Answer: (b)
The setjmp function stores context information for a “non-local goto”, and returns 0. The longjmp function transfers control to the setjmp call that initialized buf, and execution continues from this point as if setjmp had returned 1.
Note: a non-volatile automatic variable that has been modified after setjmp becomes indeterminate after longjmp. Without the volatile qualifier, this program’s behavior would be undefined. This rule permits better optimization of code.
2.
Answer: (a)
The members of structs are arranged sequentially in memory, in the order of their declaration. If a pointer to a struct is cast to the type of a pointer to its first member, the result points to its first member.
3.
Answer: (a)
Consider small values of n:
foo(x, 0) = 1foo(x, 1) = x * foo(x, 0) = xfoo(x, 2) = foo(x * x, 1) = x * xfoo(x, 3) = x * foo(x, 2) = x * (x * x)
An initial guess, from this pattern, of xn can be formally verified by induction:
Base cases of n = 0 and 1 are trivial.
Suppose foo(x, n) computes xn for all nonnegative n less than some i > 1.
If i is odd, foo(x, i) computes x * foo(x * x, (i – 1) / 2) = x * (x * x)(i – 1) / 2 = x * xi – 1 = xi.
If i is even, foo(x, i) computes foo(x * x, i / 2) = (x * x)i / 2 = xi.
By induction foo(x, n) computes xn for all nonnegative n.
4.
Answer: (c)
Since a has type array[5] of int, &a has type pointer to array[5] of int. Thus &a + 1 yields a pointer to the (non-existent) array[5] of int that comes after a, and ptr points to the (non-existent) int that comes after a. Subtracting 1 from ptr yields a pointer to the last element of a.
Note: in general, you can’t use the value of non-NULL pointer that does not point to a valid object. However, an exception is made for pointers that point one past the end of an array. This makes the initialization of ptr legal, even though it can’t be dereferenced.
5.
Answer: (b)
In foo, b has type pointer to array[3] of int, and after the increment, it points to the array a[1] ({4, 5, 6}). So b[1] has type array[3] of int, and it denotes the array a[2] ({7, 8, 9}). In value context, b[1] “decays” into a pointer to a[2][0] (7), so b[1][1] denotes a[2][1], whose value is changed from 8 to 9.
6.
Answer: (c)
The comma operator evaluates both of its operands and produces the value of the second. It also has lower precedence than assignment. Hence c = a, b is equivalent to c = a, while d = (a, b) is equivalent to d = b.
7.
Answer: (a)
Here, a has type array[2] of array[3] of int, and ptr initially points to the first array[3] ({1, 2, 3}). After the increment, it points to the second array[3] ({4, 5, 6}). Of course, *ptr denotes the array[3] that ptr happens to point to.
8.
Answer: (c)
Function f1 returns the address of a local variable. Since the variable’s lifetime ends after the function returns, any use of the return value produces undefined behavior.
Function f2 produces undefined behavior because it dereferences and returns an uninitialized pointer. (It has not been assigned to point to anything, and its initial value is indeterminate.)
Function f3 has no errors (although its caller should make sure the return value is not NULL before using it, and call free when the memory is no longer needed).
9.
Answer: (b)
Evaluating ++i + ++i would produce undefined behavior, but the operand of sizeof is not evaluated, so i remains 3 throughout the program. The type of the expression (int) is deduced at compile time, and the size of this type (2) is assigned to j.
10.
Answer: (a)
The type of p is array[2] of pointers to functions taking (int*, int) and returning void; p[0] and p[1] point to f1 and f2, respectively. Notice that f1 and f2 are identical.
Since arguments are passed by value, the assignment to q does not affect b, and p[0](&a, b) is equivalent to a = b.
11.
Answer: (a)
In pseudo-code,
e(0), e(-1) -> {}
e(1) -> {e(0), print 0, e(-1)} -> {{}, print 0, {}} -> {print 0}
e(2) -> {e(1), print 1, e(0)} -> {{print 0}, print 1, {}} -> {print 0, 1}
e(3) -> {e(2), print 2, e(1)} -> {{print 0, 1}, print 2, {print 0}} -> {print 0, 1, 2, 0}.
12.
Answer: (c)
The typedef declaration creates a synonym for a type, which can then be used to declare objects of that type. Note that the new name for the type appears in the position of a variable name, as though you were declaring a variable (which you’re not). This can make it seem backwards in comparison to the syntax of a #define directive.
13.
Answer: (c)
Remember that x[i] is equivalent to *(x + i), so (buf + 1)[5] is *(buf + 1 + 5), or buf[6].
14.
Answer: (b)
In f, p initially points to the first char* ("ab") in the array of pointers argv. Adding sizeof(int) = 2 to p makes it point to the third char* ("ef"), after which p[-1] denotes the second char* ("cd").
15.
Answer: (c)
The va_arg macro produces the arguments passed as the “...” part of a variadic function. In ripple it will be called twice, setting i first to 5, then to 7.
The expression i &= i - 1 resets the right-most 1 bit in i. For example, if i is 6 (binary 110), i & i - 1 is 4 (binary 100). The inner for loop executes until i is 0, so k is increased by the number of 1 bits in i.
There are two 1 bits in 5 (binary 101) and three in 7 (binary 111), so ripple returns 5.
16.
Answer: (b)
Since count is static, it maintains its value across calls to counter. Its final value is the sum of the integers from 0 to 5.
浙公网安备 33010602011771号