You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

结构体指针->运算符疑问:两次printf输出值不同原因求解

结构体指针链式访问的数值解释

让我一步步帮你拆解这个问题,先从代码的结构和内存布局说起~

首先贴出完整可运行的代码:

#include <stdio.h>
struct S {
    int Var;
    struct S *Str;
};

int main(void) {
    struct S S[] = { { 8, NULL }, { 4, &S[0] }, { 2, &S[1] } };
    printf("%d\n", S[2].Str->Str->Var); // 输出8
    printf("%d\n", S[2].Str->Var);     // 输出4
    return 0;
}

一、明确结构体数组的初始化内容

你定义的数组S包含3个struct S实例,初始化后每个实例的成员值非常清晰:

  • S[0]: Var = 8,Str = NULL(空指针)
  • S[1]: Var = 4,Str = &S[0](指向数组第一个元素S[0])
  • S[2]: Var = 2,Str = &S[1](指向数组第二个元素S[1])

二、拆解第一个输出:S[2].Str->Str->Var = 8

我们逐层解析这个链式访问的逻辑:

  1. S[2].Str:取出S[2]的Str成员,结果是&S[1](一个指向S[1]的指针)
  2. S[2].Str->Str:通过指针访问S[1]的Str成员,结果是&S[0](指向S[0]的指针)
  3. S[2].Str->Str->Var:通过指针访问S[0]的Var成员,直接得到8——这就是第一个输出的来源。

三、拆解第二个输出:S[2].Str->Var = 4

同样逐层拆解:

  1. S[2].Str:依然是&S[1](指向S[1]的指针)
  2. S[2].Str->Var:通过指针访问S[1]的Var成员,直接得到4——这就是第二个输出的原因。

关于你提到的“指针占用8字节、地址间隔8字节”的疑问

你可能混淆了结构体实例的内存大小/数组元素的地址间隔和结构体成员的偏移量:

  • 在64位系统中,指针确实占8字节,int通常占4字节。由于内存对齐规则,每个struct S实例的大小会是16字节(Var后面会填充4字节空白,以对齐到8字节的指针边界),所以数组S中S[0]、S[1]、S[2]的地址间隔是16字节。
  • 但Var是结构体的第一个成员,它的内存偏移量永远是0。不管结构体整体多大,通过指针访问->Var时,都是直接取指针指向地址的前4字节(对应实例的Var值),这和指针本身的大小、数组元素的地址间隔没有关系。

内容的提问来源于stack exchange,提问作者Noel Nosse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:00:53