基本上,我有一个全局定义的结构,该结构将保存某些事物的最佳评分元素:

int structlength = 0;

typedef char topscorer_t[MAX_INPUT + 1];

typedef struct {
    topscorer_t name;
    double score;
    int ID;
} top_scores;

top_scores scores[HIGHEST_SCORES + 1];


不幸的是,我的程序可以运行,但是如果我这样递给我,它将不会获得满分,因为每次函数向scores添加新结构时,我也会执行structlength += 1来跟踪其中现在有多少个元素,以及是全局变量;我的讲师绝对讨厌的东西。

还有另一种方法可以跟踪将多少个结构添加到数组structlength的方法吗?

另外,以这种方式定义的结构是否也像全局变量一样对待?我对此很陌生:/

最佳答案

将内容封装在另一个struct中。注意我更喜欢calloc而不是malloc

struct ScoreEntry {
    wchar_t* name;
    double   score;
    int      id;
};

struct List {
    struct ScoreEntry buffer[]; // Note this an array-of-struct rather than array-of-ptr-to-struct
    size_t            bufferLength;
    size_t            bufferIndex;
};

List* List_create(size_t initialLength) {
    struct List* ret = calloc( 1, sizeof(struct List) );
    if( ret == NULL ) exit(1);
    ret->buffer = calloc( initialLength, sizeof(struct ScoreEntry) );
    if( ret->buffer == NULL ) exit(1);
    ret->bufferLength = initialLength;
    return ret;
}

void List_delete(struct List* list) {
    for(size_t i = 0; i < list->bufferIndex; i++ ) {
        free( list->buffer[i].name );
    }
    free( list->buffer );
    free( list );
}

void List_add(struct List* list, struct ScoreEntry entry) {
    if( list->bufferIndex >= list->bufferLength ) {
        // Reallocate buffer using `calloc`
        if( true ) {
            size_t newLength = 2 * list->bufferLength;
            struct ScoreEntry* newBuffer = calloc( newLength , sizeof(struct ScoreEntry) );
            if( newBuffer == NULL ) exit(1);
            memcpy( newBuffer, list->buffer, list->bufferIndex );
            free( list->buffer );
        } else {
            // Or reallocate with `realloc`
            list->buffer = realloc( list->buffer, newLength );
            if( list->buffer == NULL ) exit(1);
        }
        list->bufferLength = newLength;
    }
    list->buffer[ list->bufferIndex++ ] = entry; // note this is a copy operation
}


因此,在您的程序中:

int main(int argc, char* argv[]) {

    struct List* scoresList = List_create( 10 );

    List_add( scoresList, { .name = L"Person 1", .score = 123, .id = 1 } ); // C99 struct initialization syntax
    List_add( scoresList, { .name = L"Person 2", .score = 456, .id = 2 } );
    List_add( scoresList, { .name = L"Person 3", .score = 789, .id = 3 } );

    List_delete( scoresList );
}


请注意,我的示例将失败,因为字符串是在编译时分配的,因此无法释放。解决方案是显式跟踪每个name是运行时字符串还是编译时字符串,然后相应地调用free( name )

10-01 23:48
查看更多