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

如果你有一个function,采取以下措施:

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

你怎么能做到以下几点:

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

你几乎成功了…… 😉

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

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

请注意,被调用的函数(这里的foo() )不知道指针数组有多少元素,所以你想要将最终的空指针添加为sentinel:

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

例:

 #include  #include  /* 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() here)。 如果你想确保它在使用后立即从堆栈中删除,请在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. */ ... 

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

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

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

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

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

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

C可以用malloc做到这一点,但是一个好的C程序员会尝试避免不必要的堆分配,因为它有全局变量,静态变量和函数范围变量。

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

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

你不能。 在C99之前


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

 #include  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结尾。