表达式必须具有指向结构或联合的指针类型?

Expression must have pointer-to-struct-or-union type?

使用链表从链表的头部提取数据。数据已在 Head 中设置,但当我尝试访问它时出现该错误。认为指针存在问题,但我无法解决。

int main(int argc, char **argv)
{
    int i;

    struct timeval start, end;
    struct element *Head = NULL;
    struct element *Tail = NULL;

    //creating job queue
    for (i = 0; i < NUMBER_OF_JOBS; i++) {
        addLast(generateProcess(), &Head, &Tail);
    }

    //go through job queue running processes and removing processes
    while (Head) {
        runPreemptiveJob(Head->pData, &start, &end);

        int responseTime = getDifferenceInMilliSeconds(Head->pData->oTimeCreated, start);

        printf("Response Time is: %d\n", responseTime);

        Head = Head->pNext;
    }
}

我希望能够通过 head 元素访问它来使用 oTimeCreated 中的数据,它的数据字段中有一个结构。

调用 getDifferenceInMilliSeconds 函数时出现错误:我在 Head 上收到一条错误消息,提示“表达式必须具有指向结构或联合的指针类型。

此处显示元素:

struct element
{
    void * pData;
    struct element * pNext;
};

generateProcess() returns 一个结构进程,定义如下:

struct process
{
    int iProcessId;
    struct timeval oTimeCreated;
    struct timeval oMostRecentTime; 
    int iInitialBurstTime;
    int iPreviousBurstTime;
    int iRemainingBurstTime;
    int iPriority;
};

在主函数中,generateProcess() returns 一个指向进程的指针。这个指针被放入链表中,所以我试图访问 oTimeCreated 变量,它是列表头部结构的一部分。

错误与 Head 无关,而与 Head->pData 有关。请密切注意错误消息。对于某些编译器,错误消息清楚地标识了一行,但没有标识行内的确切位置;如果你的编译器的错误不清楚,你可以通过添加换行符和创建更多的中间变量来获得更精确的错误位置。

void *data = Head->pData;
struct timeval time_created = data->oTimeCreated;
int responseTime = getDifferenceInMilliSeconds(time_created, start);

请注意,要以这种方式编写代码,我必须为中间表达式 Head->pDatadata->oTimeCreated 指定类型。为了弄清楚要给出什么类型,我查看了 struct elementstruct process.

的定义

特别是Head->pData的类型是void*。那是指向未指定类型的指针。您不能取消引用它,特别是 data->oTimeCreated 会导致编译错误,因为 data 不是指向结构或联合的指针。未指定的类型不是结构或联合。

C 没有 polymorphism baked into the language. It allows polymorphism, via void pointers, but like with many things in C, you need to do some of the job yourself. C does not keep track of what the actual type of an object is if you only have a void pointer to it. You have to specify when you want to dereference the pointer, and you need to get it right, otherwise anything can happen.

如果您确定放入列表的是指向 struct process 的指针并且仍然有效,则将 void 指针转换或强制转换为指向 struct process 的指针。这是一种惯用的方法:

struct process *head_process = Head->pData;
runPreemptiveJob(head_process, &start, &end);
int responseTime = getDifferenceInMilliSeconds(head_process->oTimeCreated, start);