在普通 C 中,如何将 void 指针值分配给 double

发布于 2025-01-11 20:18:24 字数 449 浏览 0 评论 0原文

void foo(void* p) {
    double d = (double) p; // Doesn’t compile.
    printf(“%f\n”, d);
}

我需要的是能够打电话

foo((void*) 13.0);

并打印 13.0。

注意

我需要这个来存储源节点和存储在 C 哈希映射中的任意节点之间的距离(双精度类型),该哈希映射在图搜索中是通用的“void*”。请参阅 https://github.com/coderodde/Bi DirectionDijkstra4Perl2

void foo(void* p) {
    double d = (double) p; // Doesn’t compile.
    printf(“%f\n”, d);
}

What I need is to be able to call

foo((void*) 13.0);

and have 13.0 printed.

Note

I need this in order to store distances (of type double) between source nodes and arbitrary nodes stored in a C hash map that is “void*” generic in graph search. See https://github.com/coderodde/BidirectionalDijkstra4Perl2

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

兲鉂ぱ嘚淚 2025-01-18 20:18:25

当规范有通过 void * 提供数据的方法时,您通常打算使用它的方式是为数据分配内存并将内存地址作为 void *< /代码>。然后,接收数据的软件将void *转换为指向适当类型的指针,并使用该指针访问内存中的数据。

因此,如果您只需要一个 double 值,则执行此操作的方法是:

double *p = malloc(sizeof *p);  // Allocate memory for the data.
if (!p)  // Guard against allocation failure.
{
    fprintf(stderr, "Error, unable to allocate memory.\n");
    exit(EXIT_FAILURE);
}
*p = 13.0;  // Store data in memory.
foo(p);     // Pass the address of the data to foo.

稍后,在某个给出数据地址的例程中,您将执行如下操作:

void MyCallBackRoutine(void *vp) // Might be "const void *" instead.
{
    double *p = vp;  // Convert to "double *".  Might need "const" with it.
    printf("The conveyed data is %g.\n", *p);
}

您还应该当不再需要内存时释放内存。

如果您需要的不仅仅是一个 double 或其他单个项目,您可以创建一个包含您需要的所有成员的 struct 并将所有数据放入其中。

When specification has a means of providing data through void *, the way you are usually intended to use it is to allocate memory for the data and pass the address of the memory as a void *. Then the software that receives the data converts the void * to a pointer to the appropriate type and uses that pointer to access the data in memory.

Thus, if you just need a single double value, a way you would do this is:

double *p = malloc(sizeof *p);  // Allocate memory for the data.
if (!p)  // Guard against allocation failure.
{
    fprintf(stderr, "Error, unable to allocate memory.\n");
    exit(EXIT_FAILURE);
}
*p = 13.0;  // Store data in memory.
foo(p);     // Pass the address of the data to foo.

Later, in some routine that was given the address of the data, you would do something like this:

void MyCallBackRoutine(void *vp) // Might be "const void *" instead.
{
    double *p = vp;  // Convert to "double *".  Might need "const" with it.
    printf("The conveyed data is %g.\n", *p);
}

You should also free the memory when it is no longer needed.

If you need more than just a double or other single item, you would create a struct containing all the members you needed and put all the data into it.

乱了心跳 2025-01-18 20:18:25

你可以通过做一些指针技巧来做到这一点

void foo(void *p)
{
    double d = *((double *) &p);

    printf("%f\n", d);
}

它的工作原理是获取一个指向 p 的指针并将其取消引用为双精度型,因此您可以将 void * 转换为双精度型

但请注意,只有当双精度型和 void * 具有您的代码将在计算机上运行的相同长度
否则,由于 double 在内存中存储的方式,它无法工作

You can do it by doing a little pointer trick

void foo(void *p)
{
    double d = *((double *) &p);

    printf("%f\n", d);
}

It works by taking a pointer to p and dereferencing it as a double, so you can convert your void * to a double

But be aware that it's only works if the double and the void * have the same len on the computer your code will be run
Otherwise it cannot works because of the way double are stored in memory

忘你却要生生世世 2025-01-18 20:18:24

Eric 的回答给出了标准方式

但是,如果 void * 的大小不小于 double 的大小,则可以将 double 的表示形式存储在 <代码>无效*。从那时起,除了将表示形式提取回 double 对象之外,您不能使用指针执行任何操作。下面是一个演示它的示例代码:

#include <stdio.h>    
#include <assert.h>
#include <memory.h>

void foo(void* p) {
    double d;
    memcpy(&d, &p, sizeof(d));
    printf(" % f\n", d);
}

int main() {
    void* p;
    // ensure that the representation of a double can fit in a void *
    static_assert(sizeof(void*) >= sizeof(double), "sizeof(double) > sizeof(void *)");
    double d = 13.0;
    memcpy(&p, &d, sizeof(d));
    foo(p);
    return 0;
}

但是注意:这只能用作处理遗留代码的解决方法。可移植性仅限于 double 的大小不大于 void * 的大小的平台,这在 32 位平台上是错误的。在 32 位模式下编译上述代码会引发编译错误:

error ...: sizeof(double) > sizeof(void *)

The standard way has been given by Eric's answer.

But if the size of a void * is not smaller than the size of a double, you can store the representation of the double in a void *. From that point you cannot use the pointer for anything but extracting back the representation to a double object. Here is an example code demonstrating it:

#include <stdio.h>    
#include <assert.h>
#include <memory.h>

void foo(void* p) {
    double d;
    memcpy(&d, &p, sizeof(d));
    printf(" % f\n", d);
}

int main() {
    void* p;
    // ensure that the representation of a double can fit in a void *
    static_assert(sizeof(void*) >= sizeof(double), "sizeof(double) > sizeof(void *)");
    double d = 13.0;
    memcpy(&p, &d, sizeof(d));
    foo(p);
    return 0;
}

But beware: this should only be used as a workaround to cope with legacy code. The portability is limited to platforms where the size of a double is not greater than the size of a void * which is false on a 32 bits platform. Compiling above code in 32 bits mode raises a compilation error:

error ...: sizeof(double) > sizeof(void *)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文