用C打印数组的通用函数

时间:2014-11-20 03:10:53

标签: c arrays generics printing dynamic-arrays

我试图编写一个通用函数来打印数组的元素。这就是我所拥有的:

void printArray(void * source, int numElements, int size, void (*printFunction)(void *)){

     void *dest[numElements];
     memcpy(dest, &source, (size * nElem));
     int i;
     for (i = 0; i < numElements; i++){
         printFunction(dest[i]);
     }
 }

我传递了一个数组的地址,数组中元素的数量,数组中每个元素的大小,以及一个回调函数来处理它所用的任何类型的数组的打印/格式化(打印功能)工作正常,我已经测试过了。)

现在它打印出第一个元素,然后我发现了分段错误。我无法弄清问题是什么 - 任何帮助都会非常感激。我是stackoverflow的新手,所以让我知道我是否可以改进我的问题。

5 个答案:

答案 0 :(得分:1)

你为什么要复制?

你真正想要的是传递一个char指针,这样你就可以增加它 size0numElements次,每次都将其传递给printFunction。

请注意,您实际上编写的函数比只打印数组的函数更通用。你有效地写了一张地图&#39;将函数映射到数组的函数。

这样的事情应该有用(注意它未经测试):

void printArray(void * source, int numElements, int size, void (*printFunction)(void *)){
    int i;
    for (i = 0; i < numElements; i++){
        printFunction(((char *)source) + i * size);
     }
}

答案 1 :(得分:1)

我假设source是数组开头的void *(而不是指针数组)。在那种情况下......

无需复制数组 - 您只需使用source本身即可。并且由于允许在C中修改函数参数并且仅影响函数内的副本,因此在继续执行数组时可以更改sourcenumElements。考虑到这些要点,您可以将功能简化为以下内容:

void printArray(void *source, int numElements, 
                    int size, void (*printFunction)(void *))
{
    for (; numElements; numElements--) {
        printFunction(source);
        source = ((char *)source) + size;
    }
}

上面的版本运行for循环,递减numElements以为每个数组元素提供一次传递。在每次传递结束时,sourcesize偏移,以便在将其传递给回调函数后转到下一个元素。 (char *)强制转换用于允许指针算术,即使sourcevoid *

答案 2 :(得分:0)

您应该使用char数组来对数据进行别名,而不是void*数组。后者是一个指针数组,它不适合缓冲区。

泛型函数看起来应该更像这样:

void printArray(void * source, int numElements, int size, void (*printFunction)(void *)){

     char dest[numElements*size];
     memcpy(dest, source, (size * numElements)); // source is already a pointer, don't address it
     int i;
     for (i = 0; i < numElements; i++){
         printFunction(dest[i*size]); //make sure you index based on the type and not just a single byte
     }
 }

答案 3 :(得分:0)

它甚至更简单,不需要乘法,只需指针算术:

void printArray(void *source, int numElements, int size, void (*printFunc)(void *)){
  while (numElements--) {
    printFunc(source);
    source=(char *)source+size; //C forbids void* math. source+=size fails on MSVC
  }
}

答案 4 :(得分:-1)

void printArray(void * source, int numElements, int size, void (*printFunction)(void *)){
    int i;
    for (i = 0; i < numElements; i++){
        printFunction((source + i * size));
    }
}

在您的程序中,您将源内容保存到void指针数组,以便在打印时获得段错误。相反,您可以直接使用source,以便获取您必须添加大小的每个元素来源。