【问题标题】:Struct array with array inside it结构数组,里面有数组
【发布时间】:2021-02-08 05:15:08
【问题描述】:

我在课堂上有一个作业,我想将变量保存在结构数组中,因为我认为这是最干净的方法。

我用油漆画了这张速写图,只是为了更容易解释

这只是结构中的“节点”之一,我想制作结构,这样我就可以在绘图中复制文件之后的所有内容

不完全确定我该怎么做

到目前为止,我得到了一个运行良好的结构数组。但我似乎不知道如何添加最后一行,最后一行是指杂货店 1-3、数量 1-3 和单价 1-3。

对于我创建的结构:

这部分工作正常,但仍然缺少最后一个“节点”

【问题讨论】:

  • 另一种方法是 struct file { char Filenr;国际杂货店1;国际杂货店2; int杂货店3;整数数量1;整数数量2;整数数量3;浮动单价1;浮动单价2;浮动单价3; };结构文件表[5];我只是觉得这是一种更混乱的方式
  • 术语“结构数组”没有意义。你想要一个结构数组。您确定需要 3 个杂货、3 个数量和 3 个单价吗?而且为什么这是一个文件?
  • Filenr 代表什么?
  • 请删除该图像,将您的代码作为代码块。
  • 绘图不代表struct file 的数组。添加带有struct file 的数组会适得其反。您将失去groceryquantityunitprice 之间的协调。 struct file 的数组将保持这种协调。 (这就是为什么您使用结构开头...)

标签: c struct


【解决方案1】:

以下是在 C 中在结构内部创建结构数组的简短示例。我将其设置为结构侧面的结构数组,因为我认为您可能想要自定义每个“杂货”/“价格”/“单价”是。

在下面的代码中,我使用“malloc”来动态分配结构数组。这是动态分配内存的“C”风格方式。如果你使用的是 C++,那么你应该使用“new”

我只用 [0] 分配数组中的第一项。您可以分别使用 [1] 和 [2] 索引分配其他索引。

struct Grocery
{
   /* fill in details of Grocery here you could add more than 1 item*/
   int Value;
}

struct Quantity
{
   /* fill in details of Quantity here */
   int Value;
}

struct Unitprice
{
   /* fill in details of Unitprice here */
   int Value;
}

struct file
{
   struct Grocery* groceries;
   int totalGroceries;
   
   struct Quantity* quantities;
   int totalQuantities;
   
   struct Unitprice* unitprices;
   int totalUnitprices;
}

int main()
{
   struct file Table;
   
   Table.totalGroceries = 3
   Table.groceries = (struct Grocery*)malloc(Table.totalGroceries * sizeof(Grocery));
   
   Table.totalQuantities = 3
   Table.quantities = (struct Quantity*)malloc(Table.totalQuantities * sizeof(Quantity));
   
   Table.totalUnitprices = 3
   Table.unitprices = (struct Unitprice*)malloc(Table.totalUnitprices * sizeof(Unitprice));
   
   /* Assign details to groceries here */
   Table.groceries[0].Value = 5;
   
   /* Assign details to Quantity here */
   Table.quantities[0].Value = 5;
   
   /* Assign details to unitprices here */
   Table.unitprices[0].Value = 5;
   
   /* Other logic here */
   
   /* End of program deallocate allocated memory */ 
   free(Table.groceries);
   free(Table.quantities);
   free(Table.unitprices);
}

有关更多信息,我建议您查看此链接https://stackoverflow.com/questions/260915/how-can-i-create-a-dynamically-sized-array-of-structs#:~:text=If%20you%20want%20to%20allocate,type%20void%20(%20void*%20),了解如何在 C 中动态分配结构数组

【讨论】:

  • 非常感谢,这对我有很大帮助。我的电脑刚刚死机,而我在火车上,所以我无法确保它正常工作。但是从上面看,它看起来和我要找的完全一样
  • 但是请记住,这对于您实际需要的东西来说可能是多余的。它可能是一个更好的结构,将项目组合成一个结构,并且只做一个“malloc”
  • 另外...我只是假设你是用C编码的。如果你用C++编程,你不应该按照这个例子,使用“new / delete”来动态分配内存
  • 我会看一下,如果它过度杀伤力,我会稍微简化一下,这样它就可以工作了。是的,我用 C 编写代码
  • @IlanKeshet 在现代 C++ 中使用 newdelete 表达式几乎没有充分的理由,除非旧接口需要它。
【解决方案2】:

虽然您的绘图和您的描述在一定程度上存在冲突,但您似乎希望能够存储多个项目文件的数据,其中每个项目协调 grocery 值、quantity 值和 unitprice 值(类似于您将用于库存系统的基础)。

从您的绘图来看,您的 Filenr 结构成员没有多大意义。为什么?如果您的基础Item 结构坐标groceryquantityunitprice,那么除非Filenr 提供了作为grocery 一部分的附加唯一 位信息, quantity, 和unitprice, 那么可以简单地省略它,你可以使用它的索引来描述grocery, quantity, 和unitprice

此外,作为char 类型,其值将被限制为256 个值之一(-128 - 127)。如果您实际上认为这是一个可打印字符,那么您的值范围将减少到只有 96 个可打印字符。

你根据你拥有的数据定义你的结构。如果Filenr 是您输入的一部分并与groceryquantityunitprice 相关联的数据,则将其作为成员添加到您的结构中。如果它只是您用来引用唯一结构的东西,那么就不需要它——除非——您可以在groceryquantityunitprice 中拥有两个具有完全相同值的结构,并且您正在使用 Filenr 来消除两个相同的结构之间的歧义。否则,省略它并使用索引。

没有它,您只需创建一个结构数组。这将使您能够按任何成员值进行排序、查询和求和。打印存储(虚构)值的简单实现是:

#include <stdio.h>

typedef struct {                /* your struct using a typedef for convenience */
    int grocery, quantity;
    double unitprice;
} item;

/* simple function to output all n struct in any array of item */
void prn_items (item *items, size_t n)
{
    for (size_t i = 0; i < n; i++)
        printf ("\nFilenr[%2zu]:\n grocery   : %d\n quantity  : %d\n unitprice : %0.4f\n",
                i, items[i].grocery, items[i].quantity, items[i].unitprice);
}

int main (void) {
    
    item files[] = {{ 31756, 22, 1.3405 },      /* made-up example data for array */
                    {  7818, 83, 2.4722 },
                    { 17920, 63, 1.3795 },
                    {  2937, 32, 2.8648 },
                    {  8423, 44, 2.6031 }};
    size_t n = sizeof files / sizeof *files;    /* number of elements in array */
    
    prn_items (files, n);                       /* output all struct */
}

使用/输出示例

运行程序只需将所有存储的由索引协调的结构值输出为Filenr

$ ./bin/grocerystruct

Filenr[ 0]:
 grocery   : 31756
 quantity  : 22
 unitprice : 1.3405

Filenr[ 1]:
 grocery   : 7818
 quantity  : 83
 unitprice : 2.4722

Filenr[ 2]:
 grocery   : 17920
 quantity  : 63
 unitprice : 1.3795

Filenr[ 3]:
 grocery   : 2937
 quantity  : 32
 unitprice : 2.8648

Filenr[ 4]:
 grocery   : 8423
 quantity  : 44
 unitprice : 2.6031

现在,如果您的意图是将每个结构保存在单独的文件中,您可以简单地使用 sprintf() 创建一个输出文件名,其中包含基于索引的唯一后缀(或前缀)。

如果你真的想要一个 charFilenr 作为你的结构的一部分,你可以简单地通过添加它作为成员来包含它,例如

typedef struct {                /* your struct using a typedef for convenience */
    char Filenr;
    int grocery, quantity;
    double unitprice;
} item;

调整代码提醒处理新增成员。

最后,您不想使用与价格相关的浮点数。 (当您由于舍入错误而亏损时,公司会生气)。最好使用相应相乘的整数值,以确保不会发生舍入错误。您可以搜索“floating point type for money”并找到有关该主题的大量附加信息。

检查一下,如果您还有其他问题,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-27
    • 1970-01-01
    • 2013-07-29
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多