【问题标题】:Learning how to properly reference to a struct field when using scanf (C)学习如何在使用 scanf (C) 时正确引用结构字段
【发布时间】:2019-10-13 22:49:29
【问题描述】:

我已经做了这个结构

struct dadosPessoais
{
    char nome[60];
    char end[60];
    char cidade[60];
    char estado[3];
    int cep;
};
typedef struct dadosPessoais dadosPessoais

另外,我已经声明了这些变量和指针

dadosPessoais dp[4], *dpp;

我目前正在尝试做的是从用户接收一些数据并使用 *dpp 指针将这些数据存储在 dp[] 变量中。为此,我制作了这个循环结构

for (i = 0; i < 4; i++)
{
    dpp = &dp[i];
    printf("-- Dados da %da pessoa --\n", i + 1);
    printf("Nome: ");
    scanf("%s", dpp->nome);
    getchar();
    printf("Endereço: ");
    scanf("%s", dpp->end);
    getchar();
    printf("Cidade: ");
    scanf("%s", dpp->cidade);
    getchar();
    printf("Estado: ");
    scanf("%s", dpp->estado);
    getchar();
    printf("Cep: ");
    scanf("%d", dpp->cep);
    getchar();
    system("clear");
}

我知道在使用 scanf 时使用 dpp-&gt;field 之类的东西是不正确的,因为箭头运算符 (->) 用于通过使用该结构变量的地址返回一个结构字段值,而不是用于返回结构字段地址本身。但是,如果我尝试使用dpp.field 之类的东西,它仍然不起作用,因为它应该意味着类似&amp;dp[index].field 的东西,所以令人困惑,对吧?这个问题我还没想好怎么解决……

【问题讨论】:

  • 节省时间,启用所有警告。启用良好的编译器会抱怨scanf("%d", dpp-&gt;cep);

标签: c arrays pointers data-structures struct


【解决方案1】:

dpp = &amp;dp[i]; 执行后,dpp 指向struct dadosPessoais 的一个实例。那么dpp-&gt;cep指的是那个structcep成员,&amp;dpp-&gt;cep是那个成员的地址。因此,要将cep 成员的地址传递给scanf,请传递&amp;dpp-&gt;cep

当使用scanf%s 时,您应该传递数组中第一个字符的地址。所以,对于dpp-&gt;nome,你可以通过&amp;dpp-&gt;nome[0]

但是,由于nome 是一个数组,当你在表达式中使用它时,它会自动转换为指向它的第一个元素的指针。1 所以,你可以使用 pass dpp-&gt;nomescanf,和传递&amp;dpp-&gt;nome[0]一样。

脚注

1 当数组是sizeof 的操作数、是一元&amp; 运算符(获取地址)的操作数或者是字符串文字时,不会发生这种自动转换用于初始化数组。特别注意&amp;arrayarray是指针,但&amp;array的类型是“指向数组的指针”,而array自动转换后是指向数组元素的指针。

【讨论】:

    【解决方案2】:

    正确的方法应该是 scanf("%s", dpp->nome)。示例:

    #include <stdio.h>
    
    struct test {
         char a[10];
    };
    
    int main() {
         struct test new_struct_array[1];
         struct test * ptr = &new_struct_array[0];
         scanf("%s", ptr->a);
         printf("%s", ptr->a);
         return 0;
    }
    

    在 C 中,数组将指向其第一个元素的内存地址。这就是为什么当你做这样的事情时:

    char nome[10];
    scanf("%s", nome);  // works
    scanf("%s", &nome); // does not
    

    nome 已经是对数组开头的引用。

    【讨论】:

    • 这与cep 成员无关,也没有解决 OP 对引用结构成员及其地址缺乏理解的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    • 2022-06-23
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多