#include<stdio.h>
struct test{
int a;
int b;
}m;
int main()
{
m.a=5;m.b=7;
struct test *p;
p = &m;
printf("p[0] = %d\n",*(p+0));
printf("p[1] = %d\n",*(p+1));
return 0;
}
我得到以下输出:
p [0] = 5 p [1] = 0
有人可以解释一下这种行为吗?有没有办法使用索引打印所有结构成员?
对于错字感到抱歉。
(更新)
因为我可以使用索引0打印第一个元素,虽然指针的类型是“struct test type”,第一个成员是一个整数,但我可以得到正确的值。因此,问题引发了这种行为的原因。如果可以使用索引访问所有成员,就像访问第一个成员一样。
答案 0 :(得分:2)
在您的代码中,
printf("p[0] = %d\n",*(p+0));
printf("p[0] = %d\n",*(p+1));
%d
格式说明符传递了错误的参数类型。*(p+1)
因此,无法以任何方式解释或证明输出。
现在,那就说了,让我们稍微分析一下代码。
首先,
p = &a;
是错误的,因为没有名为a
的变量。结构变量a
有一个成员变量 m
,可以m.a
访问。所以,你可以以某种方式写
p = (struct test*) &m.a;
现在,使用结构的第一个元素的地址作为结构地址是有效的,因为在结构的开头没有填充。但这并不意味着,您可以在结构指针p
上直接应用指针算法 并获取每个成员变量,主要是因为
p
的类型为struct test
(虽然您可以通过投射来解决)答案 1 :(得分:1)
获取正确的编译器。使用GCC 5上的默认设置进行编译,编译吐出:
foo.c: In function ‘main’:
foo.c:12:10: error: ‘a’ undeclared (first use in this function)
p = &a;
^
foo.c:12:10: note: each undeclared identifier is reported only once for each function it appears in
foo.c:13:12: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘struct test’ [-Wformat=]
printf("p[0] = %d\n",*(p+0));
^
foo.c:14:12: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘struct test’ [-Wformat=]
printf("p[0] = %d\n",*(p+1));
^
也许你的意思是p = &m;
。
之后,您的代码将调用未定义的行为。 %d
期望相应的参数为int,但您提供struct test
。此外,在后一个打印件上,指针在m
之后指向未初始化的内存,并且打印出垃圾。即使您在第一种情况下打印5
这一事实也无法依赖。 C标准没有解释为什么或为什么不这种情况发生,C标准说&#34;此时编译器可以生成打印的代码42342,崩溃程序,或做任何其他事情,这个标准就好了。&#34;
在C编译器中,警告通常意味着&#34;标准违规&#34;在这种情况下,可能存在未定义的行为。 C编程语言的新手应始终考虑所有编译器警告,尤其是默认设置为致命错误。
答案 2 :(得分:1)
我用gcc编译你的代码,我得到了。
In function ‘main’:
error: ‘a’ undeclared (first use in this function)
p = &a;
^
note: each undeclared identifier is reported only once for each function it appears in
warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘struct test’ [-Wformat=]
printf("p[0] = %d\n",*(p+0));
^
warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘struct test’ [-Wformat=]
printf("p[0] = %d\n",*(p+1));
假设您的意思是p=&m
,这是我的解释
printf("p[0] = %d\n",*(p+0));
printf("p[0] = %d\n",*(p+1));
首先分析像你在printf函数中那样推迟指针是否正确。
*(p+0)
将允许您访问struct test variabe m
。因为,您已将struct test
类型的变量的地址分配给指针p
,延迟指针*p
或*(p+0)
将允许您访问变量{{1 }}。但是分配给指针的地址是一个不属于m
类型数组的单个变量,延迟struct test
会给你 UNDEFINED BEAVAVIOR 。例如,如果((p+1)
)
*(p+1)
就会有效
not in printf statement
有没有办法使用索引打印所有结构成员?
你可以。但是c中的运营商没有超载。所以,你可以通过 -
实现这一目标struct test m[20];
struct test *p;
(*(p+0)).a=2;
(*(p+1)).a=5;
如果指针printf("a=%d, b=%d", p->a, p->b);
指向类型为p
的数组,则可以在printf中使用index作为
struct test
我对您未来代码实验的建议将首先分析您的代码给出的警告和错误。警告可以帮助纠正代码中的大多数错误。我总是使用gcc / g ++编译器编译我的c / c ++代码,并使用-Wall,-Wshadow,-Wextra等标志。如果您不理解,可以发出警告。
答案 3 :(得分:0)
您直接将a
的地址指定给p
。 a
是m
的成员,因此无法直接访问。从代码开始,您应该使用整数指针进行算术运算。
您需要修改代码的一部分
struct test *p;
p = &a;
到
int *p;
p = &m.a;
现在代码应该按照您的意愿工作。
答案 4 :(得分:0)
首先,您的代码中有拼写错误。
请从p = &a;
更改为p = &m;
,以便删除编译器抱怨的错误。
其次,我猜您期望输出为p [0] = 5且p [1] = 7。 为此,请从
修改代码printf("p[0] = %d\n",*(p+0));
printf("p[1] = %d\n",*(p+1));
到
printf("p[0] = %d\n",p->a);
printf("p[1] = %d\n",p->b);
可以工作。