题一:
这道题目的考察点是 sizeof 操作符。
在ANSI C ISO/IEC 9899:1999(E)里面,6.5.3.4节对 the sizeof operator做了如下说明:
The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member.
The operand can be an expression or the parenthesized name of a type.
If the type of operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.
The value of result is implementation-define, and its type is size_t (an unsigned integer type), defined in <stddef.h>.
注:variable length array type为C99引入的新特性
按照这个说明,显然在Line 2,i的值在编译期使用常量替换了;而Line 4,因为sizeof的操作数是一个变长数组,故i值是在程序运行期确定的。
答案:
1 100
4294967292 -1
4294967288 -2
注:unsigned(-1 * 4) == 4294967292, unsigend(-2 * 4) == 4294967288
下面新增几个,作为思考题:
题二: 该题考察点指针运算:
(1)、对一个变量取地址,则其类型为一个指向该变量类型的指针,这里&a,a为一个具有5个元素的整形数组,故&a获得的是一个指向具有5个元素的整形数组的指针。注:如果
在gcc编译环境下,Line 3会产生一个"warning: initialization from incompatible pointer type" ,原因很简单,ptr是一个整形指针,而&a不是
(2)、指针与常量的加减,这里三条语句是等效的:
注:两个指针变量相减,则必须要求二者为同一类型的指针,且无论两个指针变量是否为相同类型,均不能相加,否则编译无法通过,产生如下错误"invalid operands to binary -"
题三: 该题涉及的知识点有静态变量、函数参数压栈顺序(一般为从右向左压栈)、函数参数计算顺序(编译器相关)等。
注:stdcall、cdecl所表示的是函数调用约定,二者的参数压栈顺序均为从右向左;不同之处是cdecl调用约定,函数本身不清理堆栈,调用者负责清理堆栈,而stdcall则是被调用者自己恢复堆栈,故stdcall不能支持变长参数函数,因此printf这类函数只能是cdecl调用约定。
gcc 4.0.2编译环境下的答案为:
2 2
4 3
使用gcc编译出的汇编代码如下:
题四:求结构体中某个成员变量的偏移量
1、gcc 4编译器中带有offsetof宏,利用该宏可直接求得偏移量,实例代码如下:
2、自行实现offsetof宏,定义如下: