C中联合后的“++”是什么意思?

What's the meaning of "++" after a union in C?

这是代码

int AreSymEquivalent_hkl(const T_SgInfo *SgInfo, int h1, int k1, int l1,
                                                 int h2, int k2, int l2)
{
  int     iList, mh2, mk2, ml2, hm, km, lm;
  T_RTMx  *lsmx;


  mh2 = -h2;
  mk2 = -k2;
  ml2 = -l2;

  /* check list of symmetry operations */

  lsmx = SgInfo->ListSeitzMx;

  for (iList = 0; iList < SgInfo->nList; iList++, lsmx++)
  {
    hm = lsmx->s.R[0] * h1 + lsmx->s.R[3] * k1 + lsmx->s.R[6] * l1;
    km = lsmx->s.R[1] * h1 + lsmx->s.R[4] * k1 + lsmx->s.R[7] * l1;
    lm = lsmx->s.R[2] * h1 + lsmx->s.R[5] * k1 + lsmx->s.R[8] * l1;

    if      ( h2 == hm &&  k2 == km &&  l2 == lm)
      return  (iList + 1);

    else if (mh2 == hm && mk2 == km && ml2 == lm)
      return -(iList + 1);
  }

  return 0;
}

这是一个函数,定义自计算晶体学领域的一个相当著名的包 'sginfo'。 (如果需要可以从这里下载:https://github.com/rwgk/sginfo/tree/master/sginfo_1_01) 所以我确定它没有错误。问题在行

  lsmx = SgInfo->ListSeitzMx;

  for (iList = 0; iList < SgInfo->nList; iList++, lsmx++)

其中 "SgInfo" 是一个大结构,我没有把它放在这里,包含 "ListSeitzMx" -- 一个名为 "T_RTMx" 的联合的属性,它包含一些矩阵信息。定义如下:

typedef union
  {
    struct { int R[9], T[3]; } s;
    int                        a[12];
  }
  T_RTMx;

这是让我感到困惑的部分,联合后的“++”。我所知道的是“++”之前的int值加1,但是union类型就没有意义了。或者我在整件事上犯了一个大错误? "lsmx" 不是工会之类的…… 作为 C 的初学者,我曾尝试写一个关于这个问题的小测试脚本,但错误让我抓狂。所以我最终决定发布这个问题...

lsmx++

相当于

( orig = lsmx, lsmx = lsmx + 1, orig )

换句话说,

  • lsmx++lsmx 上加一(就好像你已经完成了 (lsmx = lsmx + 1).

  • lsmx++ 的计算结果为 lsmx 的原始值,但在您的代码中被丢弃了。

lsmx 是一个指针。向指针添加 1 会增加指向对象的大小 (sizeof(*lsmx)) 的地址。

例如,

T_RTMx foo[5] = ...;
T_RTMx *lsmx = foo;   # Same as &( foo[0] )   # Points to foo[0]
lsmx++;                                       # Points to foo[1]
lsmx += 2;                                    # Points to foo[3]

请记住 a[b] 完全等同于 *(a+b)

你实际上并没有加入联盟。您正在添加地址。

考虑类似的情况:

struct abc {
    int a, b, c;
    //Lots more nonsense
};

现在,

struct abc z;
struct abc *a;
a = &z

这表明 a 存储 struct abc 类型的地址。

现在让我们修改指针的工作方式。

假设 z 位于 1000 的位置。 a 存储了该值。当我执行 *a 时,我指的是内存位置 1000sizeof(struct abc)。由于 a 是指向类型 struct abc 的指针,您可以这样做:

a->c = 2;

或类似的东西。

当你说:

int *b;

它实际上可以存储任何其他类型的地址。如果你真的喜欢冒险,你可以这样做:

b = &z;

您可能会收到警告,也可能不会收到警告,具体取决于您的编译器。

当我存储 &z 时,编译器唯一做的就是将 z 地址处的值视为 int。所以 b 的值为 1000.

现在,当您执行 *b 时,您将地址 1000 引用到 sizeof(int)

总结一下,

b++;

这会做 1000 + sizeof(int),然后到达下一个 int

a++;

会做 1000 + sizeof(struct abc).