带数组的scanf,什么时候加&什么时候不加&

scanf with array, when to add & and when not adding &

#include <stdio.h>

struct Person
{
    char name[50];
    int roll;
    float marks;
} s[5];

int main()
{
    printf("Enter information of students:\n");

    for (int i = 0; i < 5; ++i)
    {
        s[i].roll = i + 1;
        printf("\nFor roll number %d,\n", s[i].roll);
        printf("Enter name: ");
        scanf("%s", s[i].name);
        printf("Enter marks: ");
        scanf("%f", &s[i].marks);
    }
    printf("\nDisplaying Information:\n");

    for (int i = 0; i < 5; ++i)
    {
        printf("\nRoll number: %d\n", s[i].roll);
        printf("Name: ");
        printf("%s\n", s[i].name);
        printf("Marks: %.1f\n", s[i].marks);
    }

    return 0;
}

我正在从网站上学习 C 编程,但是我不明白为什么 scanf with name we don't need &s[i].name 前面,而 ​​s[i].marks前面有个&.

希望问题清楚,感谢您阅读我的 post。

(https://www.programiz.com/c-programming/examples/information-structure-array)

在 C 中,按引用传递意味着通过指向对象的指针间接传递对象。

为了能够更改对象(而不是对象值的副本),函数 scanf 需要通过引用获取它。

在本次通话中

scanf("%s", s[i].name);

数组指示符 name 被隐式转换为指向其第一个元素的指针。这个调用实际上等同于

scanf("%s", &s[i].name[0]);

因此,使用传递给数组第一个元素的指针和指针算法,该函数可以更改数组的任何元素,因为它们都是通过引用传递的。

要更改标量对象marks,您还需要通过引用传递它

scanf("%f", &s[i].marks);

这是一个简单的演示程序

#include <stdio.h>

void f( int *p )
{
    *p = 20;
}

int main(void) 
{
    int x = 0;
    
    printf( "Before call of f x = %d\n", x );
    
    f( &x );

    printf( "After  call of f x = %d\n", x );
    
    int a[] = { 0 };
    
    printf( "Before call of f a[0] = %d\n", a[0] );
    
    f( a );

    printf( "After  call of f a[0] = %d\n", a[0] );
    
    return 0;
}

程序输出为

Before call of f x = 0
After  call of f x = 20
Before call of f a[0] = 0
After  call of f a[0] = 20

在本次通话中

f( a );

数组指示符 a 被隐式转换为指向其第一个(在本例中为单个)元素的指针。你也可以写

f( &a[0] )