[英]void pointer in function parameter
考虑以下程序:
#include <iostream>
void f(void* a)
{
std::cout<<"(void*)fun is called\n";
std::cout<<*(int*)a<<'\n';
}
int main()
{
int a=9;
void* b=(int*)&a;
f(b);
return 0;
}
如果我像这样更改函数调用语句:
f(&b);
它仍然可以正常编译并在运行时崩溃。 为什么? 是什么原因? 我应该不会得到编译时错误吗? 因为调用函数的正确方法是f(b)。 对? 另外,为什么允许将NULL传递给参数类型为(void *)的函数?
如果我缺少某些内容或对某些内容的理解不正确,请纠正我。
它仍然可以正常编译并在运行时崩溃。 为什么? 是什么原因?
因为void*
是删除所有类型安全和类型检查的技术。
我应该不会得到编译时错误吗?
通过使用void*
而不是正确的指针类型int*
,您明确地告诉编译器不要告诉您是否使用了错误的类型或未定义的类型。
因为调用函数的正确方法是f(b)。 对?
那就是您的函数声明和内容不一致的地方。
std::cout<<"(void*)fun is called\n";
std::cout<<*(int*)a<<'\n';
上面的内容暗示应该传递一个指向int
的指针:
void f(void* a)
该声明意味着应该传递一些指针 ,并且没有其他限制。
void*
可以捕获任何类型的指针, void**
也不例外
第一
您可以将void*
指向void**
。 您的代码是许多显示void*
指针多么危险的示例之一。
第二
您应该将类型转换用于:
void* b = static_cast<int*>(&a);
而不是c样式转换,您正在使用:
void*b = (int*)&a;
好。
按照要求。
除非您无法想到其他方法,否则不要使用空指针。
然后上床睡觉再想一想。
空指针使程序员可以忘记类型。 这意味着编译可以放弃简单的检查。 在我看来,这也意味着程序员已经失去了情节。
如果您愿意,请否决我。
使用类型的好处是编译器可以为您检查内容。 例如,事物之间的关系。 如何对待那个物体。
但是使用空指针,您将非常自己。 祝好运
您不会遇到编译时错误,因为f(&b)
调用f
并将b
的地址作为参数传递,然后将其转换为void*
。 您会收到一个运行时错误,因为那样您试图将一个指针转换为整数。 但是,是的,正如其他人所说,这样做非常不好。
如果我这样更改函数调用语句:f(&b); 它仍然可以正常编译并在运行时崩溃。 为什么?
您的函数f(void*)
将毫无疑问地接受任何类型的指针。 任何指针都会悄悄地转换为空指针。 指向指针的指针仍然是指针。 因此,您的第二种情况确实可以编译。 然后崩溃。 也许。
在第一种情况下,您将指针从int转换为指针以将void转换回指向int的指针。 通过void*
(以及通过char*
)的那些往返转换必须起作用。 在第二种情况下,您从void**
转换为void*
转换为int*
。 现在,您正在调用未定义的行为。 什么都行。 在我的计算机上,在我的编译器上,您的代码可以正常运行。 它打印垃圾。 我非常确定您的代码不会擦除我的硬盘,但是可以。 任何事情都伴随着不确定的行为。 不要调用未定义的行为。
支持void*
的原因是历史性的。 许多旧的C和C ++代码都使用void指针。 编写使用空指针的新C ++代码的唯一原因是,如果您需要与使用空指针的那些旧函数之一进行交互。
我发现自己在这里是因为我正在从事一项要求相同功能的家庭作业。 合并每个评论后,这就是我的想法。
// A function that accepts a void pointer
void f(void* a)
{
std::cout<<"(void*)fun is called\n";
std::cout<< "value for a: " << *(int*)a << '\n';
}
int main() {
int a = 9;
void* c = static_cast<int*>(&a);
int b = 3;
f(&b);
f(c);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.