在函数调用的参数内定义新函数,数组,结构等

时间:2016-08-27 03:15:35

标签: c arrays function pointers compound-literals

如果您的功能具有以下功能:

void foo(char **arr);

如何执行以下操作:

void foo(char* x[] = { "hello", "my", "friend" });

如果这让您感到困惑,那么在Java中我们可以通过以下方式解决这个问题:

public void foo(String[] x);

foo(new String[] { "hello", "my", "friend" });

目前,我在C中做了以下我讨厌,因为它看起来很丑:

char* myArr[] = 
    { 
        "hello", "my", "friend"
    };

foo(myArr);

3 个答案:

答案 0 :(得分:5)

Java和C是具有不同习语的不同语言。

如果是我,我不会试图[太难]强迫C变成“类似Java”。根据自己的优点接受每种语言。

对于你的第一个例子,“丑陋”的例子,你可以使用CPP [C预处理器] - 这个概念在Java中存在 not :< / p>

#define FOO(_av...) \
    do { \
        char *myArr[] = { _av, NULL }; \
        foo(myArr); \
    } while (0)

FOO("hello", "my", "friend");

但是,这可能被许多人视为“太可爱”了。最好创建某种表格。

每当Java执行new时,它就会进行堆分配[这很慢]。这部分是因为所有必须“在堆上”,或多或少。

C可以使用malloc执行此操作,但是一个优秀的C程序员将尝试避免不必要的堆分配,因为它具有全局变量,静态变量和函数范围变量。

答案 1 :(得分:5)

  

如何执行以下操作:

void foo(char* x[] = { "hello", "my", "friend" });

你几乎成功了......; - )

如果使用C99或更新版本,请使用这样的复合文字:

foo((char *[]){"hello", "my", "friend"});

请注意,被调用函数(此处为foo())不知道指针数组有多少元素,因此您希望将最终空指针添加为sentinel:

foo((char *[]){"hello", "my", "friend", NULL});

示例:

#include <stdio.h>
#include <stdlib.h> /* for EXIT_xxx macros */


void foo(char **arr)
{
  while (arr && *arr)
  {
    printf("%s\n", *arr);
    ++arr;
  }
}

int main(void)
{
  foo((char *[]){"hello", "my", "friend", NULL}); /* Mind the final NULL. */

  return EXIT_SUCCESS;
}

这将打印:

hello
my
friend

复合文字是有效的,直到它定义的范围被保留(main()这里)。如果你想确保它在使用后立即从堆栈中删除,请在foo()的调用周围创建一个本地范围/块:

int main(void)
{
  {
    foo((char *[]){"hello", "my", "friend", NULL}); /* Mind the final NULL. */
  }

  /* The compound literal passed to foo() is already deallocated here, had been 
     removed from the stack. */

  ...

答案 2 :(得分:3)

你必须是以开头,然后尝试进入的人的另一个受害者,这就是我将回答的原因。

  

我想在该参数内初始化我的数组。怎么办?

你不能。 在C99之前

一般来说,这是你可以做的事情:

#include <stdio.h>

void foo(char** arr, int size)
{
    int i;
    for(i = 0; i < size; ++i)
        printf("%s\n", arr[i]);
}

void bar(char** arr)
{
    while(*arr)
        printf("%s\n", *arr++);
}

int main(void)
{
    char* x[] = { "hello", "my", "friend" };
    foo(x, 3);

    char* null_terminated[] = { "ShadowRanger", "Correct", NULL };
    bar(null_terminated);

    return 0;
}

其中foo()显式使用数组的大小,而bar()要求数组以NULL结尾。