以下是一些更改(感谢 AndreyT):
显然,您必须更改标头才能进行编译。但即便如此,这似乎不是AndreyT 指出的标准C。尽管如此,像 gcc 这样的编译器仍然会按预期编译它并且只发出警告。同样,Microsoft 似乎并没有过于严格地解释标准:
“当结构声明是另一个结构或联合的成员时,也可以在没有声明符的情况下指定结构声明”
要使其成为标准 C,您必须将“struct yy”声明转换为定义。那么您的代码将在 C 和 C++ 中有效。为了说明发生了什么,我以一种我认为更易于理解的方式重写了它,并添加了一个关于发生了什么的小测试。
#include<stdio.h>
#include<stdlib.h>
typedef struct xx xx;
typedef struct yy yy;
struct yy{ char s; xx *p;};
struct xx{ int x; yy *q;};
int main(){
xx test;
test.q = (yy*)malloc(sizeof(yy));
test.q->s = 'a';
test.q->p = (xx*)malloc(sizeof(xx));
test.q->p->x = 1;
test.q->p->q = (yy*)malloc(sizeof(yy));
test.q->p->q->s = 'b';
printf("s: %c\n", test.q->s);
printf("x: %d\n", test.q->p->x);
printf("s: %c\n", test.q->p->q->s);
return 0;
}
您可以很容易地看到,您有一个带有指向 xx 的指针的结构 yy,而结构 xx 有一个指向 yy 的指针。这相当于在 ansi-C 中可以这样写:
#include<stdio.h>
#include<stdlib.h>
int main(){
struct xx{
int x;
struct yy{
char s;
struct xx *p;
} *q;
/*Here is the change to your example. You cannot have a structur
without a declactor inside of another structur!
Your version might due to compiler extensions still work*/
};
struct xx test;
test.q = (struct yy*)malloc(sizeof(struct yy));
test.q->s = 'a';
test.q->p = (struct xx*)malloc(sizeof(struct xx));
test.q->p->x = 1;
test.q->p->q = (struct yy*)malloc(sizeof(struct yy));
test.q->p->q->s = 'b';
printf("s: %c\n", test.q->s);
printf("x: %d\n", test.q->p->x);
printf("s: %c\n", test.q->p->q->s);
return 0;
}
我用 gcc 和以下选项编译它:
gcc -ansi -pedantic -Wall -W -Wshadow -Wcast-qual -Wwrite-strings test.c -o
两种变体将具有相同的输出
s: a
x: 1
s: b
现在,如果您想在 c++ 中做同样的事情,您的结构不必更改,但要使用内部结构,您必须调用范围解析运算符 (::),如下所示:
test.q = (xx::yy*)malloc(sizeof(xx::yy));
test.q->s = 'a';
test.q->p = (xx*)malloc(sizeof(xx));
test.q->p->x = 1;
test.q->p->q = (xx::yy*)malloc(sizeof(xx::yy));
test.q->p->q->s = 'b';
printf("s: %c\n", test.q->s);
printf("x: %d\n", test.q->p->x);
printf("s: %c\n", test.q->p->q->s);