簡體   English   中英

C:試圖將結構插入結構數組

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

在我的代碼中,我有包含姓名、年齡和 GPA 的學生資料。 我還有一個包含每個配置文件的數組。 我正在嘗試創建一個插入 function 將另一個學生資料插入數組並在索引無效時顯示錯誤。 我試圖通過在數組中為新學生添加另一個空間來做到這一點,然后將占據錯誤空間的學生的位置向右移動一個空間。

前任。 如果我想將一個學生放在索引 2 中,function 會將占據該空間的學生移動到 3,並將 3 中的學生移動到空間 4。

到目前為止,這是我所擁有的,但我在array[i+1] = i上遇到錯誤,說“從 int 類型分配給 Student 類型時類型不兼容”。 我嘗試將 i 更改為 Student 類型,但我在整個循環中又遇到了幾個錯誤,說它是無效的初始化程序並且我不能使用 >=,並且我是“錯誤的遞減類型”

對於初學者來說,不清楚為什么參數index具有有符號類型int而不是無符號類型size_t 無符號類型允許避免這種冗余檢查

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

此外,如果index的值大於*size的當前值,那么只需將 append 傳遞給數組即可。

所以一般來說這個檢查

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

是多余的。

function 聲明太復雜了。 不需要返回指向傳遞數組的第一個元素的指針。 如果將 function 聲明寫成這樣,它看起來會更簡單

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

即 function 返回更新后數組的新大小。

這個說法

array[i+1] = i; 

沒有任何意義,因為左操作數的類型是 Student,而右操作數的類型是 int。 此外,它有一個邏輯錯誤,因為您必須使用索引而不是索引i i + 1

而不是手動編寫的循環,您可以使用標准 C function memmove

這是一個演示程序,展示了如何定義 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;
}

程序 output 是

{ A, 20 } 
{ B, 21 } { A, 20 } 
{ B, 21 } { A, 20 } { C, 22 } 
{ B, 21 } { E, 23 } { A, 20 } { C, 22 }
  1. 使用的縮進樣式使得很難輕松查看括號是否正確關閉。 請使用自動格式化程序,例如:clang-format

  2. 你的 function 不是很安全。 它應該采用另一個參數max_size因此分配的 memory 是已知的

  3. 如果在if分支中使用 return,則不需要顯式聲明else分支。

  4. for循環已經有一個條件,如果循環中的唯一功能是if ,則可以將其提升到該條件中。

  5. 要將學生從數組中的某個位置移動,必須將學生的“副本”復制到新位置 - 而不僅僅是它的索引。

固定的:

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