我在尝试使用C++编程时,发现使用 const char*
和 const char[]
会导致代码表现出不同的行为。如果我的问题表述不太清晰,请谅解,因为我对代码中发生的事情并不十分明确。
#include <iostream>
#include <vector>
// This version uses <const char[3]> for <myStr>.
// It does not work as expected.
struct StrStruct
{
const char myStr[3];
};
// This program extracts all the string elements in <strStructList> and copy them to <strListCopy>
int main()
{
StrStruct strStruct1{"ab"};
StrStruct strStruct2{"de"};
StrStruct strStruct3{"ga"};
std::vector<StrStruct> strStructList{strStruct1, strStruct2, strStruct3};
std::vector<const char*> strListCopy{};
for (StrStruct strStructEle : strStructList)
{
strListCopy.push_back(strStructEle.myStr);
std::cout << "Memory address for the string got pushed back in is "
<< &strStructEle.myStr << std::endl;
std::cout << "Memory address for the first element of the string got pushed back in is "
<< (void *) &strStructEle.myStr[0] << "\n" <<std::endl;
}
std::cout << "Show content of <strListCopy>:" << std::endl;
for (const char*& strEle : strListCopy)
{
std::cout << strEle << std::endl;
}
}
以下是它的输出:
Memory address for the string got pushed back in is [address#99]
Memory address for the first element of the string got pushed back in is [address#99]
Memory address for the string got pushed back in is [address#99]
Memory address for the first element of the string got pushed back in is [address#99]
Memory address for the string got pushed back in is [address#99]
Memory address for the first element of the string got pushed back in is [address#99]
Show content of <strListCopy>:
ga
ga
ga
然而,如果我只是简单地改变
StrStruct
的实现方式:从:
// This version uses <const char[3]> for <myStr>.
// It does not work as expected.
struct StrStruct
{
const char myStr[3];
};
to
// This version uses <const char*> for <myStr>.
// It works as expected.
struct StrStruct
{
const char* myStr;
};
程序的输出如下:
Memory address for the string got pushed back in is [address#10]
Memory address for the first element of the string got pushed back in is [address#1]
Memory address for the string got pushed back in is [address#10]
Memory address for the first element of the string got pushed back in is [address#2]
Memory address for the string got pushed back in is [address#10]
Memory address for the first element of the string got pushed back in is [address#3]
Show content of <strListCopy>:
ab
de
ga
我困惑的是以下问题:
为什么在第一个版本中所有字符串都具有相同的值?我尝试在for each循环中使用
const strStruct&
代替strStruct
,这解决了问题,但我不明白原因。为什么
const char*
和const char[]
表现如此不同?我认为它们在很大程度上相似,因为:
const char myChars[] = "abcde";
const char* myCharsCopy = myChars;
std::cout << myChars << " vs " << myCharsCopy << std::endl;
它打印出abcde vs abcde
并且你可以直接将const char[]
的值分配给const char*
,而不会出现任何错误。
- 为什么将
const char[]
改为const char*
可以解决这个问题?
for (StrStruct strStructEle : strStructList)
会创建结构体的临时副本。您正在存储对这些副本的指针,并且似乎由于它们在循环结束时超出了作用域,程序一直在重复使用相同的位置,因此所有指针都指向同一位置。使用for (StrStruct & strStructEle : strStructList)
可以得到原始向量中的引用,而不是它们的副本。 - user4581301struct { char x[8]; }
时,你复制了字符串;当你复制struct { char *x; }
时,你复制了字符串的地址。 - Yakov Galka