先决条件:结构填充,整数提升和序列点。
Q1。考虑以下代码:
#include
struct geeks{
int i;
char c;
} obj;
int main()
{
printf("%ld", sizeof(obj));
}
上面的代码的输出是什么?
A.4
B.5
C.8
D.无法确定
Output: Can't be determined
解释:
这都是关于结构填充的。 C编译器知道在RAM中存储未对齐的数据可能会很昂贵,因此它会根据需求填充数据。如果一个结构中有5个字节的数据,它可能会变成8或16或6。有一些对齐和打包的扩展,例如GCC属性,可以对这个过程进行一些控制,但是它们是非标准的。 C本身未定义填充属性。因此正确的答案是“无法确定”。
Q2。考虑以下代码:
#include
int main(){
char a = 0;
short int b = 0;
printf("%d", sizeof(b) == sizeof(a+b));
return 0;
}
上面的代码的输出是什么?
A.0
B.1
C.2
D.无法确定
Output: Can't be determined
说明:全部与整数提升有关。当对它们进行计算时,诸如“ char”,“ short int”之类的数据类型会自动提升为“ int”。但是即使这样,表达式(sizeof(b)== sizeof(a + b))也会比较大小而不是类型,并且根据C标准,可以保证’short int’的大小不能大于’int的大小’。因此,我们无法确定“ sizeof(a + b)”将返回什么,因此正确的答案是“无法确定”。
Q3。考虑以下代码:
#include
int main()
{
char a = ' ' * 13;
printf("%d", a);
return 0;
}
上面的代码的输出是什么?
A. 416
B. 160
约-96
D.无法确定
Output: Can't be determined
解释:
空格字符(”)的ASCII值为32,首先,表达式(”* 13)不会整数溢出(由于整数提升),因此行为是不确定的。其次,“ char类型”(有符号或无符号)不是由标准定义的,因此它将是特定于实现的。
但更重要的是,char类型本身的大小也未按位指定。在某些平台上,它是6位(三边形),在某些平台上,所有五个整数类型都是32位。如果未指定所有这些详细信息,则对结果的任何猜测都是无效的,因此答案是:“无法确定”。
Q4。考虑以下代码:
#include
int main()
{
int i = 16;
printf("%d", (((i >= i) << i) >> i) <= i);
return 0;
}
上面的代码的输出是什么?
A.0
B.1
C.16
D.无法确定
Output: Can't be determined
解释:
上面的表达式的输出取决于编译器,因为’int’的大小不是在C标准中直接指定的。它可以很容易地是16位,然后比较之后的第一个操作((i> = i)<< i)会导致移位,这是普通的未定义行为。这不是C错误,在某些平台上甚至在汇编中都未定义,因此编译器根本无法给出上述表达式的有效保证。因此,答案将是“无法确定”。
Q5。考虑以下代码:
#include
int main()
{
int i = 0;
int ans = i++ + ++i;
printf("%d ", ans);
return 0;
}
上面的代码的输出是什么?
A.1
B.2
C.3
D.无法确定
Output: Can't be determined
解释:
在C语言中,表达式“ i ++ + ++ i ”没有意义,因为它违反了相同的变量没有序列点不能多次更改的规则。顺序点基本上是代码中编译器保证已完成所有评估的点。例如,语句末尾的分号是一个序列点。
在此表达式中,变量“ i”的值两次更改而没有序列点。因此,编译器可以执行任何所需的操作,并且会导致未定义的行为。因此,答案将是“无法确定”。
参考资料:https://hackernoon.com/so-you-think-you-know-c-8d4e2cd6f6a6