我需要了解为什么将void*
分配给int**
会有效,但是在打印int**
的值时,它将无效。这是代码:
int k = 3;
int *l = &k;
void *a = l;
int **c = a; // if I assign, &a, the below line work, but get warning: incompatible
// pointer type.
printf("%d", **c); // Code break;
但这一行
printf("%d", *c); // will work, but get warning "%d expect int but of type int *".
更新:我在OOC book
中看到了这种类型的代码:作者这样做:
struct Class {
size_t size;
int (*differ)(const void *self, const void *b);
..... Some more code ....
};
int differ(const void *self, const void *b) {
// Note this line
const struct Class **cp = self;
assert(self && *cp && (*cp)->differ);
return (*cp)->differ(self, b);
}
答案 0 :(得分:3)
你有这种情况:
+---+ | l | --\ +---+ \ +---+ >--> | k | +---+ / +---+ | a | --/ +---+
即。 l
和a
都直接指向k
。
然后你做
int **c = a;
你使c
指向a
所指向的内容(即它与执行int **c = &k
相同),但是你声明c
是一个指针指向int
的指针,但指向int
。这意味着使用单个解除引用(*c
)可以获得k
的值,当您使用双重引用(**c
)时,可以使用k
的值作为指针(事实并非如此)。
我认为你真正想要的是这种情况:
+---+ +---+ +---+ | a | --> | l | --> | k | +---+ +---+ +---+
你将通过
获得void *a = &l;
然后使用c
作为指针指针将起作用,因为a
是指向指针的指针。
如果您继续第一个方案,那么
int k;
int *l = &k;
void *a = l;
然后再做
int **c = (int **) &a; // The typecast is needed
然后你有以下情况:
+---+ | l | --\ +---+ \ +---+ >--> | k | +---+ +---+ / +---+ | c | --> | a | --/ +---+ +---+
这样可行,因为c
实际上是指向某事物指针的指针。
答案 1 :(得分:2)
这就是为什么你必须小心void*
指针。您可以为它们分配任何指针,并可以将它们分配给任何其他指针。即使它没有意义(如你的例子)。
当您指定int **c = a
时,您已经犯了一个错误,我认为您已经意识到这一点。您已更改了间接级别(a
来自int*
,但您已将其分配给int**
),但未提取其他地址-of(&
)。
您的程序失败的原因相同,如果您删除了void* a
,而是尝试了此操作,则会失败。
int k = 3;
int *l = &k;
int **c = l; // Error - wrong level of indirection.
这是低级别C.只是因为编译器让你做某事并不意味着它会起作用。
这个问题的解决方案是:不要这样做。