p->data = (int*)malloc(sizeof(int)); compare to (int*)p->data = (int*)malloc(sizeof(int));
typedef struct _DListNode
{
struct _DListNode* prev;
struct _DListNode* next;
void* data;
}DListNode;
in gcc :
DListNode *p = NULL;
p = (DListNode*)malloc(sizeof(DListNode));
p->data = (int*)malloc(sizeof(int));
scanf("%d", (int*)p->data);
compile correctly.
in gcc :
DListNode *p = NULL;
p = (DListNode*)malloc(sizeof(DListNode));
(int*)p->data = (int*)malloc(sizeof(int));
scanf("%d", (int*)p->data);
There is a problem on :
(int*)p->data = (int*)malloc(sizeof(int)); -------error: lvalue开发者_如何学C required as left operand of assignment.
the difference:
scanf("%d", (int*)p->data) ,
(int*)p->data = (int*)malloc(sizeof(int)),
p->data = (int*)malloc(sizeof(int));
The difference between the statements is that it doesn't make sense to try and specify the pointer type on the left-hand-side of an expression which is what you're doing in the (int*)p->data
case because p->data
is always a void*
as defined in the structure. When the compiler sees this it assumes you're casting it to an int*
so that you can read it, i.e. it becomes an r-value, a value which is only valid on the right-hand-side of an assignment expression not an l-value (left-hand-side) which can be assigned to.
If you want to read / write an integer value stored in p->data
then I think the clearest syntax is *((int*)(p->data))
- i.e. take the p->data
pointer, cast it to an int*
and then dereference that - but I'm sure you can lose some of the brackets due to the precendence rules.
data
is a void pointer; it doesn't care what you store in it, i.e. your (int*)
cast on the malloc is effectively wasted; it only cares that you've given it some allocated memory.
Is there a good reason to have a void*
instead of an int*
in struct _DListNode
? If not, change it to int*
and then you don't need any of the casts. It's always better to make the types be correct in the first place than to sprinkle casts all over your code.
The error you're getting is because you simply cannot put a cast on the left side of an assignment. It's against the rules. You need to read up on what lvalues and rvalues are and what the difference between them is.
How about (int*&)p->data = (int*)malloc(sizeof(int));
"?
(int *) gives the pointer value itself, i.e. it's akin to saying 0x12345678 = malloc(sizeof(int));
.
Btw, mallocing for something as small as an int is extremely wasteful.
EDIT:
This might only work in C++, not C.
Why do you cast in the first place? You're assigning a void pointer to a void pointer. Isn't that convenient? Why cast?
If you really want to amuse yourself, you could do something silly like
*(int **) &(p->data) = (int *) malloc(sizeof(int));
. Nonsense, right? Right. Just assign the value. Better yet, replace your data with a union.
type cast() has high Precedence than ->, so your first one is equal to ((int*)p)-data. I think that's not what you want.
So, what is your question? And what is that "the difference" section supposed to mean?
So far, you've got the problem with
(int*)p->data = (int*)malloc(sizeof(int));
which is obviously an invalid statement. The compiler has already told you why.
So, once again, what is your question?
精彩评论