Предоставление определенных значений, но возвращает неверный указатель - PullRequest
0 голосов
/ 17 ноября 2018

У меня есть структура, которая содержит слова разных классов. Например, если вы получаете оценку «А», слова, которые описывают вас, «Brilliant», «Fantastic». Если вы получаете оценку «B», слова, которые описывают вас, «Хороший», «Неплохой». Эти слова хранятся в виде структур.

Тем не менее, мне нужно создать функцию (grade_pnter_finder), в которой я анализирую оценку, и если это голова или хвост этой оценки, и она возвращает мне структуру слова этой оценки. Тем не менее, он продолжает возвращать мне один и тот же указатель независимо от класса. Если я задаю ему оценку A для хвоста, он возвращает мне указатель 100. Если я даю ему оценку B для хвоста, он возвращает мне указатель 100.

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

struct grade {
    struct grade_word *A_head;
    struct grade_word *A_tail;

    struct grade_word *B_head;
    struct grade_word *B_tail;

    struct grade_word *C_head;
    struct grade_word *C_tail;

    struct grade_word *D_head;
    struct grade_word *D_tail;

    struct grade_word *E_head;
    struct grade_word *E_tail;

};

struct grade_word {
    char *word;
    int word_len;
    struct grade_word *next;
    struct grade_word *prev;
};

struct grade *create_grade() {

    struct grade *new_grade = malloc(sizeof(struct grade));

    // Check grade was allocated correctly
    if (new_grade == NULL) {
        fprintf(stderr, "ERROR: Could not allocate memory for grade\n");
        exit(1);
    }

    // Initialise all variables
    new_grade->A_head = NULL;
    new_grade->A_tail = NULL;
    new_grade->B_head = NULL;
    new_grade->B_tail = NULL;
    new_grade->B_head = NULL;
    new_grade->C_tail = NULL;
    new_grade->C_head = NULL;
    new_grade->C_tail = NULL;
    new_grade->D_head = NULL;
    new_grade->D_tail = NULL;
    new_grade->E_head = NULL;
    new_grade->E_tail = NULL;

    return new_grade;
}

struct grade_word *grade_pnter_finder(struct grade *grade_data, char grade,
                                      char h_or_t) {

    struct grade_word *target = NULL;
    if (grade == 'A') {
        if (h_or_t == 'H') {
            target = grade_data->A_head;
        } else {
            target = grade_data->A_tail;
        }
    } else if (grade == 'B') {
        if (h_or_t == 'H') {
            target = grade_data->B_head;
        } else {
            target = grade_data->B_tail;
        }
    } else if (grade == 'C') {
        if (h_or_t == 'H') {
            target = grade_data->C_head;
        } else {
            target = grade_data->C_tail;
        }
    } else if (grade == 'D') {
        if (h_or_t == 'H') {
            target = grade_data->D_head;
        } else {
            target = grade_data->D_tail;
        }
    } else {
        if (h_or_t == 'H') {
            target = grade_data->E_head;
        } else {
            target = grade_data->E_tail;
        }
    }

    if (h_or_t == 'H') printf("Grade %c's Head pointer is at: %p\n", grade, &target);
    else printf("Grade %c's Tail pointer is at: %p\n", grade, &target);
    return target;
}

int main(void) {

    struct grade *new_grade = create_grade();
    struct grade_word *pnter;
    pnter = grade_pnter_finder(new_grade, 'A', 'H');
    pnter = grade_pnter_finder(new_grade, 'A', 'T');
    pnter = grade_pnter_finder(new_grade, 'B', 'H');
    pnter = grade_pnter_finder(new_grade, 'B', 'T');
    pnter = grade_pnter_finder(new_grade, 'C', 'H');
    pnter = grade_pnter_finder(new_grade, 'C', 'T');
    pnter = grade_pnter_finder(new_grade, 'D', 'H');
    pnter = grade_pnter_finder(new_grade, 'D', 'T');
    pnter = grade_pnter_finder(new_grade, 'E', 'H');
    pnter = grade_pnter_finder(new_grade, 'E', 'T');

    printf("Stop compiler complaining for unused variable = %p\n", &pnter);


}

Выход:

Grade A's Head pointer is at: 0028FEFC
Grade A's Tail pointer is at: 0028FEFC

Grade B's Head pointer is at: 0028FEFC
Grade B's Tail pointer is at: 0028FEFC

Grade C's Head pointer is at: 0028FEFC
Grade C's Tail pointer is at: 0028FEFC

Grade D's Head pointer is at: 0028FEFC
Grade D's Tail pointer is at: 0028FEFC

Grade E's Head pointer is at: 0028FEFC
Grade E's Tail pointer is at: 0028FEFC

Stop compiler complaining for unused variable = 0028FF28

Как видите, все указывает на одно и то же место. Разве это не должно указывать на различия мест?

Ответы [ 2 ]

0 голосов
/ 17 ноября 2018

Размещенный код показывает один и тот же адрес для каждого напечатанного адреса, поскольку он печатает значение &target каждый раз. Но target сам по себе является указателем на структуру grade_word со своим собственным адресом. Это адрес target, который печатается, а не значение , удерживаемое с помощью target, то есть адрес, на который указывает target.

Обратите внимание, что при печати адресов, как этот код, например, с printf("Grade %c's Tail pointer is at: %p\n", grade, &target); вызывает неопределенное поведение в соответствии со стандартом C, который говорит о спецификаторе преобразования %p, что «аргумент должен быть указателем на void.»

Вместо этого код должен быть:

printf("Grade %c's Tail pointer is at: %p\n", grade, (void *) target);

Даже после исправления двух вышеупомянутых проблем, обратите внимание, что указатели во вновь созданной структуре grade_word все были инициализированы в NULL, но ни один из них не был установлен, чтобы указывать где-либо значащим.

0 голосов
/ 17 ноября 2018

Если вы ссылаетесь на значение, напечатанное:

if (h_or_t == 'H') printf("Grade %c's Head pointer is at: %p\n", grade, &target);
else printf("Grade %c's Tail pointer is at: %p\n", grade, &target);

Вы должны изменить &target на target. Вы хотите напечатать значение локальной переменной, а не место, где она хранится в памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...