#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct info
{
int id;
char name[20];
};
int main()
{
struct info p;
struct info *ptr;
ptr = &p;
(*ptr).id = 20;
strcpy((*ptr).name, "Delluh");
printf("\n %u %u %u\n\n",*ptr,ptr->id,ptr->name);
return 0;
}
最后一个printf语句给我输出'20 1819043140 26741',其中20是正确的值,其余2个值是一些垃圾值。但是,在从ptr中删除*时,我得到一个正确的地址值输出,20然后是另一个地址值。任何人都可以告诉我为什么把*放在ptr前导致其他两个值搞砸了?
答案 0 :(得分:0)
如果您使用此
,那就不会更加正确printf("\n %p %i %s\n\n",ptr,ptr->id,ptr->name);
你在printf中使用%u(无符号整数)来表示所有参数,但是你传递了一个指针,整数和一个字符串参数我认为这就是你遇到的问题。 您应该查看printf documentation%s,%u,%i等参数的含义。
答案 1 :(得分:0)
因为那里有*
,你就是取消引用结构并传递整个事物in-id和name&amp; mdash。
Printf使用varargs,这基本上只是意味着您可以传入任意类型的任何类型的参数,但这也意味着编译器不会进行任何自动类型转换或检查(因为它不会知道期待什么类型)。因此,传入的参数最终会成为堆栈上的字节序列,格式字符串会告诉printf如何解释该字节串。除此之外,它告诉它要跳过多少字节才能到达下一个参数。
所以你想要ptr->id
第一个参数,它只有4个字节。但实际上你传递了结构的所有24个字节作为参数。因此,在printf完成打印前4个字节作为unsigned int之后,它已准备好打印下一个参数,但仍然停留在name字段的开头。如果你看,它打印的“垃圾”值是0x6C6C6544,它是4个ASCII字符“lleD”,这是你的字符串,被解释为小端整数。
一般情况下,你可以通过取消引用指针(指针指向结构及其第一个字段)从结构中拉出第一个字段,但只有当编译器知道你正在尝试的时候才会这样做根据类型做。例如,这可能会起作用:
int id = *ptr;
从技术上讲,至少可以工作,因为编译器知道你实际上想要达到的类型。实际上,编译器可能会发出错误或警告,您需要进行一些转换。