c# 在函数调用中自动将void指针转换为double指针

htzpubme  于 2023-04-04  发布在  C#
关注(0)|答案(3)|浏览(194)

我有一个问题,它可能已经在其他地方得到了回答,我找不到它,所以如果它已经存在,我道歉。
下面的代码:

#include <stdio.h>

void foo(double *number) {
    printf("%f\n", *number);
}

void bar(void *number) {
    double *new_number = (double *)number;
    printf("%f\n", *new_number);
}

int main()
{
    double test_number = 3.0;
    double *test_double_pointer = &test_number;
    void *test_void_pointer = (void *)test_double_pointer;
    
    foo(test_double_pointer);
    foo(test_void_pointer);
    bar(test_double_pointer);
    bar(test_void_pointer);

    return 0;
}

结果是

3.000000
3.000000
3.000000
3.000000

我不明白这里面发生了什么。C编译器是如何处理这些函数调用的?

k4emjkb1

k4emjkb11#

C编译器如何处理这些函数调用?
编译器知道如何转换指针。具体来说,

  • C编译器知道如何将double *转换为void *
  • C编译器知道如何将已转换为void *double *转换回double *

(On您可能使用的机器,不需要实际转换。)
它知道什么时候做。具体来说,

  • 当你转换为void *时,它知道它需要一个void *
  • 当你转换为double *时,它知道它需要一个double *
  • 当您分配给void *时,它知道它需要void *
  • 当你赋值给double *时,它知道它需要一个double *
  • 当参数的类型为void *时,它知道它需要一个void *参数。
  • 当参数的类型为double *时,它知道它需要一个double *参数。

(You我不想做所有这些,但我想包括一些常见的情况。)

fhg3lkii

fhg3lkii2#

首先变量名有点混乱(编辑前的标题也是)。通常,双指针被理解为指向指针的指针,而不是指向double的指针。
有人可能是用C编译器来编译C代码的。C和C是不同的语言,有自己的规则。
在C语言中,不需要对void *进行强制转换。在C++中,它需要显式的强制转换,没有强制转换的代码将无法编译https://godbolt.org/z/78KbW4Wdz
在底层,编译器只需要知道指针引用的是什么数据类型。

jgovgodb

jgovgodb3#

对于初学者,您可以按以下方式更改功能栏

void bar(void *number) {
    double *new_number = number;
    printf("%f\n", *new_number);
}

删除显式强制转换。
在C语言中,void * 类型的指针可以赋值给指向任何其他类型的对象的指针。
所以在这个调用中

foo(test_void_pointer);
bar(test_double_pointer);

类型void * 的指针可以被分配给类型double * 的参数,反之,类型double * 的指针可以被分配给类型void * 的参数。

相关问题