2014-05-07 63 views
1

我正在將一些數據加載到結構中。結構c的保存指針

struct test { 
    char x[101]; 
    char y[101];  
    int z; 
}; 

然後,我創建了結構

struct test * data; 
data = malloc(10 * sizeof(struct test)); 

內存和填補這樣

data[0].z = 123; 

這工作正常的數據。但我想對這些結構進行分類。像根據z屬性對它們進行排序。

我的想法是創建一個新的數組,然後用指向正確的結構體的指針填充它。

有人可以告訴我如何或如果有更好的辦法嗎?

謝謝

+1

您提到的方式創建一個新的指針數組是最好的方法,也就是說,不需要對實際數據進行排序。 –

+2

您也可以使用'qsort'來排序'data'。 –

+0

是@FiddlingBits但我不知道該怎麼做 – user2976389

回答

0

一種方法是使用qsort,這是標準庫中提供的一般排序算法用於排序用戶定義數據的序列。目標是做到以下幾點:

  • 源數據必須保持未被觸摸。
  • 的「排序」必須通過指針列表從上面

這是做一個方式提供給非接觸數據的訪問,使用qsort()標準庫函數:

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

struct test { 
    char x[101]; 
    char y[101]; 
    int z; 
}; 

int cmp_test_ptrs(const void* arg1, const void* arg2) 
{ 
    struct test const * lhs = *(struct test const * const*)arg1; 
    struct test const * rhs = *(struct test const * const*)arg2; 
    return (lhs->z < rhs->z) ? -1 : (rhs->z < lhs->z); 
} 

int main() 
{ 
    srand((unsigned int)time(0)); 

    // populate data array. 
    struct test * data = malloc(10 * sizeof(*data)); 
    for (int i=0; i<10; ++i) 
    { 
     data[i].z = rand() % 20; 
     printf("%d ", data[i].z); 
    } 
    printf("\n"); 

    // allocate a pointer array to use as a sort-bed, copying each 
    // structure address into this pointer array afterward 
    struct test **ptrs = malloc(10 * sizeof(*ptrs)); 
    for (int i=0; i<10; ++i) 
     ptrs[i] = data+i; 

    // sort the pointer bed using our comparator 
    qsort(ptrs, 10, sizeof(*ptrs), cmp_test_ptrs); 

    // ptrs now has sorted pointers. Note the dereference for access 
    // to the actual data, which remains where it originally was. 
    for (int i=0; i<10; ++i) 
     printf("%d ", ptrs[i]->z); 
    printf("\n"); 

    free(ptrs); 
    free(data); 
    return 0; 
} 

樣品輸出

11 7 6 17 8 8 11 4 7 5 
4 5 6 7 7 8 8 11 11 17 

要注意的是原始結構重新陣列保持不變。我們對指針序列進行了排序,而不是實際的結構本身,並使用了那些指針指向的作爲排序標準。

無論如何,我希望它有幫助。仔細研究比較器和qsort()的設置。他們很重要。您可以閱讀有關qsort() here的更多信息。

2

這取決於你的目標。如果你想弄清楚什麼是最有效的程序員,那麼創建一個基於你的結構的z屬性的排序函數,並直接對列表進行排序是最簡單的。但是,如果您關心的是程序效率,那麼按照Fiddling Bits所建議的那樣排序指針會更快一些。但是,您必須記住,這會給您一個有序的指針列表 - 您的數據數組仍然會以相同的順序排列。

舉例來說,如果datapoints是您的指針數組,你想通過z值進行排序,你可以定義比較

int compare(const void *a, const void *b) 
{ 
    return ((*(test *)a).z -(*(test *)b).z); 
} 

然後調用

qsort(datapoints, 10, sizeof(test), compare); 

的完整文檔可以找到qsort here:

+0

罰款與我..你可以展示如何做到這一點 – user2976389

+2

@ user2976389開始工作,發佈一個新的問題,如果你卡住了某個地方。如果你想讓某人爲你寫代碼,那你就錯了。 –

+0

@RedAlert減速,我沒有要求完整的排序代碼,我只是問我該怎麼做指針數組 – user2976389

0

或者您可以將它們排序在同一個數組中,並可能保存一些內存(4個字節作爲任何類型的指針):P 雖然沒有關係,指針仍然可以正常工作。 但是我認爲在某些情況下,指針會更有用,就好像你將它排列在數組中一樣,你需要一個臨時結構來定義包含結構,當你排序時,如果你的結構比你想象的大實際上比4字節需要更多的內存。 +還記得當定義一個指向struct的指針時 - 用->運算符訪問它。 用法:STRUCT_POINTER_NAME->VARIABLE