我需要一些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?
}
编辑:我写错了,我认为这不重要,因此,我更改了代码的变量数据*以便更好地找不到。
答案 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)
您无法分配数组对象。
data1
,data2
,data3
和data4
如何宣布?
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()
(您无法分配数组值)。但是,对于大多数用途,使用指针访问原始数组更有意义。如果要在不影响原件的情况下修改副本,则需要制作副本。
我已经更正了main
和some_function
的声明,并在some_function
添加了声明,以便在您调用它时可见。
您应该始终显式声明所有函数的返回类型。在1990版本的C中,您可以省略它,它将默认为int
(但最好明确地将其声明为int
)。在1999版的C中,类型是必需的,如果没有可见的声明,就不能调用函数。
同样,从您向我们展示的代码中很难说出您正在尝试做什么,这使得很难猜测如何做到这一点。
答案 3 :(得分:0)
几个问题:
这不起作用:
int data1, data2;
char data3, data4;
void *function_data[] = {data1, data2, data3, data4};
因为int
和char
与void *
不兼容。您可以按如下方式解决此问题:
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
强制转换为数组类型,以便像数组一样使用它。