Массив указателей разыменовывается при доступе в C - PullRequest
0 голосов
/ 29 июня 2018

У меня есть структура массива, которая должна содержать указатель на другую структуру. Мои структуры такие:

struct Term{
    char* term;
    int times;
};
typedef struct Term TERM;

struct HeapTer{
    TERM* Term;
    size_t used;
    size_t size;
};
typedef struct HeapTer HEAPTER;

struct Pack{
    HEAPCON* hCon;
    HEAPTER* hTer;
};
typedef struct Pack PACK;

Пакет будет содержать указатели обоих массивов, которые я вернусь из функции загрузки структуры.

Моя проблема в том, когда я вызову функцию, где я вставлю данный термин в кучу терминов для консультаций.

InsertHeapTer(pack->hTer->Term[ind_term],consult->hTer)

Где InsertHeapTer определяется как InsertHeapTer(TERM* Ter, HEAPTER *t). Компилятор выдает мне следующую ошибку: error: incompatible types when assigning to type 'TERM {aka struct Term}' from type 'TERM * {aka struct Term *}'.

Итак, он говорит, что когда я использую pack->hTer->Term[ind_term], он дает мне TERM, а не TERM*, даже если он определен как указатель в структуре. Что я делаю не так и почему это происходит?

EDIT: Код для воспроизведения:

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

struct Termo{
    char* termo;
    int vezes;
};
typedef struct Termo TERMO;

struct HeapTer{
    TERMO* Termo;
    size_t usado;
    size_t tam;
};
typedef struct HeapTer HEAPTER;

struct consulta{
    char *Local;
    HEAPTER *hTer;
};
typedef struct consulta CONSULTA;

struct HeapCon{
    CONSULTA* con;
    size_t usado;
    size_t tam;
};
typedef struct HeapCon HEAPCON;

struct Pacote{
    HEAPCON* hCon;
    HEAPTER* hTer;
};
typedef struct Pacote PACOTE;

void InsereHeapTer(TERMO* Ter, HEAPTER *t){
}

int main(){
    PACOTE* pack;
    CONSULTA* consulta;
    int ind_termo=1;

    InsereHeapTer(pack->hTer->Termo[ind_termo],consulta->hTer);

    return 0;
}

void InsereHeapTer(TERMO* Ter, HEAPTER *t){
}

Извините, но это была минимальная настройка, которую я мог сделать.

Ответы [ 2 ]

0 голосов
/ 30 июня 2018

Чтобы упростить некорректную строку кода, вы можете сделать:

TERMO* termo = pack->hTer->Termo;
InsereHeapTer(termo[ind_termo],consulta->hTer);

Очевидно, termo - это TERMO*. Оператор [] определяется следующим образом:

Определение подстрочного оператора [] состоит в том, что E1[E2] идентичен (*((E1)+(E2))).
С.11 - раздел 6.5.2.1 - пункт 2

Таким образом, ваш вызов функции эквивалентен:

InsereHeapTer(*(termo + ind_termo),consulta->hTer);

И это можно снова упростить:

TERMO* termo_plus_ind = termo + ind_termo;
InsereHeapTer(*termo_plus_ind,consulta->hTer);

Когда вы разыменовываете TERMO*, вы получаете TERMO.

0 голосов
/ 29 июня 2018

Итак, это говорит о том, что когда я использую pack->hTer->Term[ind_term], это дает я TERM а не TERM*,

Да.

даже если он определен как указатель в структура.

Будьте осторожны: даже если что определяется как указатель? Это pack->hTer->Term, который так определен. В таком случае pack->hTer->Term[ind_term] действительно имеет тип TERM. Это эквивалентно *(pack->hTer->Term + ind_term).

И это предполагает решение: если вы намеревались передать указатель на этот элемент вместо копии элемента, то вы можете использовать арифметику указателей для получения искомого указателя как pack->hTer->Term + ind_term. Я склонен предпочесть простоту этого, но стилистически я уверен, что некоторые люди предпочли бы эквивалентное выражение &pack->hTer->Term[ind_term].

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