具有两个不同功能的相同结构对象的变量地址不同

时间:2018-08-01 13:42:07

标签: c

我有两个函数,一个是main函数,另一个是使用结构显示的函数,我初始化了变量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();
}

输出:

值:

id为2,名称为kunal

地址:

id主代码中的地址是FFEA,名称是FFEC

值:

Id为:2,名称为:kunal

地址:

id函数的地址为FFDE,名称为FFE0

2 个答案:

答案 0 :(得分:1)

在此结构声明中:

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

name成员是所谓的“柔性数组成员”。这不是您想要的目的,尤其是因为

  

在大多数情况下,柔性数组成员将被忽略。

C2011 6.7.2.1/18

异常与通过.->运算符访问灵活数组成员有关。正如您所做的那样,按值将结构传递给函数是 not 的例外之一。因此,是的,该函数不接收成员。此外,由于超出结构的限制,您的main可能会(但不确定)将数据复制到name时调用未定义的行为(该结构可能足够大以容纳您正在写入的数据,但这不能保证)。

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

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

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

当然,这会将您限制为指定的大小。如果您想变得更具适应性,则可以将name声明为char *,然后将其指向足够大的动态分配空间。与灵活的数组成员相比,这种方法更为普遍并且适用范围更广,但是对于您的锻炼而言可能是过大了。

答案 1 :(得分:0)

只需在代码中添加数组的大小,在编译时它的大小就固定。

请勿使用过旧的conio.h

conio.h

  

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

#include <stdio.h>
#include <string.h>

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

int main() 
{
    struct student record = {0}; //Initializing to null

    record.id=1;
    strcpy(record.name, "No one");

    printf(" Id is: %d \n", record.id);
    printf(" Name is: %s \n", record.name);

    return 0;
}