我根除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);
}
答案 0 :(得分:2)
您创建了一个多维数组,而不是指针数组。通常一个数组可以说相当于一个指针,但在这种情况下,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类对象数组,而不是处理多维无意义。没有人喜欢seg故障和内存泄漏。
答案 1 :(得分:1)
鉴于任何类型T
,T arr[N];
声明类型为arr
的变量T[N]
,其为数组而非指针。在几乎所有情境中使用arr
时,array to pointer conversions都会发生错误,错误地认为arr
是T*
类型的指针。
char s[n][16] = { "Hello", "Bye", "Sky" };
将s
声明为类型为n
的{{1}}元素数组。现在,当数组到指针转换发生时,char[16]
会衰减为类型为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
的数组不是标准C ++ 。它是您的编译器提供的扩展,不可移植,在大多数情况下不是必需的。
int
答案 2 :(得分:0)
编译器无法从char **中提取有关char [16]的信息。您需要定义一个char [16]类型,并将指向此类型的指针传递给您的打印函数。
import UIKit
class MenuBar: UIView{
let buttonWidth = 50
let friendsButton: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.image = #imageLiteral(resourceName: "Friends Button")
imageView.contentMode = .scaleAspectFill
imageView.widthAnchor.constraint(equalToConstant: 50)
imageView.heightAnchor.constraint(equalToConstant: 50)
return imageView
}()