C 同一结构对象在两个不同函数中的变量地址不同

C 同一结构对象在两个不同函数中的变量地址不同,c,C,我有两个函数,一个是main,另一个是display,使用结构初始化变量id和name,并在显示值时显示。主功能和显示功能的值不同 #include<stdio.h> #include<conio.h> struct Person { int id; char name[]; }; void display(struct Person p) { printf("\n\n value: \n Id is : %d And name is: %s \n

我有两个函数,一个是main,另一个是display,使用结构初始化变量id和name,并在显示值时显示。主功能和显示功能的值不同

#include<stdio.h>
#include<conio.h>

struct Person
{
  int id;
  char name[];

};

void display(struct Person p)
{
  printf("\n\n value: \n Id is : %d   And name is: %s  \n ",p.id,p.name);
   printf("Address: \nThe addres in  function of id is %p and name  is %p \n .........  \n",&(p.id),&(p.name));
}

void main()
{
  struct Person p;
  clrscr();
  p.id=2;
  strcpy(p.name,"kunal");
  printf("Values : \n the id is %d and name is %s \n",p.id,p.name);
  printf("Address: \n The addres in main of id is %p and name is %p",&(p.id),&(p.name));

  display(p);
  getch();
}
#包括
#包括
结构人
{
int-id;
字符名[];
};
无效显示(结构人p)
{
printf(“\n\n值:\n Id为:%d,名称为:%s\n”,p.Id,p.name);
printf(“地址:\n id函数中的地址是%p,名称是%p\n………\n”,&(p.id),&(p.name));
}
void main()
{
结构人p;
clrsc();
p、 id=2;
strcpy(p.name,“kunal”);
printf(“值:\n id是%d,名称是%s\n”,p.id,p.name);
printf(“地址:\n id的主地址是%p,名称是%p”,&(p.id),&(p.name));
显示器(p);
getch();
}
输出:

价值观:

id为2,名称为kunal

地址:

id的主地址为FFEA,名称为FFEC

价值:

Id为:2,名称为:kunal

地址:


id函数中的addres是FFDE,name是FFE0,只是在代码中添加了数组的大小,它在编译时具有固定的大小

不要使用非常旧的
conio.h

h是一个C头文件,主要由MS-DOS编译器用于提供 控制台输入/输出。它不是C标准库或ISO的一部分 C、 POSIX也没有定义它

#包括
#包括
结构学生
{
int-id;
字符名[20];
};
int main()
{
struct student record={0};//初始化为null
记录id=1;
strcpy(record.name,“无人”);
printf(“Id是:%d\n”,record.Id);
printf(“名称是:%s\n”,record.Name);
返回0;
}

在此结构声明中:

,则
名称
成员是所谓的“灵活数组成员”。这不是你想要达到的目的,特别是因为

在大多数情况下,将忽略灵活数组成员

()

例外情况与通过
->
操作符访问灵活数组成员有关。正如您所做的那样,通过值将结构传递给函数不是例外情况之一。因此,是的,函数不接收成员。此外,当
main
将数据复制到
name
中时,可能会调用未定义的行为,这是由于超出了结构的边界(结构可能足够大,足以容纳您正在编写的数据,但这不是保证的)

通过确保为原始结构(动态地)分配足够的空间以容纳
name
成员的预期内容,并通过向其传递指针而不是通过值传递指针,您可以使代码与当前的结构声明一起工作。但这肯定比它的价值要麻烦得多,而且这在某种程度上是特定于这种情况的,因为一个结构最多只能有一个灵活的数组成员

当然,您真正想要做的是用大小声明
名称
成员。这就是C要求您声明数组的方式,灵活的数组成员是唯一的例外。(函数参数不是例外,尽管它们看起来可能是。这是另一回事。)如果您使用大小声明
name
,那么您的代码应该可以正常工作:

struct Person {
  int id;
  char name[20];
};

当然,这将您限制为指定的大小。如果您希望更具适应性,那么可以将
name
声明为
char*
,然后将其指向足够大的动态分配空间。这比灵活的数组成员更常见,适用范围也更广,但对于您的练习来说,这可能有些过头了。

name
的大小为零,您不能在那里复制任何内容。当然,您可以,但这样做时的行为是未定义的。在
struct
中没有大小的数组只允许作为最后一个成员,称为灵活数组成员,并且只有在使用
malloc()
动态分配此
struct
时才有意义,手动添加数组的大小。将输出作为文本发布。没有理由离开网站去帮助你。这甚至不会编译。@mad物理学家可能会编译这段特定的代码。但一般来说,它可能会导致严重错误。谢谢…我忘记添加大小…是的,它的工作方式是显示的内容相同,但结构的两个变量的地址不相同。我忘记了更新…两个变量的地址将不同,因为它们是标准和实际参数。
struct Person
{
  int id;
  char name[];
};
struct Person {
  int id;
  char name[20];
};