0

虽然我在 C++ 中使用 char* 数组尝试了一些示例程序,但程序的输出对我来说不是很清楚。

示例代码

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<string>

using namespace std;

int main()
{
    string val="val1";
    char* hello[10]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};

    hello[1]=(char*)val.c_str();

    val="val2";

    printf("The val in hello[1] is :%s\n",hello[1]);

    hello[3]=(char*)val.c_str();

    printf("The val in hello[3] is :%s\n",hello[3]);
}

结果 :

The val in hello[1] is :val2

The val in hello[3] is :val2

但是同样的程序我附加了字符串

val.append("val2"); //val="val2";

结果是

The val in hello[1] is :val1

The val in hello[3] is :val1val2

您能否解释一下,输出如何给出 2 个不同的结果?

4

3 回答 3

1

string.c_str()返回 . 使用的内部char*缓冲区string

当您第一次获得指向内部缓冲区的指针c_str()并将其存储在 中hello[1]时,缓冲区包含"val1". 在下一行你用 value 覆盖字符串"val2"。由于"val1""val2"的长度相同,因此新值适合原始缓冲区,因此会被覆盖。

相反,当您追加"val2"到时val,原始内部缓冲区必须太小而无法容纳结果,因此它会分配一个新缓冲区。因此,hello[1]andhello[3]指向两个不同char*的 s,它们持有不同的值。

您可以通过在程序末尾添加几行来看到两个打印机不相等:

printf("Pointer in hello[1]: %p\n", hello[1]);
printf("Pointer in hello[3]: %p\n", hello[3]);

我在测试运行中得到了这些结果:

Pointer in hello[1]: 0x10ca00a68
Pointer in hello[3]: 0x10ca00a88

调用append显然会强制字符串分配一个新的、更大的缓冲区。但是,您不能保证缓冲区 inhello[1]将保持其当前值,因为string如果您再次调用字符串方法(甚至可能在另一个字符串上),实现可能会决定稍后重用该缓冲区。

于 2013-10-18T04:54:32.843 回答
1

在第一种情况下,您将值明确地分配给 std::string,擦除存储在那里的先前值,但在第二种情况下,使用 std::string::append 您将新值“val2”添加到先前存在的一个“val1” .

以下是一些规范:http ://en.cppreference.com/w/cpp/string/basic_string/append “通过在其当前值的末尾附加附加字符来扩展字符串”

于 2013-10-18T04:54:55.447 回答
0

一个 char* 类型的数组,所有 NULL 将被 c++ 视为一个空字符串。

会发生什么: printf 在内存中接收到一个指针并开始一个一个地“打印”字符,直到它遇到 NULL。所以 NULL 终止字符串。NULL 之后的所有内容都不会被考虑在内

append() 在这种情况下将开始将字符放置在前一个字符的末尾。这是“val1”之后的第一个NULL

希望能帮助到你

于 2013-10-18T04:57:29.483 回答