【发布时间】:2021-10-25 03:32:50
【问题描述】:
struct student
{
int roll_no;
int physics;
int chem;
float percentage;
};
int main()
{
struct student s = {1, 96, 98, 97.00};
printf("%d", *((int *) &s + 1));
}
在上面的代码中,我们知道's'是一个结构变量,我的问题是什么
's' 是衰减指针还是为结构分配了单独的堆栈帧,如果它是衰减指针,我们不必将 '&' 与 's' 放在一起,所以我猜它必须是一个堆栈帧,因为它的行为就像一个普通变量。
如果我们打印's',第一个成员的值就会被打印出来,如果我们打印'&s',第一个成员的地址就会被打印出来。
如果不是这个,请帮助我们理解。
还有,
如果 Char 数组是结构的成员,如何访问,试过这个 *((char*)&s + offset_value); 不起作用。
您的帮助将不胜感激。
【问题讨论】:
-
你能不能只用'.'访问字段而不是指针?
-
强制转换结构是 C 中未定义的行为。这意味着:“(int *) s”是未定义的行为,因为“s”不是原始类型(char、short、int 等) .但是, (int *) &s 非常好,它会为您提供结构包含的第一个整数。
-
"'s' 是衰减指针还是为结构分配了单独的堆栈帧,如果它是衰减指针,我们不必将 '&' 与 's ' 所以我猜它一定是一个堆栈帧,因为它的行为就像一个正常的变量。”这没有任何意义。
s是一个结构。它不是一个数组,所以它不会“衰减”。它不是“堆栈框架”。您似乎混淆了许多非常不相关的术语。 -
@tstanisl:相比之下,
*((int *) &s + 1)的行为没有定义。如上,这相当于*(&s.roll_no + 1)。&s.roll_no + 1已定义;它是一个指向s.roll_no末尾的指针。但是,没有定义用*解引用它,因为C 2018 6.5.6 8 表示如果+的结果像这样指向末尾,“它不应用作一元*的操作数被评估的运算符。”换句话说,即使我们可以推断出指针指向的内存中的内容是另一个int,但有一个明确的规则说我们不能在上面使用*。 -
@EricPostpischil,我仍然有疑问。我不认为
*(&s.roll_no + 1)等同于*((int*)&s + 1)。第一个产生一个源自s.roll_no对象的指针,即int。因此,增加的指针确实不能被取消引用。另一方面,((int*)&s + 1)源自对象s,因此生成的指针不会“溢出”原始对象。假设((int*)&s + 1)无效,memcpy会使用这样的指针吗?那么(int*)((char*)&s + sizeof(int))是否有效?
标签: c