C++通过引用传递字符串与通过引用传递字符数组
C++ pass string by reference vs pass char array by reference
好的,所以我是C++新手,我只是想问为什么你不应该用"&"符号引用传递字符数组,而应该用字符串传递,因为这两个参数都是指针。我编写的示例代码:
void changeChar(char* buffer, int bSize) {
strcpy_s(buffer, bSize, "test123");
}
void changeString(string* buffer) {
*buffer = "test321";
}
char mychar[10] = "hello world";
string mystr;
changeChar(mychar, sizeof(mychar));
changeString(&mystr);
changeChar()
将char*
指针指向位于内存中某处的char
(该函数假定char*
实际上指向指定大小的char[]
数组的第一个char
)。
任何固定长度的数组在仅用其名称引用时都会衰减为指向其第一个元素的指针。因此,当mychar[]
数组需要char*
指针时,没有必要(也不能)使用operator&
将数组传递给changeChar()
函数。
如果你不想通过指针传递mychar
,你必须通过引用传递它(否则,按值传递它将创建数组的副本,然后函数将无法修改原始数组)。 在这种情况下,您必须将数组的大小作为用于引用的数据类型的一部分,例如:
void changeChar(char (&buffer)[12]) {
strcpy_s(buffer, 12, "test123");
}
char mychar[] = "hello world";
changeChar(mychar);
但是,仅当传递给函数的所有数组具有相同的大小时,这才有效。如果需要传递不同大小的数组,请将函数设置为模板,以便编译器可以推断传入数组的大小,例如:
template<size_t size>
void changeChar(char (&buffer)[size]) {
strcpy_s(buffer, size, "test123");
}
char mychar[] = "hello world";
changeChar(mychar);
changeString()
将一个string*
指针指向位于内存中某处的string
对象。
如果不使用operator&
(或类覆盖operator&
时std::addressof()
)来获取对象的地址,则无法通过指针传递对象(除非它与new
一起分配,在您的示例中并非如此)。
如果不想通过指针传递string
对象,则必须通过引用传递它(否则,按值传递对象将创建对象的副本,并且函数将无法修改原始对象):
void changeString(string &buffer) {
buffer = "test321";
}
string mystr;
changeString(mystr);
你需要知道,std::string
不是内置类型。它是一个实现各种自定义行为的类,例如在对象复制上创建硬拷贝。
"some text" // this is a string literal, meaning the type is const char[num]
当您输入字符串文本时,它很可能位于名为".rodata"(只读数据)的代码部分内。您不能合法地修改此字符的值。文本还有一个"空终止符" - 末尾值为零的字符。它很有用,因为您需要知道文字何时结束。num
总是number of characters
+1
,因为 null 终止符。
当你写这个的时候:
const char* text = "hello world!";
// note that this is illegal:
// char* text = "hello world!"; // literal is read-only.
你只是说:
让我们
text
指向内存,文本所在的位置。
复制文本实际上需要从中做更多的工作。必须明确地完成:
char* notReadOnly = new char[30]; // you can allocate some more
// program will still interpret character of value 0 as the end, even if buffer is bigger
std::strcpy(notReadOnly, "hello world");
// use string literal as src in std::strcpy
请注意,您还需要手动删除它:
delete[] notReadOnly;
std::string
使它变得容易得多。当你像这样写 sth 时,它会自动复制文本:
std::string text = "some string literal";
std::string
的复制构造函数也制作缓冲区的硬拷贝。即使std::string
类看起来像这样:
class string
{
char *buffer;
std::size_t numberOfCharacters;
};
每次复制时,它都会执行buffer
的硬拷贝,如下所示:
class string
{
// rest
string(const string &other)
{
numberOfCharacters = other.numberOfCharacters;
buffer = new char[numberOfCharacters];
// copy everything
std::strncpy(buffer, other.buffer, numberOfCharacters);
}
};
请注意,这只是一个简化的示例。
std::string a = "some text";
std::string b = a; // copy constructor is called. It uses method implemented above
const char* x = "some text2";
const char* y = x; // copy constructor is called. Only the address is copied, there is no hard copy of the actual buffer.
当您将变量作为参数传递给函数时,也会调用复制构造函数。但是,在某些常见情况下,编译器可以对其进行优化。
- 关于引用数组位置的问题
- 使用指针交换而不引用数组C++
- 对于Boost.Propertytree,有没有办法使用JSON点表示法来引用数组元素?
- 如何在递归函数中调用引用数组?
- 动态指针引用数组由三元运算符返回值,但有异常
- 为什么没有 std::string 构造函数来引用数组
- 指针/引用数组
- 错误 C2234:引用数组是非法的
- 引用数组的方法
- 通过引用数组值进行交换
- 引用数组涉及的技术问题
- 引用数组的函数调用
- 从其他类中的类引用数组
- 如何使用变量名称引用数组位置
- 在 OpenGL 中呈现三角形结构引用数组
- 如何取消引用数组元素(C++)
- c++引用数组数组(指针到指针?)
- 指向指针的指针如何能够引用数组
- C++取消引用数组
- c++中引用数组中对象的共享指针