当前位置: 首页 > 知识库问答 >
问题:

将void指针强制转换为double而不知道其在C中的类型

申屠泳
2023-03-14

我需要编写一个函数,它将一个空指针(表示数组)和一个表示数组长度的整数作为参数。在函数中,我需要将这个空指针转换为双指针。问题是void指针可以表示整数、浮点或双精度的数组。因此,在void指针表示整数或浮点数组的情况下,以下内容显然不起作用:

void foo(void *v,int n){
    double *values;

    values=(double*)v;
    for(i=0;i<n;i++)
        printf("%f\n",values[i]);
}

因此,这将打印正确的输出:

foo((double[]){1,2,3,4},4);

这将打印错误的输出:

foo((int[]){1,2,3,4},4);
foo((float[]){1,2,3,4},4);

因此...我可以正确地将空指针投射到一个双1,只知道它可以是整数或浮点数或双数组吗?有必要有数组的长度吗?或者我可以用某种方式计算它?P. S.不使用回调

共有1个答案

燕志学
2023-03-14

只有知道空指针可以是整数数组、浮点数数组或双精度数组,我才能正确地将它转换为双精度指针吗?

不,你不能。您需要以某种方式传递类型信息。

有必要知道数组的长度吗,或者我可以计算出来?

通过长度是必要的。

您可以将信息“隐藏”在结构中

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum etype { INTEGER, FLOAT, DOUBLE };
struct data {
    void *values;
    size_t n;
    enum etype type;
};

void foo(struct data *x) {
    int *xd = x->values;
    float *xf = x->values;
    double *xg = x->values;
    for (int k = 0; k < x->n; k++) {
        switch (x->type) {
            default: printf("%g ", xg[k]); break;
            case FLOAT: printf("%f ", xf[k]); break;
            case INTEGER: printf("%d ", xd[k]); break;
        }
    }
    puts("");
}

int main(void) {
    struct data x;

    x.values = malloc(4 * sizeof(int));
    ((int*)(x.values))[0] = 42;
    ((int*)(x.values))[1] = -1;
    ((int*)(x.values))[2] = 0;
    ((int*)(x.values))[3] = 999;
    x.n = 4;
    x.type = INTEGER;
    foo(&x);

    x.values = calloc(4, sizeof(float));
    x.type = FLOAT;
    float tmp = 3.14159;
    memcpy(((float*)(x.values))+1, &tmp, sizeof (float));
    foo(&x);
    free(x.values);

    x.values = calloc(4, sizeof(double));
    x.type = DOUBLE;
    ((double*)(x.values))[2] = 2.7182818;
    foo(&x);
    free(x.values);
}

查看在ideone上运行的代码

 类似资料:
  • 指针变量数据类型的强制转换 必须显式强制类型转换,不允许隐式类型转换 指向空间的强制类型转换,本质上就是普通变量的强制类型转换 int a = 10; float b = 3.14; int *pa = &a; float *pb = &b; *pa = (int)*pb; // 等价于 a = (int)b; 指针本身强制类型转换,改变的是对其指向空间的引用方式(空间大小和存储结构) int

  • 公有派生类的对象可作为其相应基类的对象处理,这使得一些有意义的操作成为可能。例如,从某个特定基类派生出来的各种类,尽管这些类的对象彼此之间互不相同,但是仍然能够建立这些对象的链表,只要把这些对象作为基类对象处理就可以了。然而反过来是不行的,基类的对象不能自动成为派生类的对象。 常见编程错误 9.1 将基类对象作为派生类对象处理。 程序员可以用显式类型转换把基类指针强制转换为派生类指针。但是,如果要

  • 关于指针的转换,C草案标准(N3337)有以下内容: 4.10指针转换 2“指向cv的指针”类型的右值(其中T是对象类型)可以转换为“指向cv的指针无效”类型的右值将“指向cv的指针”转换为“指向cv的指针无效”的结果指向类型为T的对象所在的存储位置的起点,就好像该对象是类型为T的派生度最高的对象(1.8)(即,不是基类子对象)。 和 4.12布尔转换 1算术、枚举、指针或指向成员类型的指针的右值

  • 有一些东西让我困惑,我没有找到关于VM规范的太多信息。这有点晦涩,如果有人能给我解释一下就好了。 这几行代码...... ..... 生成此输出: 浮动:无限 int: 2147483647 短:-1 字节:-1 、和是8位、16位和32位,带有两个补码和是32位和64位的IEEE 754(参见此处)。 根据我的理解,最大值的意味着尾数的所有位(52位)都切换到1。因此,转换为短或字节返回-1,即

  • 假设代码是用c11编译的,并且启用了严格别名。 我不是在寻找一种不同的方法,我想专注于这个具体的问题,以及它是否可行或为什么不可行。 (如果我无意中犯了一些无关的错误,请告诉我,我会改正的) C11标准说: 6.2.5.28所有指向结构类型的指针应具有彼此相同的表示和对齐要求。 6.7.2.1.6结构是由成员序列组成的类型,其存储按有序顺序分配 这意味着结构A和B中指针的大小和对齐方式相同。 结构