从 (void**) 转换为 (int*),反之亦然
Cast from (void**) to (int*) and viceversa
我做了一个函数 f,它将 a (void*) 作为输入,将其转换为 (int*) 并打印值。
#include <stdlib.h>
#include <stdio.h>
void f(void* p)
{
int *pi = (int*)p;
printf("%d\n", *pi);
}
int main()
{
int x = 1;
int *px = &x;
void *pv = (void*)px;
f(pv);
return 0;
}
是否可以实现一个功能:
void f2(void** pp);
使得它执行函数 f 的“相同”操作?我的目标是学习如何将 (int*) 转换为 (void**),反之亦然。
编辑:@tadman 代码的错误和警告(我做错了)
fvv.c: In function ‘f2’:
fvv.c:10:12: warning: initialization of ‘int *’ from incompatible pointer type ‘int **’ [-Wincompatible-pointer-types]
10 | int *pi = (int**)p;
| ^
fvv.c:12:17: error: invalid type argument of unary ‘*’ (have ‘int’)
12 | printf("%d\n", **pi);
|
编辑2
fvv.c: In function ‘main’:
fvv.c:19:5: warning: passing argument 1 of ‘f2’ from incompatible pointer type [-Wincompatible-pointer-types]
19 | f2(&px);
| ^~~
| |
| int **
fvv.c:7:16: note: expected ‘void **’ but argument is of type ‘int **’
7 | void f2(void** p)
您可以采用任何您想要的间接级别,直至公然、完全荒谬 (void*******
),但我不确定为什么这会有用:
void f2(void** p)
{
// Note you must maintain the same level of indirection
int **pi = (int**)p;
// Since this is a ** pointer, it requires ** to fully de-reference
printf("%d\n", **pi);
}
要调用它,您需要一个指向指针的指针:
int x = 1;
int *px = &x;
f2((void**) &px);
在 C 术语中,指向指针的指针通常被解释为以下两种情况之一:
- 二维数组
- 一个可变指针参数
这里都不适用。
话虽这么说,但在 C 语言中并没有太多关于可以转换和不能转换的规则。如果您想这样做,C 不会妨碍您,即使生成的代码毫无意义或在执行时会立即崩溃。
您可以将 int*
转换为 void**
然后再转换回来,C 不会在意,但是您应该有一个很好的理由来做这样的事情。通常任意指针几乎总是被指定为 void*
,因为这可以重新转换为 任何你想要的,这就足够了。
例如,当指针实际上是 int**
时,您可以将 void*
指定为参数,这是您经常看到的,例如 thread_create
接受 [=19] =] 参数。不仅限于指点,大家可以随心所欲地投射。
我做了一个函数 f,它将 a (void*) 作为输入,将其转换为 (int*) 并打印值。
#include <stdlib.h>
#include <stdio.h>
void f(void* p)
{
int *pi = (int*)p;
printf("%d\n", *pi);
}
int main()
{
int x = 1;
int *px = &x;
void *pv = (void*)px;
f(pv);
return 0;
}
是否可以实现一个功能:
void f2(void** pp);
使得它执行函数 f 的“相同”操作?我的目标是学习如何将 (int*) 转换为 (void**),反之亦然。
编辑:@tadman 代码的错误和警告(我做错了)
fvv.c: In function ‘f2’:
fvv.c:10:12: warning: initialization of ‘int *’ from incompatible pointer type ‘int **’ [-Wincompatible-pointer-types]
10 | int *pi = (int**)p;
| ^
fvv.c:12:17: error: invalid type argument of unary ‘*’ (have ‘int’)
12 | printf("%d\n", **pi);
|
编辑2
fvv.c: In function ‘main’:
fvv.c:19:5: warning: passing argument 1 of ‘f2’ from incompatible pointer type [-Wincompatible-pointer-types]
19 | f2(&px);
| ^~~
| |
| int **
fvv.c:7:16: note: expected ‘void **’ but argument is of type ‘int **’
7 | void f2(void** p)
您可以采用任何您想要的间接级别,直至公然、完全荒谬 (void*******
),但我不确定为什么这会有用:
void f2(void** p)
{
// Note you must maintain the same level of indirection
int **pi = (int**)p;
// Since this is a ** pointer, it requires ** to fully de-reference
printf("%d\n", **pi);
}
要调用它,您需要一个指向指针的指针:
int x = 1;
int *px = &x;
f2((void**) &px);
在 C 术语中,指向指针的指针通常被解释为以下两种情况之一:
- 二维数组
- 一个可变指针参数
这里都不适用。
话虽这么说,但在 C 语言中并没有太多关于可以转换和不能转换的规则。如果您想这样做,C 不会妨碍您,即使生成的代码毫无意义或在执行时会立即崩溃。
您可以将 int*
转换为 void**
然后再转换回来,C 不会在意,但是您应该有一个很好的理由来做这样的事情。通常任意指针几乎总是被指定为 void*
,因为这可以重新转换为 任何你想要的,这就足够了。
例如,当指针实际上是 int**
时,您可以将 void*
指定为参数,这是您经常看到的,例如 thread_create
接受 [=19] =] 参数。不仅限于指点,大家可以随心所欲地投射。