简体   繁体   English

将结构指针添加到指针数组

[英]Adding struct pointer to a pointer array

I have a problem and I really dont know what to do. 我有一个问题,我真的不知道该怎么办。

I'am trying to insert "new students" to an student-array. 我正在尝试将“新学生”插入到学生数组中。 The array contains pointers to the created structs. 该数组包含指向创建的结构的指针。 Can somebody find the error? 有人可以找到错误吗? It adds the student-structs to the array but especially the printing doesnt work. 它将学生结构添加到数组,但尤其是打印不起作用。

It would be really helpful, if somebody could help me. 如果有人可以帮助我,那将真的很有帮助。 :) PS: You can just copy the code. :) PS:您可以复制代码。

Here is my code: 这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_HASH 10
typedef struct student
{
    unsigned int matnr;
    char *name;
    struct student *next_student;
} Student;

Student **hash_tabelle[MAX_HASH];

void insert_student (unsigned int matnr, char *name)
{
    Student *neuer_student = malloc(sizeof(Student));
    neuer_student->name = malloc(sizeof(*name)+1);
    neuer_student->matnr = matnr;
    strcpy(neuer_student->name, name);
    neuer_student->next_student = NULL;

    // Index im Hash-Array ermitteln
    int hash_index = matnr % 10;

    if(hash_tabelle[hash_index] == NULL)
    {
        neuer_student->next_student = hash_tabelle[hash_index];
        hash_tabelle[hash_index] = neuer_student;
    }
    else
    {      
        while(*hash_tabelle[hash_index] != NULL && (((*hash_tabelle[hash_index])->matnr - neuer_student->matnr) <= 0))
            hash_tabelle[hash_index] = &(*hash_tabelle[hash_index])->next_student;
        neuer_student->next_student = *hash_tabelle[hash_index];
        *hash_tabelle[hash_index] = neuer_student;
    }
}

void print_hash_tabelle()
{
    for(int i = 0; i != MAX_HASH - 1; i++){
        printf("%d)\t", i);

        hash_tabelle[i] = &(*hash_tabelle[i])->next_student;

        for(; hash_tabelle[i] != NULL; hash_tabelle[i] = &(*hash_tabelle[i])->next_student){
            printf("%s (%d)", (&(*hash_tabelle[i])->name), (&(*hash_tabelle[i])->matnr));
        }
        printf("\t");
    }
}

int main()
{
    unsigned int matnr;
    char name[100];

    do
    {
        printf("Matrikelnummer:\t");
        scanf("%d", &matnr);
        fflush(stdin);
        getchar(); // um das \n aus dem Puffer zu kriegen und rauszuschmeißen
        printf("Name:\t\t");
        fgets(name, 30, stdin);
        insert_student(matnr, name);
    }
    while (matnr != 0);

    print_hash_tabelle();

    return 0;
}

Using a hash table is so simple... No need to use dereferencing for a fixed-size array of linked-list pointers. 使用哈希表非常简单...无需对链接列表指针的固定大小数组使用解引用。

Step 1 - a hash table is a array of linked-list pointers. 步骤1-哈希表是链接列表指针的数组。

As @BLUEPIXY suggests: 正如@BLUEPIXY建议的那样:

Student *hash_tabelle[MAX_HASH];

Step 2 - to allocate and free each linked-list, initialize each item to NULL. 第2步 -分配和释放每个链表,将每个项目初始化为NULL。

Otherwise, if(hash_tabelle[hash_index] == NULL) is Undefined behavior in the function insert_student() . 否则, if(hash_tabelle[hash_index] == NULL)是函数insert_student()中的未定义行为。

void hash_init()
{
    for(int i=0;i<MAX_HASH;i++) {
        hash_tabelle[MAX_HASH]=NULL;
    }
}

Step 3 - allocate enough char to store the char *name to insert_student() . 步骤3-分配足够的char以将char *name存储到insert_student()

As @ WhozCraig suggests, use strlen() . 正如@ WhozCraig所建议的那样,请使用strlen()

void insert_student (unsigned int matnr, char *name)
{
    Student *neuer_student = malloc(sizeof(Student));
    neuer_student->name = malloc(strlen(name)+1);
    neuer_student->matnr = matnr;
    strcpy(neuer_student->name, name);
    neuer_student->next_student = NULL;

Step 4 - add the neuer_student in the hash_tabelle[] (function insert_student() ) 第4步 -将neuer_student添加到neuer_student hash_tabelle[] (函数insert_student()

Warning: the index shall be included in the size of the array [0..MAX_HASH[. 警告:索引应包含在数组[0..MAX_HASH [。 (using 10 instead of MAX_HASH could become a bug). (使用10代替MAX_HASH可能会导致错误)。

int hash_index = matnr % MAX_HASH;

When the hash_tabelle[hash_index] is NULL, simple store the neuer_student . hash_tabelle[hash_index]为NULL时,简单存储neuer_student No need to modify neuer_student->next_student . 无需修改neuer_student->next_student

if(hash_tabelle[hash_index] == NULL)
{
    hash_tabelle[hash_index] = neuer_student;
}

Else explore the linked-list of hash_tabelle[hash_index] to store the neuer_student at the end. 否则,将探索hash_tabelle[hash_index]的链接列表,以在最后存储neuer_student

else
{
    Student *tmp;

    tmp = hash_tabelle[hash_index];
    while (tmp->next_student!=NULL) {
        tmp = tmp->next_student;
    }
    tmp->next_student = neuer_student;
}

Step 5 - to print the all items of the hash table (function print_hash_tabelle() ) 第5步 -打印哈希表的所有项目(函数print_hash_tabelle()

Reuse the same method to explore each linked-list pointer. 重用相同的方法来探索每个链表指针。

Warning: explore all item from 0 to MAX_HASH-1 警告:浏览从0MAX_HASH-1所有项目

void print_hash_tabelle()
{
    for(int i = 0; i < MAX_HASH; i++){ // ERR != MAX_HASH - 1; i++){
        printf("%d)\t", i);
        Student *tmp = hash_tabelle[i];
        while (tmp!=NULL) {
             printf("%s (%d)", tmp->name, tmp->matnr);
            tmp = tmp->next_student;
        }
        printf("\n");
    }
}

Step 6 - free the memory of each item of the hash_tabelle[] . 步骤6-释放hash_tabelle[]各项的内存。

  1. Free the allocated string free(tmp->name); 释放分配的字符串free(tmp->name); .
  2. Remove the current student hash_tabelle[i] = tmp->next_student; 删除当前的学生hash_tabelle[i] = tmp->next_student;
  3. Free the allocated student free(tmp); 释放分配的学生free(tmp);
  4. Repeat until the end of the linked-list 重复直到链接列表的末尾

That's all (no change in the main() except adding a call to hash_free() at the end). 就是全部(除了在末尾添加对hash_free()的调用之外, main()没有任何更改)。

void hash_free()
{
    for(int i=0;i<MAX_HASH;i++) {
        Student *tmp = hash_tabelle[i];
        while (tmp!=NULL) {
            free(tmp->name);
            hash_tabelle[i] = tmp->next_student;
            free(tmp);
            tmp = hash_tabelle[i];
        }
    }
}

like this: 像这样:

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

#define MAX_HASH 10

typedef struct student {
    unsigned int matnr;
    char *name;
    struct student *next_student;
} Student;

Student *hash_tabelle[MAX_HASH];

void insert_student (unsigned int matnr, char *name){
    Student *neuer_student = malloc(sizeof(Student));
    neuer_student->name = malloc(strlen(name)+1);
    strcpy(neuer_student->name, name);
    neuer_student->matnr = matnr;
    //neuer_student->next_student = NULL;

    int hash_index = matnr % MAX_HASH;
    Student head = { .next_student = hash_tabelle[hash_index] };
    Student *prev = &head, *curr = head.next_student;
    while(curr != NULL && curr->matnr <= neuer_student->matnr){
        prev = curr;
        curr = curr->next_student;
    }
    neuer_student->next_student = curr;
    prev->next_student = neuer_student;
    hash_tabelle[hash_index] = head.next_student;
}

void print_hash_tabelle(void){
    for(int i = 0; i < MAX_HASH; i++){
        printf("%d)\t", i);
        for(Student *p = hash_tabelle[i]; p; p = p->next_student){
            printf("%s (%d)\t", p->name, p->matnr);
        }
        printf("\n");
    }
}

void free_hash_tabelle(void){
    for(int i = 0; i < MAX_HASH; i++){
        Student *p = hash_tabelle[i];
        while(p){
            Student *temp = p->next_student;
            free(p->name);
            free(p);
            p = temp;
        }
    }
}

int main(void){
    int matnr = -1;//for %d of scanf
    char name[100];

    while(1){
        printf("Matrikelnummer(-1 for end input): ");fflush(stdout);
        scanf("%d", &matnr);
        if(matnr < 0)
            break;
        while(getchar() != '\n');
        printf("Name: ");fflush(stdout);
        fgets(name, sizeof name, stdin);
        name[strcspn(name, "\n")] = 0;
        insert_student(matnr, name);
    }

    print_hash_tabelle();
    free_hash_tabelle();

    return 0;
}

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

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