如果您的功能具有以下功能:
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);
答案 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)
你必须是以java开头,然后尝试进入c的人的另一个受害者,这就是我将回答的原因。
我想在该参数内初始化我的数组。怎么办?
你不能。 在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结尾。