Я не понимаю, как указатели работают в этом коде? - PullRequest
0 голосов
/ 20 июня 2019

Я не понимаю эту часть кода ниже.Я имею в виду alloc_MY_CAR() возвращает некоторый массив и как & работает так, что newTab->pFunFree = &free_MY_CAR видит этот массив, который newTab->pDat возвращает?

Я плохо понимаю указатели.Я только знаю, что & хранит адрес переменной, а * является указателем или значением переменной.Кто-нибудь может подсказать мне, как правильно его использовать и как он работает?Я новичок, так что не будь таким строгим со мной.

Заранее спасибо!

#pragma once
struct MY_CAR {
    char *model;
    int year;
};


void print_MY_CAR(void* pdata);
void free_MY_CAR(void *pdata);

MY_CAR* alloc_MY_CAR();



    switch (typ) {
        case 0:
            newTab->pDat = alloc_MY_CAR();
            newTab->pFunFree = &free_MY_CAR;
            newTab->pFunPrint = &print_MY_CAR;
            break;
    }
    MY_CAR* alloc_MY_CAR() {
        MY_CAR* tab = (MY_CAR*)calloc(1, sizeof(MY_CAR));
        if (!tab) {
            exit(0);
        }
        else {
            char model[125];
            printf("Podaj model: ");
            scanf("%s", model);
            tab->model = (char*)calloc(strlen(model) + 1, sizeof(char));
            strcpy(tab->model, model);
            printf("Podaj rok: ");
            scanf_s("%d", &tab->year);
        }
        return tab;
    }
void free_MY_CAR(void *pdata) {
    MY_CAR* car = (MY_CAR*)pdata;
    if (!car || !car->model) return ;
    free(car->model);
    free(car);
}

1 Ответ

1 голос
/ 20 июня 2019

Обратите внимание, что функция free_MY_CAR имеет аргумент типа void*, указатель на тип void (который является C-идиомой для указателя на что-то, не указывая тип вещи, на которую указывает), и первое, что он делает, это интерпретирует этот указатель как указатель на MY_CAR.

Так что функция, вероятно, предназначена для вызова так:

newTab-> pFunFree (newTab-> PdAt);

То есть способ, которым функции «знают», какой указатель был возвращен alloc_MY_CAR() и хранится в newTab->pDat является то, что программист явно сообщает функции, что указатель хранится в newTab->pDat.

Преимущество таких действий состоит в том, что он позволяет некоторому коду выполнять некоторые операции со структурой данных, не обязательно зная, над какой структурой данных он будет работать, когда программа действительно выполняется. При вызове pFunFree выше, newTab мог быть инициализирован кодом case 0, показанным в вопросе, но мог быть другой случай который инициализирует его с alloc_MY_JOB(), &free_MY_JOB и &print_MY_JOB, где функции MY_JOB выделяют / освобождают / печатают структуру данных, которая сильно отличается от структуры данных, используемой alloc_MY_CAR(), &free_MY_CAR и &print_MY_CAR. Тогда, если вы позвоните

newTab-> pFunPrint (newTab-> PdAt);

мы не сможем предсказать, когда мы напишем код, будет ли он печатать содержимое структуры данных, созданной alloc_MY_CAR() или alloc_MY_JOB(); но мы можем предсказать, что он напечатает подробную информацию, которая у него есть о вашем автомобиле, вашей работе или о чем-либо, что было прочитано из файла данных и сохранено в newTab.

Свойство, которое мы можем сделать вызовом функции, которая использует структуру данных способом, соответствующим этой структуре данных, без необходимости знать, когда мы пишем код, каким будет тип структуры данных, называется полиморфизм .

Это громоздкая идиома, и есть много способов ошибиться. Одним из преимуществ C ++ является то, что людям проще писать полиморфные объекты.

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