总结void *值的数组

时间:2018-03-16 09:53:51

标签: c macros

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

#define LEN 5

#define sum_mac(func,type)\
    void* func (void* arr, int size)\
    {\
    int i;\
    type *sum = (type*)malloc(sizeof(type));\
    if(sum == NULL)\
    {\
        printf("Error\n");\
        exit(1);\
    }\
    *sum = 0;\
    for(i = 0; i<size ; i++)\
    {\
        *sum = *sum + *((type*)arr[i]);\
    }\
    return sum;\
    }\
sum_mac(int_sum,int);
void *summary(void* arr, int size, void *(*func)(void*, int))
{
    if (func == NULL)
        return NULL;
    return (*func)(arr, size);
}

int main()
{
    int arr[] = { 1,2,3,4,5 };
    int *sum = summary(arr, LEN, int_sum(arr, LEN));
    printf("the sum is: %d ", *sum);
    free(sum);
    return 0;
}

当我尝试编译此代码时出现以下错误:

  

错误LNK2019未解析函数_main

中引用的外部符号_int_sum

当我搜索这个问题的可能原因时,我得到了&#34;对链接器无法解析的函数或变量的引用,或找到&#34; 的定义

有人可以帮我找到问题。

4 个答案:

答案 0 :(得分:2)

存在(至少)三个问题:

您在宏本身中包含了宏实例,更改:

}\
sum_mac(int_sum,int);

为:

}
sum_mac(int_sum,int);

因此sum_mac不是宏的一部分。

在宏定义中,更改:

*sum = *sum + *((type*)arr[i]);

为:

*sum = *sum + ((type*)arr)[i];

在第一种情况下,您尝试对void指针类型使用索引,这是不可能的(void没有大小)。因此,将arr转换为正确类型的指针,并对其使用算术。

-------------- EDIT -----------

变化:

int *sum = summary(arr, LEN, int_sum(arr, LEN));

int *sum = summary(arr, LEN, int_sum);

在第一种情况下,你调用summary,第三个参数值是调用int_sum的结果,如果不是函数指针,那么结果是指向int的指针。您需要传递函数指针。

您的大多数问题都是由于宏的使用造成的。这绕过了类型系统并欺骗了编译器,这绝不是一个好主意。

答案 1 :(得分:1)

问题出在这里:

    return sum;\
    }\ <---------- Remove the \
sum_mac(int_sum,int);  <---- also remove the ; because this is not a statement
void *summary(void* arr, int size, void *(*func)(void*, int))

编译器认为sum_mac(int_sum,int);是宏定义的一部分,因为行尾的\连接行。这就是永远不会调用sum_mac(int_sum,int);的原因。

然而,这揭示了运营商在线优先的另一个问题:

*sum = *sum + *((type*)arr[i]);\

数组访问[i]的优先级高于强制转换(type*),因此您尝试访问无效的void数组。最后一个引用也是毫无意义的。行应更改为:

*sum = *sum + ((type*)arr)[i];\

还有第三个问题:你过早地打电话给int_sum。函数需要函数指针,因此您只应传递指针:

int *sum = summary(arr, LEN, int_sum); // Only pass int_sum

您应确保已在编译器上启用所有警告,因为这是编译器可能会发出警告的错误。

答案 2 :(得分:0)

另一个问题在于:

int *sum = summary(arr, LEN, int_sum(arr, LEN));

summary的第三个参数应该是函数指针,但int_sum(arr, LEN)不是函数指针,而是int_sum函数的结果。

你需要写下这个:

int *sum = summary(arr, LEN, int_sum);

答案 3 :(得分:0)

您没有声明您在任何地方调用的函数,因此链接器不知道该怎么做。

话虽如此,将整个函数放在宏中并不是一个好主意,也不是malloc单个项目。并且代码*sum = *sum + *((type*)arr[i]);超出范围,因为你没有分配数组,而是像使用它一样使用它。

我会从头开始重写。这就是你可以做的事情:

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

int int_sum (size_t size, int arr[size])
{
  int sum = 0;
  for(size_t i=0; i<size; i++)
  {
    sum += arr[i];
  }
  return sum;
}

float float_sum (size_t size, float arr[size])
{
  float sum = 0.0f;
  for(size_t i=0; i<size; i++)
  {
    sum += arr[i];
  }
  return sum;
}

#define sum_array(arr) _Generic((arr[0]), \
                         int:   int_sum,  \
                         float: float_sum) (sizeof(arr)/sizeof(arr[0]), arr)

int main (void)
{
    int arr[] = { 1,2,3,4,5 };
    int sum = sum_array(arr);
    printf("int, the sum is: %d\n", sum);

    float farr[] = {1.0f, 2.0f, 3.0f}; 
    printf("float, the sum is: %f\n", sum_array(farr));

    return 0;
}

即使不涉及函数指针,也可以使其更通用:

#define do_stuff(arr, stuff) _Generic((arr[0]), \
                         int:   int_##sum,  \
                         float: float_##sum) (sizeof(arr)/sizeof(arr[0]), arr)

int main (void)
{
    int arr[] = { 1,2,3,4,5 };
    int sum = do_stuff(arr, sum);
    printf("int, the sum is: %d\n", sum);

    float farr[] = {1.0f, 2.0f, 3.0f}; 
    printf("float, the sum is: %f\n", do_stuff(farr, sum));

    return 0;
}