Hat*_*end 3 c arrays pointers function compound-literals
如果你有一个功能,采取以下措施:
void foo(char **arr);
Run Code Online (Sandbox Code Playgroud)
你怎么能做到以下几点:
void foo(char* x[] = { "hello", "my", "friend" });
Run Code Online (Sandbox Code Playgroud)
如果这让您感到困惑,那么在Java中我们通过以下方式实现此目的:
public void foo(String[] x);
foo(new String[] { "hello", "my", "friend" });
Run Code Online (Sandbox Code Playgroud)
目前,我在C中做了以下我讨厌,因为它看起来很丑:
char* myArr[] =
{
"hello", "my", "friend"
};
foo(myArr);
Run Code Online (Sandbox Code Playgroud)
Java和C是具有不同习语的不同语言.
如果是我,我就不要试图[太难]将C强迫变成"像Java一样".根据自己的优点接受每种语言.
对于您的第一个例子,"丑陋"的例子,您可以使用CPP [C预处理器] 宏 - Java 中不存在的概念:
#define FOO(_av...) \
do { \
char *myArr[] = { _av, NULL }; \
foo(myArr); \
} while (0)
FOO("hello", "my", "friend");
Run Code Online (Sandbox Code Playgroud)
但是,这可能会被许多人视为"太可爱".最好创建某种表格.
只要Java做了,new它就会进行堆分配[这很慢].这部分是因为一切都必须"在堆上",或多或少.
C可以做到这一点malloc,但是一个好的C程序员会尽量避免不必要的堆分配,因为它有全局变量,静态变量和函数范围变量.
你怎么能做到以下几点:
Run Code Online (Sandbox Code Playgroud)void foo(char* x[] = { "hello", "my", "friend" });
你几乎成功了...... ;-)
如果做C99或更新版本使用这样的复合文字:
foo((char *[]){"hello", "my", "friend"});
Run Code Online (Sandbox Code Playgroud)
请注意,被调用的函数(foo()这里)不知道指针数组有多少元素,因此您希望将最终的空指针添加为sentinel:
foo((char *[]){"hello", "my", "friend", NULL});
Run Code Online (Sandbox Code Playgroud)
例:
#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;
}
Run Code Online (Sandbox Code Playgroud)
这将打印:
hello
my
friend
Run Code Online (Sandbox Code Playgroud)
复合文字有效,直到它定义的范围留在(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. */
...
Run Code Online (Sandbox Code Playgroud)