【问题标题】:Choosing a random struct by its members由其成员选择一个随机结构
【发布时间】:2017-05-20 04:27:12
【问题描述】:

为了一个教育软件项目(基本上是一个测验),我必须在 C 中为元素周期表建模。

我已经创建了一个结构并声明了所有元素。现在我必须编写一个随机选择一个元素的函数。

这是我的结构:

typedef struct{
        char name[15];
        char shortname[3];
        int group;
        int period;
}element;
element hydrogen={"hydrogen", "H", 1, 1}, helium={"Helium", "He", ...

我已经尝试将它们组合成一个数组,然后生成一个随机索引:

element elements[118];
elements[1] = {"hydrogen", "H", 1, 1};

但这只是给了我错误:(

有什么想法吗?

【问题讨论】:

  • 你可以定义一个数组,例如像这样:element table[118] = { {"hydrogen", "H", 1, 1}, ... };
  • 注意:char shortname[3]; 对于temporary systematic IUPAC symbol 来说太小了,例如"Uue"。最好使用#define SHORTNAME_N 4 ... char shortname[SHORTNAME_N ]; char name[15]; 看起来也很小。
  • OTOH "Rutherfordium" 似乎是最长的 char name[NAME_N]; 需要 #define NAME_N (14 /* or more */)

标签: c arrays pointers struct c99


【解决方案1】:

该方法应该有效。 设置一个结构数组,然后使用 index = rand() % 118。设置结构列表的语法是问题所在。试试

struct element elements[118] = {
 {"hydrogen", "H", 1, 1},
 {"helium", "He", 2, 4},

  ... etc 
};

【讨论】:

  • srand((unsigned) time(&t));他应该分配一个 time_t t var 以确保它是随机的。
【解决方案2】:

你可以使用指定的初始化器:

element elements[118] =
{
  [0] = {"hydrogen", "H", 1, 1},
  [1] = {"helium", 18, 1},
  ...
};

更好的是,您可以通过使用枚举来摆脱“幻数”:

typedef enum
{
  ELEMENT_H,
  ELEMENT_He,
  ELEMENT_Li,
  ...

  NUMBER_OF_ELEMENTS
} element_t;

element elements[] =
{
  [ELEMENT_H]  = {"hydrogen", "H", 1, 1},
  [ELEMENT_He] = {"helium", 18, 1},
  ...
};

_Static_assert(sizeof(elements)/sizeof(elements[0]) ==  NUMBER_OF_ELEMENTS, 
               "Missing elements!");

但请注意,这将是零索引,与元素周期表不同。因此,您要打印元素周期表编号,打印时必须使用 +1。 (或者,您可以在数组的开头留下一个垃圾项,但这是草率的编程。)

【讨论】:

  • 为什么我们不能按问题单独初始化结构数组?
  • @Karthick 因为你只能在一个地方初始化一个变量,在声明过程中——在这种情况下,变量是数组。但是,您可以使用复合文字等在运行时分配单个项目,但在这种情况下,我怀疑数组应该是 const,所以无论如何这是不可能的。
  • 感谢您的解释
【解决方案3】:

您在 C 名称空间中使用 C++ = 运算符心态。那是你的错误。您在命名空间“C”中。

::= 隐式复制所有成员元素的运算符在 C 中不存在。

相反,您必须逐个元素显式复制所有成员。

所以:

strncpy (elements[1].name, "hydrogen", strlen("hydrogen"));
strncpy (elements[1].shortname, "H", strlen("H"));
elements[1].group =  1;
elements[1].period = 1;

将是正确的方法。内联函数或#define 会使其更容易执行并在以后忘记。

【讨论】:

  • "= 隐式复制所有成员元素的运算符在 C 中不存在" 当然可以,只要没有指针成员,您就可以使用 = 运算符复制结构.您只需要使用复合文字。 element[1] = (element){"hydrogen", ...};。不知道你为什么一开始就提到了 C++。
  • 因为我对他的困惑的解释是他在用 C++ 思考。他没有指定静态分配是他可能拥有的唯一应用程序。
  • 正如我在评论中提到的,在这种情况下,普通的旧作业就可以正常工作。对于other reasons,不需要strncpy,这是一个无论如何都不应该使用的函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-26
  • 2015-02-26
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多