结构数组作为参数和访问成员的混淆

时间:2019-02-20 00:34:52

标签: c arguments structure

My Codepen:

如果我想将结构作为参数传递并修改其原始值,则必须作为指针传递,但是结构数组不应该像数组数组那样作为指针的指针传递?为什么编译器使用指针,并使用指针的指针给出错误?

typedef struct Calendar {
    int day;
    int month;
    int year;
}Calendar;

typedef struct Person {
    char name[40];
    int age;
    float salary;
    Calendar birth;
}Person;
void add(Person * a, int * tam);

最后一行给出警告C4047:char的间接级别不同。如果删除“ *”,它将无法编译。如何从结构数组中正确访问数组成员?

编辑1:这里需要说明的是完整的for (int i = 0; i < *tam + 1; i++) { printf("Insert your name:\n"); fgets(name, 30, stdin); *a[i].name = name; } 函数和add()函数。

main()

2 个答案:

答案 0 :(得分:0)

函数的原型应明确说明它可用于数组:

void add(size_t n, struct Person arr[n], int *tam);

这样,您就知道数组(n)的大小,并且可以确保不尝试访问超出该大小的数组,如果超出该大小,它将以segmentation fault结尾您很幸运(请阅读:How dangerous is it to access an array out of bounds?)。


然后for循环将遍历数组:

for (int i = 0, *tam = 0; i < n; i++, (*tam)++) {
    printf("Insert your name:\n");
    fgets(name, 30, stdin);
    /* a[i].name = name; */
}
(*tam)++;

由于运算符的优先级,您需要(*tam)++周围加上括号(请阅读:How to increment a pointer address and pointer's value?)。


对于访问数组内部的struct来说,您必须知道您正在访问struct数组。这只是许多struct的总和,因为int的数组是:

astruct个数组。

a[i]是数组中的第i个结构。

a[i].name是结构name中的元素a[i]


要将一个字符串复制到另一个字符串中,必须逐个元素地复制它,因为在内部它们是char的数组,并且由于数组在C中的工作方式,因此不能使用{ {1}},但逐个元素进行迭代和复制。

对于普通数组,函数=为您做到了(请阅读:http://man7.org/linux/man-pages/man3/memcpy.3.html)。

在处理字符串时,要用于复制字符串的函数为memcpy()(请阅读:http://man7.org/linux/man-pages/man3/strncpy.3p.html)。

此答案中说明了strncpy()的正确用法:https://stackoverflow.com/a/14067026/6872717

基本上,您将像这样使用它:

strncpy()

因此您的strncpy(a[i].name, name, n - 1); 循环应如下所示:

for

这只是一条注释,如果您不想要它,我可以稍后将其删除,但是在这里我可以更好地格式化代码:

我不确定为什么会出现for (int i = 0, *tam = 0; i < n; i++, (*tam)++) { printf("Insert your name:\n"); fgets(name, 30, stdin); strncpy(a[i].name, name, 40 - 1); a[i].name[40 - 1] = '\0'; } (*tam)++; 循环,但是对于上下文来说,我猜想此函数只能写入数组中的一个for。因此,也许不需要struct循环,而是想要这样的东西:

for

最后的注释:我在if (*tam = (n - 1)) goto err_array_full; if (*tam > (n - 1) || *tam < 0) goto err_invalid_index; printf("Insert your name:\n"); fgets(name, 30, stdin); strncpy(a[*tam].name, name, 40 - 1); a[*tam].name[40 - 1] = '\0'; (*tam)++; 中使用了40,因为您使用了strncpy()创建了数组,但是应该是您要在其中使用的宏这两个地方都使您在更改数组的大小时不会忘记在40中也进行更改,这会引入一个错误。使用宏可以安全,因为您只需更改一个数字,并且所有代码都会更新。

答案 1 :(得分:-1)

传递struct Person数组和设置名称成员的正确方法是:

Person tab[10]; /* array of 10 Person */

void add(Person *a, int tam)
{
    [...]

    for (int i = 0; i < tam; i++) {
        printf("Insert your name:\n");
        fgets(name, 30, stdin);
        strncpy(a[i].name, name, 30);
    }

    [...]
}

/* Call add() like that */
add(tab, 10);

struct数组就像常规数组(例如int数组)一样。在函数内部时,您需要处理一个指针,但仍可以使用数组符号。要访问函数内部的名称成员,只需执行a[i].name。由于name是一个char数组,因此需要使用诸如strncpy()之类的东西,而不是=来设置其值。