c结构使用for循环初始化

c structures initializing using for-loop

我正在创建一个质量中心程序,我正在尝试将其推广,它最多只适用于 3D。使用具有 3D 和质量元素的结构。类型对象的变量数量,我想由用户而不是我来定义。但是我找不到使用循环创建变量的方法。也许有不同的方法来做,我只是不知道。这是我的代码示例,它不是完整的代码,但它是所有方程式的相同逻辑。

#include <stdio.h>
#include <stdlib.h>

struct objects 
{
    int Xcdnt;
    int Ycdnt;
    int Zcdnt;
    int Mass;
};

int main()
{

    int objectcount = 0;
    int dimensioncount = 0;

    printf("How many objects are there?");
    scanf(" %d", &objectcount);

    printf("How many dimensions are used?");
    scanf(" %d", &dimensioncount);

    for(int i = 0; i < objectcount; i++)
    {
        struct objects (i);
    }

    for(int i = 0; i < objectcount; i++)
    {
        printf("X coordinate is %d.\n", (i).Xcdnt);
    }

    return 0;

}

您需要分配一个对象数组。您当前的代码只是循环创建和销毁同一个

struct objects* objects = malloc(objectcount * sizeof(struct objects));
for(int i = 0; i < objectcount; i++)
{
   objects[i].Xcdnt = 42;
   .....

}

要创建对象数组,您将编写而不是循环,

struct objects foo[objectcount];

其中 foo 是数组的名称,objectcount 是数组中的项目数。

那么访问每个元素的代码将是:

for(int i = 0; i < objectcount; i++)
{
    printf("X coordinate is %d.\n", foo[i].Xcdnt);
}

尽管在此之前您需要执行一些其他步骤才能在打印之前实际为 foo[i].Xcdnt 赋值。

使用malloc动态创建数组

struct objects* objs = malloc(sizeof *objs * objectcount);

您也可以像这样创建一个本地数组:

struct objects objs[objectcount];

但是如果堆栈太大,你就有炸毁堆栈的风险。

这是在 C 语言中处理内存的基础部分。这并不难,但是在灯泡亮起之前你必须与它交朋友的事情之一。 (注意:如果您的编译器支持 C99 可变长度数组对象,您可以使用 VLA 而不是动态分配,此处未解决)

您有三种动态分配内存的工具,malloccallocrealloc。 (callocmalloc 做同样的事情,但将所有字节初始化为零——当你想确保所有内存都被初始化并且只比 malloc 稍微慢一点时很有用)

对于您的示例,您可以按如下方式为对象动态分配内存(注意 下面 /* comments */ 中的附加信息):

#include <stdio.h>
#include <stdlib.h>

typedef struct {    /* a typedef will do (and make things easier)  */
    int xcdnt;      /* C generally uses all lowercase variable and */
    int ycdnt;      /* function names, avoiding MixedCase or       */
    int zcdnt;      /* camelCase, reserving all uppercase for      */
    int mass;       /* constants and macros.                       */
} object;

int main (void) {

    int objectcount = 0;
    int dimensioncount = 0;
    object *objects = NULL; 

    printf ("How many objects are there?: ");
    if (scanf (" %d", &objectcount) != 1) {  /* validate ALL user input */
        fprintf (stderr, "error: invalid conversion or EOF.\n");
        return 1;
    }

    printf ("How many dimensions are used?: ");
    if (scanf (" %d", &dimensioncount) != 1) {
        fprintf (stderr, "error: invalid conversion or EOF.\n");
        return 1;
    }

    /* create objectcount objects using calloc */
    objects = calloc (objectcount, sizeof *objects);

    if (!objects) { /* validate all memory allocations */
        fprintf (stderr, "error: virtual memory exhausted.\n");
        return 1;
    }

    /* create some random values */
    for (int i = 0; i < objectcount; i++) {
        objects[i].xcdnt = i;
        objects[i].ycdnt = i + 1;
        objects[i].zcdnt = i + 2;
        objects[i].mass = i % 10 + 5;
    }

    printf ("\ndimensioncount: %d\n\n", dimensioncount);

    /* output the random data in objects */
    for (int i = 0; i < objectcount; i++) {
        printf ("X coordinate is %d.\nY coordinate is %d.\n"
                "Z coordinate is %d.\nmass is: %d\n\n", 
                objects[i].xcdnt, objects[i].ycdnt, objects[i].zcdnt,
                objects[i].mass);
    }

    free (objects); /* don't forget to free the memory you allocate */

    return 0;
}

例子Use/Output

$ /bin/dynamicobjects
How many objects are there?: 10
How many dimensions are used?: 3

dimensioncount: 3

X coordinate is 0.
Y coordinate is 1.
Z coordinate is 2.
mass is: 5

X coordinate is 1.
Y coordinate is 2.
Z coordinate is 3.
mass is: 6

<snip... objects[2-7]>

X coordinate is 8.
Y coordinate is 9.
Z coordinate is 10.
mass is: 13

X coordinate is 9.
Y coordinate is 10.
Z coordinate is 11.
mass is: 14

内存Use/Error检查

在您编写的任何动态分配内存的代码中,您对分配的任何内存块负有 2 责任:(1) 始终保留指向内存块的起始地址,因此,(2) 当不再需要它时可以释放

您必须使用内存错误检查程序来确保您不会尝试写入 beyond/outside 已分配内存块的边界、尝试读取或基于未初始化值的条件跳转,最后,确认您释放了所有已分配的内存。

对于Linux valgrind是正常的选择。每个平台都有类似的内存检查器。它们都很简单易用,只需运行你的程序就可以了。

$ valgrind ./bin/dynamicobjects
==9105== Memcheck, a memory error detector
==9105== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==9105== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==9105== Command: ./bin/dynamicobjects
==9105==
How many objects are there?: 10
How many dimensions are used?: 3

dimensioncount: 3

X coordinate is 0.
Y coordinate is 1.
Z coordinate is 2.
mass is: 5

<snip... remaining>

==9105==
==9105== HEAP SUMMARY:
==9105==     in use at exit: 0 bytes in 0 blocks
==9105==   total heap usage: 1 allocs, 1 frees, 160 bytes allocated
==9105==
==9105== All heap blocks were freed -- no leaks are possible
==9105==
==9105== For counts of detected and suppressed errors, rerun with: -v
==9105== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

始终确认您已释放所有分配的内存并且没有内存错误。

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