【问题标题】:Array elements of struct and struct membersstruct和struct成员的数组元素
【发布时间】:2020-04-03 17:01:24
【问题描述】:

我想问一下C中的结构声明。例如,

struct Person
{
    char name[50];
    int citNo;
    float salary;
} prsn[20];

[20] 是做什么的?这是什么意思?是否将名称限制为 20(从 50)或将 prsnprsn[1] 限制为 prsn[20]

如果我这样写代码:

struct Person
{
    char name[50];
    int citNo;
    float salary;
};
struct Person prsn[20];

它做同样的事情吗?

【问题讨论】:

  • 它们是一样的:都声明了一个20类型的struct Person元素数组
  • 它就像int prsn[20]; 除了用 struct Person 而不是 int

标签: c struct


【解决方案1】:

上面两段代码是等价的。

在第一个中,您同时定义 struct Personprsn 作为该结构的 20 个元素的数组。第二种,先定义结构体,再单独定义数组。

在 C 中,数组索引从 0 开始,因此在这两种情况下,prsn 数组都包含索引从 0 到 19 的元素。这不会影响 name 成员的大小,这是一个 50 个元素的数组。您有一个包含 20 个 struct Person 的数组,每个数组都包含一个 50 个元素的 char 数组,称为 name

关于使数组大小不受限制,数组必须有一个大小,可以在[] 之间显式指定,也可以通过初始化列表隐式指定。 size 可以是一个变量,但是这样的数组不能在文件范围内定义,并且 size 变量之前必须已经分配了一个值。

【讨论】:

  • 所以这意味着 prsn[0] 到 prsn[19] 的数组对吗?如果我想让元素无限,我必须做什么? prsn[n] 或 prsn[] 或只是 prsn ?
  • @abw1904 数组必须有一个大小,可以在[] 之间显式指定,也可以通过初始化列表隐式指定。 size 可以是一个变量,但是这样的数组不能在文件范围内定义,并且 size 变量之前必须已经分配了一个值。
  • @abw1904 要编写“可变大小数组”,您应该查看 Linked-List。显然不会是无限的,但它可以在运行时增长
【解决方案2】:

[20] 是做什么的?这是什么意思?

下面的cmets显示common nomenclature for the parts of your struct

struct Person {    //struct name (Person)
    char name[50]; // \
    int citNo;     //  --struct members 
    float salary;  // /
} prsn[20];        // instance of struct Person array

[20] 表示struct Person 的这个实例是一个包含 3 个成员的 20 个单独集合的数组。可以使用数组表示法访问数组的每个元素。例如,在一个循环中:

int main(int argc, char *argv[])
{
    for(int i=0;i<20;i++)// note i goes from 0 to 19
    {
        //.....
        //assuming members have been populated
        printf( "%d)\nName is: %d\ncitNo is: %d salary is: %f\n\n", prsn[i].name, prsn[i].citNo, prsn[i].salary);
    }

    return 0;
}

[20] 是否将名称限制为 20(从 50)或将 prsnprsn[1] 限制为 prsn[20]

成员 name[50] 定义了一个 50 字符数组。它的大小不受用于调整结构数组大小的[20] 索引的任何影响。即,正如您定义的那样,有 20 个 prsn 实例,每个实例包含 3 个成员:char [50]intfloat。根据您的定义,[20] 创建的 20 个实例允许使用从019 的索引值访问数组。 (参见上面的循环图。)

编辑以解决 cmets 中的 OP 问题:

如果我想让元素不受限制,我该怎么办?

如果您想使用空数组括号,([])定义必须包含struct initializer list。例如:

... } prsn[] = {{"Bill", 1, 23000.00}, {"John", 2, 45000.00}, ...};  

如果结构数组的大小在编译时未知,并且需要根据仅在运行时可用的信息来调整大小,则可以使用动态内存分配或VLA。首先,对于动态内存,不要用数组表示法定义,而是创建一个指针实例:

... } *prsn;  

然后,在一个函数中,使用 callocmalloc 为 1000 个实例创建内存:

int someFunction(void)
{
    prsn = calloc(1000, sizeof(struct Person));
    if(prsn)
    {
        // Use instances of prsn
        // free when finished
        free(prsn);
    }

对于 VLA,创建的实例必须具有本地范围。因此,在某处的函数内部,执行以下操作:

int someFunction(int sizeOfStruct)
{
    struct Person newPerson[sizeOfStruct] = {0};

注意这个方法不需要释放与newPerson相关的内存

【讨论】:

  • 虽然对于无限数量的 Persons,OP 可能会更好地使用链表,或者可能是指向 Person 的指针数组,特别是如果 Persons 的数量可能在运行时发生变化。否则,您将花费大量时间手动或通过调用 realloc 来复制现有成员。
【解决方案3】:

您正在声明一个包含 20 个该类型结构的数组

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 2014-10-19
    • 2023-04-04
    • 2012-03-08
    • 2011-10-02
    • 2019-09-07
    相关资源
    最近更新 更多