【问题标题】:How to pass float pointer to function which takes double pointer如何将浮点指针传递给采用双指针的函数
【发布时间】:2020-12-17 15:33:43
【问题描述】:

我有一个函数,它接收一个指向双精度的指针 并对它做一些事情。假设我有一个指向浮点数的指针 它是通过 malloc 或 calloc 创建的。我如何将此指针传递给函数 正确吗?我尝试通过 (double *)var 进行简单转换,但这并没有达到我的预期。

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

void TestFunc(double *x, long arr_size)
{
    long i;
    for (i=0; i<arr_size; ++i)
        x[i] = (double)i;
}


int main()
{
    long i;
    long n = 10;
    float *x = (float *)calloc(sizeof(float), n);

    TestFunc((double *)x, n);

    for (i=0; i<n; ++i)
        printf("%f\n", x[i]);

    return 0;
}

我也尝试过使用指针算法而不是索引:

void TestFunc(double *x, long arr_size, size_t size)
{
    long i;
    for (i=0; i<arr_size; ++i)
    {
        *x = (double)i;
        x += size;
    }
    x -= size*arr_size;
}

int main()
{
    long i;
    long n = 10;
    float *x = (float *)calloc(sizeof(float), n);

    TestFunc((double *)x, n, sizeof(float *));

    for (i=0; i<n; ++i)
        printf("%f\n", x[i]);

    return 0;
}

第一种方法的结果是:

0.000000
0.000000
0.000000
1.875000
0.000000
2.000000
0.000000
2.125000
0.000000
2.250000

第二个的输出全为零,而我希望是 0.0,...,9.0。有什么建议吗?

编辑:目标是使以下代码更短。这是一个 Python 扩展,我想安全地处理各种数据类型。

if (typenum == NPY_FLOAT)
    _array_from_one(data, y, dim, float, CName##_Float);
else if (typenum == NPY_DOUBLE)
    _array_from_one(data, y, dim, double, CName##_Double);
else if (typenum == NPY_LONGDOUBLE)
    _array_from_one(data, y, dim, long double, CName##_Long_Double);
else
{
    if (typenum == NPY_BYTE)
        _array_to_double(data, y, dim, char, CName##_Double);
    else if (typenum == NPY_UBYTE)
        _array_to_double(data, y, dim, unsigned char, CName##_Double);
    else if (typenum == NPY_SHORT)
        _array_to_double(data, y, dim, short, CName##_Double);
    else if (typenum == NPY_USHORT)
        _array_to_double(data, y, dim, unsigned short, CName##_Double);
    else if (typenum == NPY_INT)
        _array_to_double(data, y, dim, int, CName##_Double);
    else if (typenum == NPY_UINT)
        _array_to_double(data, y, dim, unsigned int, CName##_Double);
    else if (typenum == NPY_LONG)
        _array_to_double(data, y, dim, long, CName##_Double);
    else if (typenum == NPY_ULONG)
        _array_to_double(data, y, dim, unsigned long, CName##_Double);
    else if (typenum == NPY_LONGLONG)
        _array_to_double(data, y, dim, long long, CName##_Double);
    else if (typenum == NPY_ULONGLONG)
        _array_to_double(data, y, dim, unsigned long long, CName##_Double);
    else {
        PyErr_Format(PyExc_TypeError,
                    "Invalid data type.",
                    VarToString(FuncName));
        return NULL;
    }
    typenum = NPY_DOUBLE;
}

这两个宏的定义是:

#define _array_from_one(x, y, dim, type, f) ({                                 \
    long i;                                                                    \
    type *out = (type *)malloc(sizeof(type)*dim);                              \
    for (i=0; i<dim; ++i) out[i] = (*f)(((type *)x)[i]);                       \
    y = out;                                                                   \
})

#define _array_to_double(x, y, dim, type, f) ({                                \
    long i;                                                                    \
    double *out = (double *)malloc(sizeof(double)*dim);                        \
    for (i=0; i<dim; ++i)                                                      \
        out[i] = (*f)((double)((type *)x)[i]);                                 \
    y = out;                                                                   \
})

这很有效,允许我安全地传递浮点数、双精度数和长双精度 numpy 数组,同时保持精度,并将所有整数类型转换为双精度并处理它们,但它很难看。这个问题开头的代码旨在缩短和清理它。欢迎提出任何建议!

【问题讨论】:

  • 你不能这样做,因为float 不是double
  • 是的,我明白这一点,我目前的解决方案是拥有单独的功能。但是,实际代码是针对 Python 包的,我希望安全地处理大量类型的 numpy 数组(char、int、short、long、long long、float、double、long double 和它们的无符号对应物)。每个函数有 13 个别名意味着相当多的函数!

标签: c pointers casting


【解决方案1】:

如何将浮点指针传递给采用双指针的函数

如果更改测试函数不是选项以及x 的类型,请将float 元素分配给double 数组,调用测试函数,然后再次分配。

double tmp[n];  // VLA or the usual malloc/free
for (i=0; i<n; i++) tmp[i] = x[i];
TestFunc(tmp, n);
for (i=0; i<n; i++) x[i] = tmp[i];

【讨论】:

  • Welp,我是个白痴,这是一个非常简单的解决方案。谢谢!但是,以这种方式对数组或指针进行类型转换是不合法的吗?
  • @RyanMaguire 有一些抱怨的方法来执行指针转换,但是代码不能单独通过转换来实现所需的功能。每个数组元素都需要在 FP 类型之间进行转换。
  • @RyanMaguire 您需要一个有效的double* 值,这意味着它需要指向内存中double 类型的有效对象。如果您有一个 float 数组,则内存中没有可指向的 double 对象。您需要在内存中创建一个 double 对象数组。没有办法解决(除非您可以更改函数预期的类型或现有数组的类型,这两者似乎都不可能)。
【解决方案2】:

我猜在您的第一个代码中,您为浮点类型分配了内存。然后将 x 的变量类型更改为 double,这比 float 占用更多的内存。也可以尝试将函数作为变量调用,然后打印出来。

【讨论】:

  • 对不起,我不明白最后一点“尝试也将函数作为变量调用然后打印出来。”你能解释一下吗?
  • 忘记这部分下面发布的新答案,我自己解决了
【解决方案3】:

解决了!将 double 更改为像那样浮动 'void TestFunc(float *x, long arr_size)' 并在您的主要功能 TestFunc(x, n);应该是这样的

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

void TestFunc(float *x, long arr_size)
{
    long i;
    for (i=0; i<arr_size; ++i)
        x[i] = (float)i;
}

int main()
{
    long i;
    long n = 10;
    float *x = (float *)calloc(sizeof(float), n);

    TestFunc(x, n);

    for (i = 0; i < n; ++i)
        printf("%f\n", x[i]);

    return 0;
}

【讨论】:

  • 对不起,问题的关键是如何安全地将 A 类型的指针传递给需要 B 类型的函数。这就是为什么 TestFunc 需要一个双精度,而我想传递一个浮点数。很抱歉!
猜你喜欢
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-20
  • 1970-01-01
相关资源
最近更新 更多