C语言中的Foreach函数

时间:2019-04-01 15:53:19

标签: c function foreach

我想创建一个带有数组的函数和一个函数,并在数组中的每个元素上调用该函数

我一直在寻找解决方案,但是它们似乎都使用宏,而如果可能的话,我更喜欢使用函数。

我正在寻找可以起到以下作用的东西

void print_string()
{
    printf("%d\n", num);
}

int array[] = { 1, 2, 3, 4, NULL }; // So the foreach function knows when it has reached the end

for_each_function(array, print_number);

输出:

1
2
3
4

编辑:它必须是通用的,因此可能需要一个宏

6 个答案:

答案 0 :(得分:4)

您可能应该使用函数指针。使用函数指针的一种完整实现就是这样。

#include <stdio.h>

void for_each(int * arr, int size, void (*fun)(int))
{
  for (int i = 0; i < size; i++)
  {
    (*fun)(arr[i]);
  }
}

void print_num(int num)
{
  printf("%d\n", num);
}

int main()
{
  int array [] = {1, 2, 3, 4};
  for_each(array, 4, print_num);
  return 0;
}

答案 1 :(得分:3)

使用function pointer,如下所示:

#include <stdio.h>

void for_each_function(int* arr, size_t size, void(*fun)(int)) {
  for(size_t i = 0; i < size; ++i)
    (*fun)(arr[i]);
}
void print_number(int);

int main(void) {
  int array[] = { 1, 2, 3, 4 };
  for_each_function(array, 4, &print_number);
  return 0;
}

void print_number(int num)
{
    printf("%d\n", num);
}

输出:

1
2
3
4

备注:

  • for_each_function的第三个参数,即void(*fun)(int), 是名为fun的函数指针,具有返回类型void和一个 类型int的参数。
  • 在每个主体的内部,您像这样调用函数指针 (*fun)(arr[i]);,它取消引用了函数指针fun,并且 将传递arr[i]作为其参数。您也可以使用fun(arr[i])
  • 在调用main函数中的每个函数时,您需要 使用您想要指向的函数的地址,像这样 for_each_function(array, 4, &print_number);。您也可以使用for_each_function(array, 4, print_number);

PS:在您的示例数组中,我认为您不想使用NULL作为最后一个元素(除非定义了warning: initialization of 'int' from 'void *' makes integer from pointer without a cast [-Wint-conversion],否则您可能会收到类似NULL的警告为0,如@EricPostpischil所述),因此在我的示例中将其删除。

答案 2 :(得分:3)

davidlowryduda / gsamaras 答案的修改,以与任何类型的数组兼容,而不仅仅是 int ,但是这会影响调用指针的调用函数比一个值:

#include <stdio.h>

void for_each(void * arr, size_t nElts, size_t sizeElt, void (*fun)(void *))
{
  char * p = arr;

  for (size_t i = 0; i < nElts; i++)
  {
    (*fun)(p);
    p += sizeElt;
  }
}

/* for_each can be called directly or via the following macro,
   the array can be an expression without any problem : is it given
   in argument and the other uses are only for sizeof */

#define FOR_EACH(a, f) for_each(a, sizeof(a)/sizeof(*a), sizeof(*a), f)

void print_int(void * p)
{
  printf("%d\n", *((int *) p));
}

void print_short(void * p)
{
  printf("%d\n", *((short *) p));
}

int main()
{
  int iarray [] = {1, 2, 3, 4};
  FOR_EACH(iarray, print_int); /* for_each(iarray, sizeof(iarray)/sizeof(*iarray), sizeof(*iarray), print_int); */

  short sarray [] = {5, 6, 7, 8};
  FOR_EACH(sarray, print_short); /* for_each(sarray, sizeof(sarray)/sizeof(*sarray), sizeof(*sarray), print_short); */

  return 0;
}

编译和执行:

pi@raspberrypi:~ $ gcc -pedantic -Wall -Wextra i.c
pi@raspberrypi:~ $ ./a.out
1
2
3
4
5
6
7
8

答案 3 :(得分:1)

您可以为此定义一个宏。

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

#define FOR_EACH(type, target, size, body) \
                                           \
    for (size_t i = 0; i < size; i++)      \
    {                                      \
        type value = target[i];            \
        body;                              \
    }

int main(int argc, char const *argv[])
{
    int arr[4] = {0, 1, 2, 3};

    char *name = "My Name";

    FOR_EACH(int, arr, 4, {
        printf("%d\n", value);
    })

    size_t len = strlen(name);

    FOR_EACH(char, name, len, {
        printf("%c-", value);
    })

    return 0;
}

在这种情况下,您甚至不需要函数,并且只要知道函数的长度,就可以使用它来迭代任何类型的任何数组。

答案 4 :(得分:0)

您可以使用函数指针执行类似的操作。但是使用会更加强大,它将使您的foreach具有通用性。

#include <stdio.h>
typedef struct int_array{
    int *data;
    int len; 
}Int_array;

void print_number(int num)
{
    printf("%d\n", num);
}

void for_each_function(Int_array a, void (*f)(int)){
    for(int i =0; i < a.len;i++){
            (*f)(a.data[i]);
    }
}

int main(){

    int data[4] = { 1, 2, 3, 4 };
    Int_array x;
    x.len = 4;
    x.data = data;
    for_each_function(x, print_number);   
}

答案 5 :(得分:0)

我在论坛上带了一个解决方案的朋友,所以我增加了。 我想到foreach不必具有值即可停止循环。

#include <iostream>
#include <stdio.h>

void for_each(int * arr, void (*fun)(int)){

   for (int i = 0; i < arr[i]; i++){
    (*fun)(arr[i]);
   }
}

void print_num(int num){
   printf("%d\n", num);
}

int main(){
int array [] = {1, 2, 3, 4, 5, 6};
for_each(array, print_num);
}