如何编写一个修改结构体的函数

3

我正在制作一个用结构体作为练习试验的程序,将学生的成绩放入数组中。我需要编写一个函数来检查数组中是否有剩余位置,如果没有,则需要将数组大小加倍,然后将成绩添加到下一个可用位置。如果数组有空缺位置,则应将成绩值添加到下一个可用位置。每当对数组进行更改时,都必须使用基本变量、for和while循环以及非常基本的方式更新grades_array_pos和grades_array_size的正确值。我对C语言还很陌生,不太清楚如何做到这一点。

struct student_grades
{
    int student_id; 
    int *grades_array[10];
    int grades_array_pos;
    int grades_array_size;
};
void add_grade(struct student_grades * student, int assignment_grade){

}

教授在Vocarium浏览器中编写了此功能的代码,并保存了测试用例。我们只需编写函数,然后在点击发送按钮时进行测试。我们可以无限次地发送它。 - user8576312
它向我们展示了上面的结构,并给出了您所看到的函数的开头。我们填写函数的内部。有一个Word文档告诉我们,就函数应该做什么,就像我上面说的那样。 - user8576312
哦...我卡在了“grades_array”上,它似乎是一个指向整数的十个项目数组的指针。抱歉,我以为我可以帮忙 - 如果只是“int *grades_array;”,我可以处理它。说,vocarium这个东西会显示printf的结果吗?还是只有“25个测试中通过了8个”这样的信息。 - jgreve
我只是添加了[10]到grades_array,因为我认为这就是如何将其变成数组。我想如果需要在需要时将其加倍,它必须具有大小。我有早课,所以直到明天才能回来。感谢您的帮助。测试通过的数量就好。 - user8576312
好的,知道了。请按原样发布结构体,不要更改 :-) 额外的[10]是朝错误的方向迈出的一步 - 我会留意我的消息框。(基本上就是david-c-rankin所说的一切。) - jgreve
显示剩余2条评论
1个回答

4

这是每个人都需要掌握的关键而简单的技能。基本方法是保持变量,存储当前分配元素的数量和计数器,用于使用的数量。然后循环填充数组。在你的循环开始时,请检查是否if (used == allocated),以确定是否需要重新分配。

如果需要重新分配,则使用临时指针调用realloc并将分配的元素数量加倍。验证realloc是否成功,否则中断填充阵列的循环,(不要退出程序),因为指向realloc尝试之前有效数据的原始数组指针仍然存在。

如果realloc成功,则将新大小的内存块分配给原始指针,更新具有新分配元素数量的变量 - 并继续进行,必要时重复。例如:

#define NSTRUCT 8    /* initial number of struct to allocate for array */
...
size_t  allocated = NSTRUCT,   /* holds current number of elements allocated */
        used = 0;              /* holds current number used/filled */
struct student_grades *grades = malloc (allocated * sizeof *grades);

if (!grades) {
    perror ("malloc-grades");
    return 1;
}

while (/* loop to fill struct array */) {

    if (used == allocated) {    /* check if realloc needed */
        /* always realloc using a TEMPORARY pointer */
        void *tmp = realloc (grades, 2 * allocated * sizeof *grades);
        if (!tmp) { /* validate reallocation */
            perror ("realloc-grades");
            break;  /* don't exit, original pointer still good */
        }
        grades = tmp;       /* assign reallocated block to grades */
        allocated *= 2;     /* update allocated size */
    }

    /* fill next element -- keep going.... */
    used++;
}

请查看内容并告诉我是否还有问题。

嗯...好的,哪一个?他已经将grades添加到数组中,然后重新分配了tmp--他还需要什么? - David C. Rankin
很遗憾,我必须以更基本的方式来完成这个任务。我不能使用perror、void *tmp或realloc。我们只能使用课堂上教授的最基本的语言部分。我知道这并没有太大帮助,但我不太熟悉这门语言,无法解释我的意思。我们必须使用基本的for或while循环。正如之前所说,我不能使用realloc。我也不知道NSTRUCT 8是什么。感谢您的帮助。 - user8576312
我们没有学过fputs或stderr,所以我不认为这样的东西会在测试中被接受。我正在尝试找到一种能够满足教授要求的方法。可悲的是,我不认为我能使用其中任何一个,但还是谢谢你的帮助。 - user8576312
好的,回答我这个问题---“在函数的返回值大小被加倍后,你要将返回值分配给指针吗?”--或者--“你想要传递原始指针的地址给函数,并在函数内部进行更新吗?”你可以选择任何一种方式,所有方式都涉及相同的功能(在C语言中没有其他方法可以实现而不实现自己的内存管理器并操纵程序brk -- 这显然不是预期的)。 - David C. Rankin
此外,如果您的数组被声明为全局变量(不好的实践),则只能使用void add_grade(struct student_grades *student, int assignment_grade)。否则,如果在add_grade中进行重新分配,则无法从函数返回新的数组地址。您还必须有一个全局计数器,因为您的函数既不接受计数器指针也不返回值。请提供[A Minimal,Complete和Verifiable Example(MCVE)](http://stackoverflow.com/help/mcve),以便我们知道您的代码期望什么。 - David C. Rankin
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接