C cast语法,复杂的转换怎么样?

时间:2011-11-04 19:39:24

标签: c arrays casting

我需要一些C语言方面的帮助,更多关于C语法的语法。
我在网上找到的所有信息都是关于(int)(char)之类的简单演员...... 我总是陷入将void*投射到数组或多分区阵列或这类事物的指针,但我永远不知道该怎么做!在这些情况下,我所做的就是尝试(char [])(char *[])(*char [])之类的内容而不知道我在做什么,直到我没有关于类型转换的错误。

任何人都有一个遵循规则的拇指或一些提示或技巧来做到这一点?
例如我有一个虚拟指针,我把它传递给一个函数,如何再次将它变成数组? / p>

main () {
   int data1, data2;
   char data3, data4;
   void *function_data[] = {data1, data2, data3, data4};
   some_function (function_data);
   return;
}


some_function (void *data) {
   void *function_d[4];
   function_d = (void *[]) data; //It not work, how to cast data?
}
编辑:我写错了,我认为这不重要,因此,我更改了代码的变量数据*以便更好地找不到。

4 个答案:

答案 0 :(得分:2)

您的问题是void *function_d[4];创建了新数组。您无法为其分配其他阵列。 function_d应为void**类型。

答案 1 :(得分:1)

基本思想是使用没有变量名的预期类型的​​类型定义,并将其放在括号中作为该类型的强制转换。例如:

int c;
c = (int) 4;

char * (*functionptr)(float, double);
functionptr = (char * (*)(float, double))myfunction;

当然总是假设类型转换是可能的并且有意义。请注意:C不会阻止大多数荒谬的演员,所以你必须自己照顾。

在您的情况下,function_data被定义为指向void的指针数组。因此,每个数据都必须是void **类型,正如Keith已经指出的那样。 通过以some_function作为参数调用function_data,您将指向function_data[0]的指针传递给函数。 为了让你的函数再次使用它作为一个4个指向void的数组,你需要像你一样使用一个强制转换(void * [])。但是,数组function_d是一个保留四个指针空间的数组,并且您无法更改function_d指针(它的类型为void * * const!)。要做你想要的事情,你需要一个非常量指针,比如

void * * function_d = (void*[])data;

然后您可以像function_data一样使用它,使用类似数组的订阅。 function_d[2]将为您提供等于*data3的值。

答案 2 :(得分:0)

您无法分配数组对象。

data1data2data3data4如何宣布?

void*是(或可以用作)通用指针类型。这可以为您提供极大的灵活性,但它也可以禁止类型检查。

function_data是一个由4个指向void的数组。在调用some_function (function_data)中,它隐式转换为void**,指向第一个元素的指针。

some_function期望void*,而不是void** - 但任何指针类型(函数指针除外)都可以隐式转换为void*,因此编译器并没有抱怨这个电话。

这是你的程序的一个版本,至少是类型正确的(我认为)。

#include <stddef.h>

void some_function(void **data, size_t count);

int main(void) {
    void **data1, **data2, **data3, **data4;
    void *function_data[] = { *data1, *data2, *data3, *data4 };
    some_function (function_data,
                   sizeof function_data / sizeof function_data[0]);
    return 0;
}

void some_function(void **data, size_t count) {
    size_t i;
    for (i = 0; i < count; i ++) {
        /*
         * do something with data[i], which is of type void*
         */
    }
}

请注意,data1和朋友未初始化,因此该程序的行为未定义。我怀疑你打算写一些类似的东西:

void *function_data[] = { &data1, &data2, &data3, &data4 };

但是很难说出你想要做什么。

如果您确实需要该函数来获得数组的副本,则可以使用memcpy()(您无法分配数组值)。但是,对于大多数用途,使用指针访问原始数组更有意义。如果要在不影响原件的情况下修改副本,则需要制作副本。

我已经更正了mainsome_function的声明,并在some_function添加了声明,以便在您调用它时可见。

您应该始终显式声明所有函数的返回类型。在1990版本的C中,您可以省略它,它将默认为int(但最好明确地将其声明为int)。在1999版的C中,类型是必需的,如果没有可见的声明,就不能调用函数。

同样,从您向我们展示的代码中很难说出您正在尝试做什么,这使得很难猜测如何做到这一点。

答案 3 :(得分:0)

几个问题:

这不起作用:

int data1, data2;
char data3, data4;
void *function_data[] = {data1, data2, data3, data4};

因为intcharvoid *不兼容。您可以按如下方式解决此问题:

void *function_data[] = {&data1, &data2, &data3, &data4};

因为int *char * void *兼容。

function_data传递给some_function时,数组表达式将转换为指针值,因此some_function收到的是void **。您可以在指针上使用下标运算符,就像它是一个数组一样:

some_function(function_data);
...
void some_function(void **data)
{
  int *x = data[0];  // remember, we stored the *addresses*
  int *y = data[1];  // of data1, data2, data3, and data4;
  char *a = data[2]; // since the type of data is void **,
  char *b = data[3]; // the type of data[i] is void *.
  ...
}

IOW,你不需要data强制转换为数组类型,以便像数组一样使用它。