使用字符串文字传递 2d char 数组而不在 c 中初始化
Passing 2d char array using string literal without initialization in c
使用一维字符数组,您可以像这样将它们作为字符串文字传递
#include <stdio.h>
void go(char *a)
{
printf("%s", a);
}
int main()
{
go("Hello");
return 0;
}
但是我们可以用二维字符数组来实现吗?可能是这样的
void go (int rowSize, int colSize, char a[rowSize][colSize])
{
for (int i = 0; i < rowSize; ++i) {
printf("%s\n"), a[i]);
}
}
go(2, 16, {"Hello", "Hi"});
您需要使用复合文字:
void go (size_t rowSize, size_t colSize, char a[rowSize][colSize])
{
for (size_t i = 0; i < rowSize; ++i)
{
printf("%s\n", a[i]);
}
}
int main(void)
{
go(2, 16, (char[][16]){"Hello", "Hi"});
return 0;
}
正如@Lundin 所建议的,您还可以使用指针数组:
void go (size_t nstrings, char **strings)
{
for (size_t i = 0; i < nstrings; ++i) {
printf("%s\n", strings[i]);
}
}
int main()
{
go(2, (char *[]){"Hello", "Hi"});
return 0;
}
或更多const
正确版本:
void go (int nstrings, char *const *strings)
{
for (int i = 0; i < nstrings; ++i) {
printf("%s\n", strings[i]);
}
}
int main()
{
go(2, (char *const[]){"Hello", "Hi"});
return 0;
}
对于大小、索引等,最好使用 size_t
或 ssize_t
。
如果你想要一个指向只读字符串文字的数组,它必须是一个字符指针数组,char* array[] = {"Hello", "Hi"};
。这种类型与二维字符数组完全不同,它们不兼容。
在这种情况下使用哪种形式取决于您想要做什么。这些应该是 read/write 字符串还是只读的?您打算调整单个字符串的大小吗?等等。字符串文字始终是只读的,因此指向它们时要使用的正确指针类型是 const char*
。但是,如果您只是为了初始化 read/write 二维数组而使用字符串文字,那没关系。
假设用例只是在一个函数中打印一堆字符串文字,没有别的,那么最正确的形式是这样的:
#include <stdio.h>
void go(size_t n, const char* a[n]) {
for (size_t i = 0; i < n; ++i) {
puts(a[i]);
}
}
int main() {
go(2, (const char*[]){"Hello", "Hi"});
}
这在功能上几乎与二维数组版本相同,但它可能不使用任何临时内存来存储字符串,因此您可以节省一些 2x16 字节等(这没什么大不了的)。
使用一维字符数组,您可以像这样将它们作为字符串文字传递
#include <stdio.h>
void go(char *a)
{
printf("%s", a);
}
int main()
{
go("Hello");
return 0;
}
但是我们可以用二维字符数组来实现吗?可能是这样的
void go (int rowSize, int colSize, char a[rowSize][colSize])
{
for (int i = 0; i < rowSize; ++i) {
printf("%s\n"), a[i]);
}
}
go(2, 16, {"Hello", "Hi"});
您需要使用复合文字:
void go (size_t rowSize, size_t colSize, char a[rowSize][colSize])
{
for (size_t i = 0; i < rowSize; ++i)
{
printf("%s\n", a[i]);
}
}
int main(void)
{
go(2, 16, (char[][16]){"Hello", "Hi"});
return 0;
}
正如@Lundin 所建议的,您还可以使用指针数组:
void go (size_t nstrings, char **strings)
{
for (size_t i = 0; i < nstrings; ++i) {
printf("%s\n", strings[i]);
}
}
int main()
{
go(2, (char *[]){"Hello", "Hi"});
return 0;
}
或更多const
正确版本:
void go (int nstrings, char *const *strings)
{
for (int i = 0; i < nstrings; ++i) {
printf("%s\n", strings[i]);
}
}
int main()
{
go(2, (char *const[]){"Hello", "Hi"});
return 0;
}
对于大小、索引等,最好使用 size_t
或 ssize_t
。
如果你想要一个指向只读字符串文字的数组,它必须是一个字符指针数组,char* array[] = {"Hello", "Hi"};
。这种类型与二维字符数组完全不同,它们不兼容。
在这种情况下使用哪种形式取决于您想要做什么。这些应该是 read/write 字符串还是只读的?您打算调整单个字符串的大小吗?等等。字符串文字始终是只读的,因此指向它们时要使用的正确指针类型是 const char*
。但是,如果您只是为了初始化 read/write 二维数组而使用字符串文字,那没关系。
假设用例只是在一个函数中打印一堆字符串文字,没有别的,那么最正确的形式是这样的:
#include <stdio.h>
void go(size_t n, const char* a[n]) {
for (size_t i = 0; i < n; ++i) {
puts(a[i]);
}
}
int main() {
go(2, (const char*[]){"Hello", "Hi"});
}
这在功能上几乎与二维数组版本相同,但它可能不使用任何临时内存来存储字符串,因此您可以节省一些 2x16 字节等(这没什么大不了的)。