簡體   English   中英

用指針對C中的結構進行排序

[英]sorting structs in C with pointers

我只是從C語言開始,對於幕后發生的事情幾乎一無所知。 我正在為數據結構類動態學習它,這使事情變得更加困難。

更新:我將程序剝離下來,從內存開始,然后繼續。 我在其中有分配和取消分配功能,並且遇到了malloc錯誤:Q1(9882)malloc: *對象0x7fff59daec08的錯誤:未分配釋放的指針*在malloc_error_break中設置斷點以進行調試

Update2這是我的修改后的代碼,仍然缺少一些內容,我的一些printf語句未顯示:

#include <stdio.h>
#include<stdlib.h>
#include<math.h>
#include<assert.h>

static int size = 10;

struct student{
    int id;
    int score;
};

struct student* allocate(){
     /*Allocate memory for ten students*/
     struct student *s = malloc(size*(sizeof(struct student)));
     assert(s != 0);
     /*return the pointer*/
     return s;
}

void generate(struct student* students){
    /*Generate random ID and scores for ten students, ID being between 1 and 10, scores between 0 and 100*/
    srand((unsigned int)time(NULL));
    int id[size];
    int y;

    for (int i = 0; i < size; i++){
        y = rand() % size + 1;
        while(dupe(id, i, y)){
            y = rand() % size + 1;
        }
        id[i] = y;
    }

    for (int j = 0; j < size; j++){
        (students + j)->id = id[j];
        (students + j)->score = rand() % 101;
        printf("ID: %d\tScore: %d\n", (students + j)->id, (students + j)->score);
    }
}

int dupe(int id[], int size1, int i){
    for (int x = 0; x < size1; x++){
        if(id[x] == i)
            return 1;
    }
    return 0;
}

void output(struct student* students){
     /*Output information about the ten students in the format:
              ID1 Score1
              ID2 score2
              ID3 score3
              ...
              ID10 score10*/
    sort(&students);
    for(int x = 0; x < size; x++){
        printf("ID: %d\tScore: %d\n", (students + x)->id, (students + x)->score); //print stmt not showing
    }
}

void sort(struct student* students){
    struct student *sd = allocate();

    struct student *stud;

    for(int i = 0; i < size; i++){
        stud = &students[i];
        sd[stud->id] = *stud;
    }
    for(int x = 0; x < size; x++){
        printf("ID: %d\tScore: %d\n", (sd + x)->id, (sd + x)->score); //print stmt not showing
    }
    students = &sd;
    deallocate(sd);
}

void summary(struct student* students){
     /*Compute and print the minimum, maximum and average scores of the ten students*/

}

void deallocate(struct student* stud){
     /*Deallocate memory from stud*/
    free(stud);
}

int main(){
    struct student* stud = NULL;
    char c[] = "------------------------------\n";
    /*call allocate*/
    stud = allocate();
    /*call generate*/
    generate(&stud);
    /*call output*/
    printf("%s", c);
    output(&stud);
    /*call summary*/

    /*call deallocate*/
    deallocate(stud);

    return 0;
}
students = &students[x];

這會改變students指向的位置,因此下一次通過循環時,您將從那里偏移,而不是從頭開始。 也就是說,你要originalstudents[0] originalstudents[1] originalstudents[1+2] originalstudents[1+2+3]等你有同樣的問題sd

相反,您想使用其他變量,例如

struct student* st = &students[x];
printf("id = %d\tscore = %d\n", st->id, st->score);
etc

另外,SD是做什么用的? 您似乎沒有明顯的理由分配一些空間並將學生復制到sd。 分配的空間沒有保存或返回……這是內存泄漏。 哦,等等,我知道..您按學生ID的順序對他們重新排序。 因此,您只需要在完成后釋放內存即可。 但是對於學生和sd,您需要一個指向數組的指針,而不是指向數組元素的指針。 您可以使用許多不同的命名約定,但是最好使用一致的命名約定。 例如:

void output(struct Student* students){
    struct Student *idstudents = allocate(); /* sorted by id */
    if (!idstudents)
        /* handle allocation error */;

    for (int x = 0; x < 10; x++){
        struct Student* student = &students[x];
        printf("id = %d\tscore = %d\n", student->id, student->score);
        struct Student* idstudent = &idstudents[student->id];
        *idstudent = *student; /* copy all fields at once */
        printf("id = %d\tscore = %d\n", idstudent->id, idstudent->score);/* pointless here, since we just printed the same info via student */
    }

    for (int x = 0; x < 10; x++){
        struct Student* idstudent = &idstudents[x];
        printf("id = %d\tscore = %d\n", idstudent->id, idstudent->score);
    }
    deallocate(idstudents);
}

您的output()函數濫用了指針,因此您在踐踏所有學生數據。 嘗試這樣的事情(假設ID是數組索引,因為那是您使用它們的方式):

struct student* allocate()
{
    /*Allocate memory for ten students*/ 
    struct student *s = malloc(10 * sizeof(struct student)); 
    assert(s != NULL); 
    /*return the pointer*/ 
    return s; 
} 

void deallocate(struct student* stud)
{ 
    /*Deallocate memory from stud*/ 
    free(stud); 
} 

int main()
{ 
    struct student* stud = NULL; 

    /*call allocate*/ 
    stud = allocate(); 

    /*call generate*/ 

    /*call output*/ 
    output(stud);

    /*call summary*/ 

    /*call deallocate*/ 
    deallocate(stud); 

    return 0; 
} 

void output(struct student* students)
{ 
    /*allocate array for sorting*/
    struct student *sd = allocate(); 

    struct student *stud; 

    /*make copy of students in sorted order*/
    for (int x = 0; x < 10; ++x)
    { 
        stud = &students[x]; 
        printf("id = %d\tscore = %d\n", stud->id, stud->score); 
        sd[stud->id] = *stud; 
    } 

    /*output sorted students*/
    for (int x = 0; x < 10; ++x)
    { 
        stud = &sd[x]; 
        printf("id = %d\tscore = %d\n", stud->id, stud->score); 
    } 

    /*deallocate array for sorting*/
    deallocate(sd); 
} 

由於已經對學生數量進行了硬編碼,因此可以消除在output()動態分配新學生數組的需要,而只需對原始數組中已經擁有的指針進行排序:

void output(struct student* students)
{ 
    /*array for sorting*/
    struct student* sd[10]; 

    struct student *stud; 

    /*sort students*/
    for (int x = 0; x < 10; ++x)
    { 
        stud = &students[x]; 
        printf("id = %d\tscore = %d\n", stud->id, stud->score); 
        sd[stud->id] = stud; 
    } 

    /*output sorted students*/
    for (int x = 0; x < 10; ++x)
    { 
        stud = sd[x]; 
        printf("id = %d\tscore = %d\n", stud->id, stud->score); 
    } 
} 

更新 :現在,您已經顯示了更多代碼,仍然在使用指針時犯了一些大錯誤。 如所示,您的代碼甚至不應編譯。 嘗試以下方法:

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include <assert.h> 

static const int numStudents = 10; 

struct student
{ 
    int id; 
    int score; 
}; 

struct student* allocate()
{ 
     /*Allocate memory for ten students*/ 
     struct student *s = malloc(numStudents * sizeof(struct student)); 
     assert(s != 0); 
     /*return the pointer*/ 
     return s; 
} 

void generate(struct student* students)
{ 
    /*Generate random ID and scores for ten students, ID being between 1 and 10, scores between 0 and 100*/ 
    int id[numStudents]; 
    int y; 
    struct student* stud;

    for (int i = 0; i < numStudents; i++)
    { 
        do
        {
          y = rand() % size + 1; 
        }
        while (dupe(id, i, y) != 0);
        id[i] = y; 
    } 

    for (int j = 0; j < numStudents; j++)
    { 
        stud = &students[j];
        stud->id = id[j]; 
        stud->score = rand() % 101; 
    } 
} 

int dupe(int id[], int size, int i)
{ 
    for (int x = 0; x < size; x++)
    { 
        if (id[x] == i) 
            return 1; 
    } 
    return 0; 
} 

void output(struct student* students)
{ 
     /*Output information about the students in the format: 
              ID1 Score1 
              ID2 score2 
              ID3 score3 
              ... 
              ID10 score10*/ 

    struct student* stud;

    for(int x = 0; x < numStudents; x++)
    { 
        stud = &students[x];
        printf("ID: %d\tScore: %d\n", stud->id, stud->score);
    } 
} 

void sort(struct student* students)
{ 
    struct student *sd = allocate(); 
    struct student *stud; 

    for(int i = 0; i < numStudents; i++)
    { 
        stud = &students[i]; 
        sd[stud->id - 1] = *stud; 
    } 

    for(int x = 0; x < numStudents; x++)
    { 
        stud = &sd[x]; 
        students[x] = *stud; 
    } 

    deallocate(sd); 
} 

void summary(struct student* students)
{ 
    /*Compute and print the minimum, maximum and average scores of the ten students*/ 
} 

void deallocate(struct student* stud)
{ 
    /*Deallocate memory from stud*/ 
    free(stud); 
} 

int main()
{ 
    /*seed random number generator*/
    srand(time(NULL)); 

    struct student* stud = NULL; 
    const char* c = "------------------------------\n"; 

    /*allocate students and generate info*/ 
    stud = allocate(); 
    generate(stud); 
    output(stud); 

    printf("%s", c); 

    /*sort students*/ 
    sort(students); 
    output(stud); 

    printf("%s", c); 

    /*display summary*/ 
    summary(stud); 

    /*deallocate students*/ 
    deallocate(stud); 

    return 0; 
} 

這個說法

students = &students[x];

修改傳入的參數。 您已經失去了“學生”所指的內容,這是struct student []的開始。

刪除該語句,然后嘗試再次運行程序。

還有其他錯誤,但這會讓您感到困惑。

指針很難。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM