2013-02-17 2 views
0

У меня есть простая структура, называемая входом, которая содержит имя и возраст. Учитывая массив этих структур, я хочу отсортировать массив по возрасту.Указатели на структуры и функции

Ниже я попытался применить это, на данный момент я даже не могу его скомпилировать. Я думаю, что моя логика указателя неверна как в сравнении сравнения операторов if, так и с последующей перестановкой указателей. Я пробовал разные способы сделать то же самое, но я никуда не денусь. Я довольно новичок в C, и я все еще пытаюсь склонить голову к указателям, поэтому, наверное, это нечто основное, что я недопонимаю. Может ли кто-нибудь объяснить, что я делаю неправильно ниже?

Любая помощь была бы принята с благодарностью.

#include <stdio.h> 

struct entry { 
    char name[15]; 
    int age; 
}; 

void entrySort(struct entry *dict); 

void entrySort(struct entry *dict){ 
    int i,j; // counters 
    int ct = 4; 
    struct entry *tmp; // temporary holder 

    for(i = 0; i < ct; i++){ 
     for(j = 0; j < ct; j++){ 
      if ((*dict[i].age) > (*dict[j].age)){ 
      tmp = (dict + i); 
      (dict+i) = (dict+j); 
      (dict+j) = tmp; 

     } 
    } 
} 

int main (void){ 
    int ct = 4, i; 
    struct entry reg[4] = 
     {{ "John", 24 }, 
     { "Alan", 18 }, 
     { "Jim", 40 }, 
     { "Sarah",32 }}; 

    entrySort(reg); 

    for(i = 0; i < ct; i++) 
     printf("name: %s. Age: %d\n", reg[i].name, reg[i].age); 

    return 0; 
} 
+0

Вы можете использовать 'qsort'? Это будет намного проще. – nneonneo

+0

Основная цель была не в том, что она сама по себе, это было больше, чтобы понять, как правильно использовать указатели. – user1895961

ответ

2

Вы передаете массив struct entry объектов как указатель: struct entry *dict, но вы лечите его, как это было бы массив указателей на объекты struct entry: (*dict[i]).age.

(dict+i) все еще только указатель, указывающий на память, где i+1. элемент хранится, то есть &dict[i]. Чтобы получить доступ к этому элементу по индексу i, вам необходимо использовать dereference operator: *(dict + i), что равно dict[i].

Также обратите внимание, что ваша замена элементов на i и j неверна. «Временный владелец» tmp должен быть объект, который будет временно хранить данные, а не просто указатель на память, что вы собираетесь переписать, таким образом, объявить его как struct entry tmp;:

struct entry tmp; 

for(i = 0; i < ct; i++) { 
    for(j = 0; j < ct; j++) { 
     if ((dict[i].age) > (dict[j].age)) { 
      tmp = dict[i]; 
      dict[i] = dict[j]; 
      dict[j] = tmp; 
     } 
    } 
} 

Кстати в коде у вас есть (}) вашего if отсутствует.

1

Try:

#include <stdio.h> 

struct entry { 
    char name[15]; 
    int age; 
}; 

void entrySort(struct entry *dict, int); 

void entrySort(struct entry *dict, int ct){ 
    int i,j; // counters 
    /* int ct = 4; */ 
    struct entry tmp; // temporary holder 

    for(i = 0; i < ct; i++){ 
     for(j = 0; j < ct; j++){ 
      if ((dict[i].age) > (dict[j].age)){ /* no * */ 
      tmp = *(dict + i); 
      *(dict+i) = *(dict+j); 
      *(dict+j) = tmp; 

     } 
    } 
} 

int main (void){ 
    int ct = 4, i; 
    struct entry reg[4] = 
     {{ "John", 24 }, 
     { "Alan", 18 }, 
     { "Jim", 40 }, 
     { "Sarah",32 }}; 

    entrySort(reg, ct); 

    for(i = 0; i < ct; i++) 
     printf("name: %s. Age: %d\n", reg[i].name, reg[i].age); 

    return 0; 
} 
1

Для полноты, вот как вы могли бы сделать это с qsort:

#include <stdlib.h> 
int sort_entry(const void *va, const void *vb) { 
    const struct entry *a = va; 
    const struct entry *b = vb; 
    if(a->age < b->age) return -1; 
    else if(a->age == b->age) return 0; 
    return 1; 
} 

... 

qsort(reg, ct, sizeof(struct entry), sort_entry); 
Смежные вопросы