从函数中为全局结构赋值

Assign values to a global struct from a function

我正在通过一本书学习 C,并且我尝试了各种方法以便更好地理解这门语言。 我试图将值从函数传递到全局结构。我遇到了麻烦,因为我执行了 printf 来查看值是否确实通过了,但结果显示了不同的值:

#include <stdio.h>

void receive_date(); //prototype of the function


struct date_example {
    int day;
    int month;
    int year;
};

int main()
{
    struct date_example d;
    receive_date();
    //this line below shows different values than those provided by the scanf inside the function
    printf("the day is %d and the month is %d and the year is %d",d.day,d.month,d.year); 
    return 0;
}



void receive_date(void)
{
    struct date_example d;
    printf("give day: \n");
    scanf("%d", &d.day);
    printf("give month: \n");
    scanf("%d", &d.month);
    printf("give year: \n");
    scanf("%d", &d.year);
    printf("the date is: %.1d %.1d %.1d \n", d.day, d.month, d.year );
}

结果如下:

give day:
2
give month:
3
give year:
2021
the date is: 2 3 2021
the day is 32758 and the month is 0 and the year is 0  // this is the part that gives different values
Process finished with exit code 0

Assign values to a global struct from a function

对于初学者,您既没有结构类型的全局对象。

在您的程序中,您有两个具有自动存储持续时间的结构类型的本地对象。这意味着它们在定义它们的范围之外不存在。

函数中receive_date

void receive_date(void)
{
    struct date_example d;
    printf("give day: \n");
    scanf("%d", &d.day);
    printf("give month: \n");
    scanf("%d", &d.month);
    printf("give year: \n");
    scanf("%d", &d.year);
    printf("the date is: %.1d %.1d %.1d \n", d.day, d.month, d.year );
}

您初始化了它的局部变量 d,该变量在函数外部不可见且存在。

在 main 中,您试图输出未初始化的对象 d 的数据成员

int main()
{
    struct date_example d;
    receive_date();
    //this line below shows different values than those provided by the scanf inside the function
    printf("the day is %d and the month is %d and the year is %d",d.day,d.month,d.year); 
    return 0;
}

所以代码调用了未定义的行为。

您可以通过以下方式更新程序

void receive_date( struct date_example *d );

注意,这种情况下需要将结构定义移到函数声明之前。

main 函数看起来像

int main()
{
    struct date_example d;
    receive_date( &d );
    //this line below shows different values than those provided by the scanf inside the function
    printf("the day is %d and the month is %d and the year is %d",d.day,d.month,d.year); 
    return 0;
}

函数 receive_date 将被定义为

void receive_date( struct date_example *d )
{
    printf("give day: \n");
    scanf("%d", &d->day);
    printf("give month: \n");
    scanf("%d", &d->month);
    printf("give year: \n");
    scanf("%d", &d->year);
    printf("the date is: %.1d %.1d %.1d \n", d->day, d->month, d->year );
}

您没有全局结构,即不是全局和结构类型的变量。只有类型声明是“全局的”。

更明确地说,这一行有两次,每个函数一次。

struct date_example d;

main()里面的做一个局部变量,只能从main()访问。
receive_date 里面的那个是一个本地的,它是从该函数中提到它的所有行访问的那个。

因此,无论您在 receive_date 中做什么都会影响本地,但不会影响另一个 main() 的本地。

你在那个函数内部从 d 本地到那个函数的 printf 是不相关的和不可见的 in/from main().

如果您确实希望在第二个函数中对 d 所做的任何操作都具有从 main() 可见的效果,那么您需要删除这两行相同的行并在外部制作一个这两个功能,即 main() 之外和另一个功能之外。它将定义一个全局 d,可从两个函数访问。

但是,“您需要”仅指您的学习实验。
使用全局变量实际上是不推荐的设计。
您最好使用 return 值,或者(可能比您现在可能稍微高级一些)指向变量的指针参数,以便在函数内进行操作。

这只会创建结构,但不会创建结构变量:

struct date_example {
    int day;
    int month;
    int year;
};

然后,您的代码在 automatic space(本地范围)中定义结构变量:

int main()
{
    struct date_example d;
    ...

}

要使其成为全球性的,只需将此语句放在您的结构定义之后:

struct date_example {
    int day;
    int month;
    int year;
};

struct date_example d;

然后修改以下内容以使用新的全局...

int main()
{
    //struct date_example d;//already defined in global space
    receive_date();
    ...
}
void receive_date(void)
{
    //struct date_example d;//already defined in global space.
    printf("give day: \n");
    scanf("%d", &d.day);
    printf("give month: \n");
    scanf("%d", &d.month);
    printf("give year: \n");
    scanf("%d", &d.year);
    printf("the date is: %.1d %.1d %.1d \n", d.day, d.month, d.year );
}