3

如果你有一个函数,它采用以下内容:

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);
4

3 回答 3

5

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

如果是我,我会避免 [太努力] 将 C 强制转换为“类 Java”。拥抱每种语言的优点。

对于您的第一个示例,“丑陋”的示例,您可以使用 CPP [C 预处理器]宏——Java 中存在的概念:

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

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

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

每当 Java 执行 anew时,它都会进行堆分配 [这很慢]。这部分是因为一切都必须或多或少地“在堆上”。

C 可以用malloc.

于 2016-08-27T03:34:06.500 回答
5

您如何执行以下操作:

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

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

如果使用 C99 或更高版本,请使用如下复合文字:

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

请注意,被调用函数(foo()此处)不知道指针数组有多少元素,因此您想添加一个最终的空指针作为标记:

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. */

  ...
于 2016-08-27T14:30:21.760 回答
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;
}

wherefoo()明确使用数组的大小,而bar()要求数组以 NULL 结尾。

于 2016-08-27T03:21:43.717 回答