简体   繁体   English

C:试图将结构插入结构数组

[英]C: Trying to insert a struct into a struct array

in my code I have student profiles with name, age, and GPA.在我的代码中,我有包含姓名、年龄和 GPA 的学生资料。 I also have an array with each profile.我还有一个包含每个配置文件的数组。 I'm trying to create an insert function that inserts another student profile into the array and display an error if the index is not valid.我正在尝试创建一个插入 function 将另一个学生资料插入数组并在索引无效时显示错误。 I'm trying to do so by moving adding another space in the array for the new student, then moving over the places of students occupying the wrong space by one space to the right.我试图通过在数组中为新学生添加另一个空间来做到这一点,然后将占据错误空间的学生的位置向右移动一个空间。

Ex.前任。 If I want to put a student in index 2, the function would move the student occupying that space to 3, and the student in 3 would be moved to space 4.如果我想将一个学生放在索引 2 中,function 会将占据该空间的学生移动到 3,并将 3 中的学生移动到空间 4。

Here's what I have so far, but I'm getting an error on array[i+1] = i saying "incompatible types when assigning to type Student from type type int."到目前为止,这是我所拥有的,但我在array[i+1] = i上遇到错误,说“从 int 类型分配给 Student 类型时类型不兼容”。 I tried changing i to type Student, I got several more errors all over the loop saying that it was an invalid initializer and that I couldn't use >=, and that i was the "wrong type to decrement我尝试将 i 更改为 Student 类型,但我在整个循环中又遇到了几个错误,说它是无效的初始化程序并且我不能使用 >=,并且我是“错误的递减类型”

For starters it is unclear why the parameter index has the signed type int instead of the unsigned type size_t .对于初学者来说,不清楚为什么参数index具有有符号类型int而不是无符号类型size_t The unsigned type allows to avoid this redundant check无符号类型允许避免这种冗余检查

if (index < 0 || index > *size) {
    ^^^^^^^^^ 

Also if the value of index is greater than the current value of *size then it is enough just to append the passed item to the array.此外,如果index的值大于*size的当前值,那么只需将 append 传递给数组即可。

So in general this check所以一般来说这个检查

if (index < 0 || index > *size) {

is redundant.是多余的。

The function declaration is too complicated. function 声明太复杂了。 There is no need to return pointer to the first element of the passed array.不需要返回指向传递数组的第一个元素的指针。 The function declaration will look more simpler if to write it like如果将 function 声明写成这样,它看起来会更简单

size_t insert( Student a[], size_t n, size_t i, const Student *student );

That is the function returns the new size of the updated array.即 function 返回更新后数组的新大小。

This statement这个说法

array[i+1] = i; 

does not make any sense because the left operand has the type Student while the right operand has the type int.没有任何意义,因为左操作数的类型是 Student,而右操作数的类型是 int。 Moreover it has a logical error because instead of the index i + 1 you have to use the index i .此外,它有一个逻辑错误,因为您必须使用索引而不是索引i i + 1

And instead of the manually written loop you could use the standard C function memmove .而不是手动编写的循环,您可以使用标准 C function memmove

Here is a demonstrative program that shows how the function can be defined.这是一个演示程序,展示了如何定义 function。

#include <stdio.h>
#include <string.h>

#define MAX_LEN 10

typedef struct Student
{
    char name[MAX_LEN];
    unsigned int age;
} Student;

size_t insert( Student a[], size_t n, size_t i, const Student *student )
{
    if ( n < i ) i = n;
    
    if ( i < n )
    {
        memmove( a + i + 1, a + i, ( n - i ) * ( sizeof( Student ) ) );
    }
    
    a[i] = *student;
    
    return ++n;
}
   
int main(void) 
{
    enum { N = 10 };
    Student a[N] = { 0 };
    
    Student student = { "A", 20 };
    
    size_t n = insert( a, 0, 0, &student );
    
    for ( size_t i = 0; i < n; i++ )
    {
        printf( "{ %s, %u } ", a[i].name, a[i].age );
    }
    putchar( '\n' );
    
    strcpy( student.name, "B" );
    ++student.age;
    
    n = insert( a, n, 0, &student );
    
    for ( size_t i = 0; i < n; i++ )
    {
        printf( "{ %s, %u } ", a[i].name, a[i].age );
    }
    putchar( '\n' );
    
    strcpy( student.name, "C" );
    ++student.age;
    
    n = insert( a, n, 2, &student );
    
    for ( size_t i = 0; i < n; i++ )
    {
        printf( "{ %s, %u } ", a[i].name, a[i].age );
    }
    putchar( '\n' );
    
    strcpy( student.name, "E" );
    ++student.age;
    n = insert( a, n, 1, &student );
    
    for ( size_t i = 0; i < n; i++ )
    {
        printf( "{ %s, %u } ", a[i].name, a[i].age );
    }
    putchar( '\n' );
    
    return 0;
}

The program output is程序 output 是

{ A, 20 } 
{ B, 21 } { A, 20 } 
{ B, 21 } { A, 20 } { C, 22 } 
{ B, 21 } { E, 23 } { A, 20 } { C, 22 }
  1. The used indentation style makes it difficult to easily see if the parenthesis are correctly closed.使用的缩进样式使得很难轻松查看括号是否正确关闭。 Please use an automatic formatter, example: clang-format请使用自动格式化程序,例如:clang-format

  2. Your function is not very safe.你的 function 不是很安全。 It should take another parameter max_size so the assigned memory is known它应该采用另一个参数max_size因此分配的 memory 是已知的

  3. If a return is used in if branch, the else branch does not have to be explicitly declared.如果在if分支中使用 return,则不需要显式声明else分支。

  4. A for loop already has a condition, if the only functionality in the loop is an if , it can be hoisted up into that condition. for循环已经有一个条件,如果循环中的唯一功能是if ,则可以将其提升到该条件中。

  5. To move students from a place in an array a "copy" of the student has to be made to the new location - not just it's index.要将学生从数组中的某个位置移动,必须将学生的“副本”复制到新位置 - 而不仅仅是它的索引。

Fixed:固定的:

Student* insert(Student* array, int max_size, int* size, int index, Student s)
{
    //error message and return NULL if space is - or > array size
    if (index < 0 || index > *size || *size + 1 > max_size)
    {
        printf("ERROR\n");
        array = NULL;
        return array;
    }

    for (int i = *size; i > index && i > 0; --i)
    {
        //move students at index or > over to make open space
        array[i] = array[i - 1];
    }

    //put new student in correct location
    array[index] = s;

    *size += 1;
    
    return array;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM