c中作为参数的未知类型数组

c中作为参数的未知类型数组,c,parameter-passing,void-pointers,C,Parameter Passing,Void Pointers,这只是一个测试,只是为了了解它是如何工作的。但我不明白为什么我会得到这个输出 #include <stdio.h> void f(void *a[]){ for(int t=0; t<5;t++){ printf("--%d--",a[t]); } } void main(void){ int a[5]={1,2,3,4,5}; f(a); } #包括 无效f(无效*a[]{ 对于(int t=0;t您告诉函数需要一个voi

这只是一个测试,只是为了了解它是如何工作的。但我不明白为什么我会得到这个输出

#include <stdio.h>

void f(void *a[]){
    for(int t=0; t<5;t++){
        printf("--%d--",a[t]);
    }
}

void main(void){
    int a[5]={1,2,3,4,5};
    f(a);
}
#包括
无效f(无效*a[]{

对于(int t=0;t您告诉函数需要一个
void*
指针数组。此外,函数返回值不正确,循环增量不正常。请尝试以下操作:

#include <stdio.h>

int f(int a[]){
    int r = 0;
    for(int t = 0; t < 5; t++){
        printf("--%d--", a[t]);
    }
    return r;
}

void main(void){
    int a[5]= { 1, 2, 3, 4, 5};
    f(a);
}

如果您启用了所有编译器警告,这些错误将向您显示。

您告诉函数需要一个
void*
指针数组。此外,函数返回值不正确,循环增量异常。请尝试以下操作:

#include <stdio.h>

int f(int a[]){
    int r = 0;
    for(int t = 0; t < 5; t++){
        printf("--%d--", a[t]);
    }
    return r;
}

void main(void){
    int a[5]= { 1, 2, 3, 4, 5};
    f(a);
}

如果您启用了所有编译器警告,这些错误就会向您显示。

根据您的标题,您需要一个接受数组的函数,该数组的元素类型对函数来说是未知的。没有这样的函数,因为在C中没有数组作为函数参数传递。相反,如果指定函数参数的表达式在数组中,该数组进一步“衰减”为指向数组第一个元素的指针,传递的是指针。实际上,数组在几乎所有上下文中都衰减为指针

不要被愚弄了:C允许您通过在其他位置指定数组的语法指定函数参数类型,但这是一个方便的功能。以这种方式指定的实际参数类型是相应的指针类型。这允许您编写匹配的变量和函数参数声明,如果您希望这样做的话

现在,由于传递的不是未知(函数)类型的数组,而是指向此类数组的第一个元素的指针,因此您的问题归结为“如何指定可以容纳指向任何类型指针的指针类型?”我打赌你已经知道:
void*
是传统的方法,但是
char*
也可以:

void f(void *a) {
    // ...
}
但是,仅此一项就无法完成很多工作
,它确实只接受这样一个指针。为了能够使用指针,它还接受指定每个数组元素大小和元素数量的参数,并且出于特定目的,它还接受指向适合比较这些元素的函数的指针

更新: 按照
qsort()
模型,如果您想要一个打印任何数组元素的函数,可以执行以下操作:

void print_elements(void *first, size_t element_size, size_t element_count,
        void (*print_element)(void *)) {
    char *element = first;  // pointer arithmetic is not allowed on void *

    for (size_t index = 0; index < element_count; index++) {
        print_element(element);
        element += element_size;
    }
}

根据标题,您需要一个函数,该函数接受的数组的元素类型对函数来说是未知的。没有这样的函数,因为在C中没有数组作为函数参数传递。相反,如果指定函数参数的表达式计算为数组,则该数组将进一步“衰减”指向数组的第一个元素的指针,它就是被传递的指针。实际上,数组在几乎所有上下文中都会衰减为指针

不要被愚弄了:C允许您通过在其他位置指定数组的语法指定函数参数类型,但这是一个方便的功能。以这种方式指定的实际参数类型是相应的指针类型。这允许您编写匹配的变量和函数参数声明,如果您希望这样做的话

现在,由于传递的不是未知(函数)类型的数组,而是指向此类数组的第一个元素的指针,因此您的问题归结为“如何指定可以容纳指向任何类型指针的指针类型?”我打赌你已经知道:
void*
是传统的方法,但是
char*
也可以:

void f(void *a) {
    // ...
}
但是,仅此一项就无法完成很多工作,它确实只接受这样一个指针。为了能够使用指针,它还接受指定每个数组元素大小和元素数量的参数,并且出于特定目的,它还接受指向适合比较这些元素的函数的指针

更新: 按照
qsort()
模型,如果您想要一个打印任何数组元素的函数,可以执行以下操作:

void print_elements(void *first, size_t element_size, size_t element_count,
        void (*print_element)(void *)) {
    char *element = first;  // pointer arithmetic is not allowed on void *

    for (size_t index = 0; index < element_count; index++) {
        print_element(element);
        element += element_size;
    }
}

在函数中,您必须将向量转换回整数,这样编译器就可以知道数组元素的宽度,并且当您想要访问数组元素时,它可以添加适当的偏移量

因此正确的代码是:

void f(void *a[]){
    int *v=(int *) a;
    for(int t=0; t<5;t++){
        printf("--%d--",v[t]);
    }
}
void f(void*a[]{
int*v=(int*)a;

对于函数中的(int t=0;t,您必须将向量转换回整数,以便编译器可以知道数组元素的宽度,并且当您想要访问数组元素时,它可以添加适当的偏移量

因此正确的代码是:

void f(void *a[]){
    int *v=(int *) a;
    for(int t=0; t<5;t++){
        printf("--%d--",v[t]);
    }
}
void f(void*a[]{
int*v=(int*)a;

对于(int t=0;成立的编译器警告:在运行代码之前修复代码,然后开始思考!
t=t++
正在调用未定义的行为。是的,我只是没有复制粘贴它…现在很好,我在代码上修复了它。启用编译器警告:在运行代码之前修复代码,然后开始思考!
t=t++
正在调用未定义的行为。是的,我只是没有t复制粘贴它…现在很好,我在代码上修复了它。好的,但是我如何制作一个函数,它接受一个未知类型的数组并通过数组打印元素?这就是为什么我使用int-array来测试它是如何工作的,但我无法理解它出了什么问题。或者我如何管理它。如果数组是未知类型的,你如何决定使用哪种格式要使用的参数,编译器如何知道数组元素的大小?您使用的是
%d
,因此您知道类型。@通常使用“functors”来完成,本质上是指向应为特定类型调用的特定行为的函数指针。例如,检查标准C函数
b搜索
的工作方式。或者,使用最新的C标准,您可以使用
\u Generic
关键字执行各种技巧。是否需要一些光盘