正在将字符[][]转换为字符**?

Converting char[][] to a char**?

本文关键字:字符 转换      更新时间:2023-10-16

我正在根除std::string,转而使用C字符串,这是我的新手。 如何编译以下内容?g++抱怨:cannot convert char(*)[16] to char**

#include <iostream>
void print(char** s, int n)
{
for (int i = 0; i < n; ++i)
{
std::cout << s[i] << 'n';
}   
}
int main()
{
constexpr int n = 3;
char s[n][16]{ "Hello", "Bye", "Sky"};
print(s, n); 
}

您创建了一个多维数组,而不是一个指针数组。通常数组可以说等效于指针,但是在这种情况下,c ++需要知道数组第二维的大小。函数如下

void print(char s[][16], int n)`{
for (int i = 0; i < n; ++i)
{
std::cout << s[i] << std::endl;
}
}

可以理解的是,您可能希望使用指针传递函数,以免创建 2-D 数组的完整副本。我看到你提到你可以使用可变长度的字符串。字符串库中支持该功能。您正在处理 c 字符串,它根本不是字符串,而是字符类型的静态数组。使用动态内存定义这些 c 字符串恰好为您提供所需的行为,因为您用最简单的术语创建指针数组。

void print(char** s, int n)
{
for (int i = 0; i < n; ++i)
{
std::cout << s[i] << std::endl;
}
}
int main()
{
int n = 3, i;
char** s = new char*[n];
for (i = 0; i < 3; i++) {
s[i] = new char[16];
}
s[0] = "Hello";
s[1] = "Bye";
s[2] = "Sky";
print(s, n);
for (i = 0; i < 3; i++) {
delete [] s[i];
}
delete [] s;
s = NULL;
return 0;
}

由于您现在正在使用动态内存,因此您需要释放内存,这就是最后一个循环的作用。如您所见,使用所有这些动态内存非常费力,使用经过优化的字符串库可以更轻松地完成更好的工作。如果您仍然不相信至少应该创建自己的字符串类来处理包含 char * 作为其私有成员的动态内存。无论哪种情况,您都可以避免这种混乱,而只是制作一个zed类对象的数组,而根本不处理多维废话。没有人喜欢赛格错误和内存泄漏。

给定任何类型TT arr[N];声明一个类型为T[N]的变量arr,它是一个数组而不是一个指针。当您在几乎所有上下文中使用arr时,会发生数组到指针的转换,从而产生不正确的错觉,即arrT*类型的指针。

char s[n][16] = { "Hello", "Bye", "Sky" };

s声明为char[16]类型的n元素数组。现在,当数组到指针的转换发生时,s会衰减为类型char (*)[16]的指针。因此,您的函数需要具有签名

void print(char (*s)[16], int n);

这相当于

void print(char s[][16], int n);

编译器将[]解释为指针。

为了使这些复杂类型更具可读性,可以使用类型别名。

using T = char[16];
void print(T s[], int n);

解决一些问题

正如评论中所指出的,std::string几乎总是应该优先于char数组。如果您有性能问题,请在执行此操作之前进行基准测试。我真的怀疑在大多数情况下可以观察到多少性能提升。

声明长度n数组是int不是标准C++。它是编译器提供的扩展,它不可移植,在大多数情况下不是必需的。

int n = 3;
char vla[n];  // this is a variable length array
char arr[3];  // this is just an array
char* darr = new char[3];  // this is a pointer pointing to dynamically allocated memory
std::string str;  // but instead, this is just better

编译器无法从 char ** 中提取有关 char[16] 的信息。您需要定义一个类型 char[16],并将指向此类型的指针传递给您的打印函数。

#include <iostream>
typedef char str_t[16];
void print(str_t* s, int n)
{
for (int i = 0; i < n; ++i)
{
std::cout << s[i] << std::endl;
}
}
int main()
{
int n = 3;
char s[n][16]{ "Hello", "Bye", "Sky"};
print(s, 3);
}