p-> data = (int *) malloc (sizeof (int));сравнить с (int *) p-> data = (int *) malloc (sizeof (int)); - PullRequest
1 голос
/ 26 августа 2010
typedef struct _DListNode
{
    struct _DListNode* prev;
    struct _DListNode* next;
    void*  data;
}DListNode;

в gcc:

DListNode *p = NULL;

p = (DListNode*)malloc(sizeof(DListNode));

p->data = (int*)malloc(sizeof(int));   

scanf("%d", (int*)p->data);

скомпилировать правильно.

в gcc:

DListNode *p = NULL;

p = (DListNode*)malloc(sizeof(DListNode));

(int*)p->data = (int*)malloc(sizeof(int)); 

scanf("%d", (int*)p->data);

Возникла проблема:

(int*)p->data = (int*)malloc(sizeof(int)); -------error: lvalue required as left operand of assignment.

разница:

scanf("%d", (int*)p->data) ,

(int*)p->data = (int*)malloc(sizeof(int)),

p->data = (int*)malloc(sizeof(int));

Ответы [ 5 ]

2 голосов
/ 26 августа 2010

Есть ли веская причина иметь void* вместо int* в struct _DListNode? Если нет, измените его на int*, и тогда вам не нужно каких-либо приведений. Во-первых, всегда лучше, чтобы типы были правильными, чем разбрасывать приведения во всем коде.

Ошибка, которую вы получаете, заключается в том, что вы просто не можете поставить приведение слева от задания. Это против правил. Вам нужно прочитать, что такое lvalues ​​и rvalues ​​ и в чем разница между ними.

2 голосов
/ 26 августа 2010

Разница между утверждениями заключается в том, что нет смысла пытаться указать тип указателя в левой части выражения, что вы и делаете в случае (int*)p->data, поскольку p->data всегда void*, как определено в структуре. Когда компилятор видит это, он предполагает, что вы приводите его к int*, чтобы вы могли прочитать его, то есть оно становится r-значением, значением, которое допустимо только в правой части выражения присваивания, а не значение l (левая сторона), которому можно присвоить.

Если вы хотите прочитать / записать целочисленное значение, хранящееся в p->data, то я думаю, что самый ясный синтаксис - *((int*)(p->data)) - т.е. возьмите указатель p->data, приведите его к int* и затем разыменуйте это - Я уверен, что вы можете потерять некоторые из скобок из-за правил приоритета.

data - пустой указатель; его не волнует, что вы храните в нем, т. е. ваше (int*) приведение к malloc эффективно теряется; его волнует только то, что вы дали ему выделенную память.

1 голос
/ 26 августа 2010

Как насчет (int*&)p->data = (int*)malloc(sizeof(int)); "?

(int *) дает само значение указателя, т. Е. Все равно, что сказать 0x12345678 = malloc(sizeof(int));.

Кстати, злоупотребление чем-то таким маленьким, как int, чрезвычайно расточительно.

EDIT:

  1. Это может работать только в C ++, но не в C.

  2. Почему вы играете в первую очередь? Вы назначаете пустой указатель на пустой указатель. Разве это не удобно? Почему бросили?

  3. Если вы действительно хотите развлечь себя, вы можете сделать что-нибудь глупое, как *(int **) &(p->data) = (int *) malloc(sizeof(int));. Ерунда, да? Правильно. Просто назначьте значение. Еще лучше, замените ваши данные на объединение.

0 голосов
/ 26 августа 2010

Итак, какой у вас вопрос? И что должен означать этот раздел «разница»?

Пока что у вас проблема с

(int*)p->data = (int*)malloc(sizeof(int));

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

Итак, еще раз, какой у вас вопрос?

0 голосов
/ 26 августа 2010

Тип cast () имеет более высокий приоритет, чем ->, поэтому ваш первый равен ((int *) p) -data.Я думаю, что это не то, что вы хотите.

...