好的,我是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);
2条答案
按热度按时间jrcvhitl1#
changeChar()
使用一个char*
指针指向位于内存中 * 某处 * 的char
(函数假设char*
实际上指向指定大小的char[]
数组的第一个char
)。任何固定长度的数组衰减成为一个指针,指向它的第一个元素,当它只引用它的名字。因此,当
char*
函数接受char*
指针时,没有必要(也不能)使用operator&
将mychar[]
数组传递给changeChar()
函数。如果不想通过指针传递
mychar
,则必须通过引用传递(否则,通过值传递将复制数组,然后函数将无法修改原始数组)。在这种情况下,必须将数组的大小作为引用所使用的数据类型的一部分,例如:但是,只有当传递给函数的所有数组大小相同时,这才起作用。如果你需要传递不同大小的数组,请将函数改为模板,这样编译器就可以推断传入的数组的大小,例如:
changeString()
接受一个string*
指针,指向位于内存中某个地方的string
对象。如果不使用
operator&
(或者当类重写operator&
时使用std::addressof()
)来获取对象的地址,就不能通过指针传递对象(除非它被分配了new
,而在您的示例中不是这种情况)。如果你不想通过指针传递
string
对象,你必须通过引用传递它(否则,通过值传递对象将复制对象,函数将无法修改原始对象):bnl4lu3b2#
您需要知道,
std::string
不是内置类型。它是一个类,实现了所有类型的自定义行为,例如在对象复制时创建硬拷贝。当您输入字符串文字时,它很可能位于名为“.rodata”(只读数据)的代码部分内。您不能合法地修改此字符的值。文本结尾还有一个“空终止符”字符,值为零。它很有用,因为您需要知道文字何时结束。
num
始终是number of characters
+1
,因为有空终止符。当你写这句话的时候:
你只要说:
让
text
指向内存,文字所在的位置。复制文本实际上需要更多的工作。必须明确地做到:
请注意,您也需要手动删除它:
std::string
使它变得容易多了。它会自动复制文本,当你写这样的东西:std::string
的复制构造函数也对缓冲区进行硬拷贝。即使std::string
类看起来像这样:每次复制时,它都会执行
buffer
的硬拷贝,看起来像这样:注意,这只是一个简化的示例。
当你把变量作为参数传递给一个函数时,也会调用复制构造函数。编译器可以在一些常见的情况下优化它。