当我使用char *数组在c ++中尝试一些示例程序时,程序的输出对我来说不是很清楚。
示例代码
#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个不同的结果?
答案 0 :(得分:1)
string.c_str()
返回char*
使用的内部string
缓冲区。
当您第一次通过c_str()
获取指向内部缓冲区的指针并将其存储在hello[1]
中时,缓冲区包含"val1"
。在下一行,您将使用值"val2"
覆盖字符串。由于"val1"
和"val2"
的长度相同,因此新值适合原始缓冲区,因此会被覆盖。
相反,当您将"val2"
追加到val
时,原始内部缓冲区必须太小才能保存结果,因此它会分配一个新缓冲区。因此,hello[1]
和hello[3]
指向两个不同的char*
,并且它们具有不同的值。
通过在程序末尾添加几行,您可以看到两台打印机不相同:
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
显然强制字符串分配一个新的更大的缓冲区。但是,您无法保证hello[1]
中的缓冲区将保持其当前值,因为如果您再次调用字符串方法,string
实现可能会决定重用该缓冲区 - 甚至可能另一个字符串。
答案 1 :(得分:1)
在第一种情况下,您将明确地将值分配给std :: string,擦除存储在那里的先前值,但在第二种情况下使用std :: string :: append,您将向以前存在的值添加新值“val2” “VAL1”。
以下是一些规格:http://en.cppreference.com/w/cpp/string/basic_string/append “通过在当前值的末尾追加其他字符来扩展字符串”
答案 2 :(得分:0)
具有所有NULL的char *类型的数组将被c ++视为空字符串。
会发生什么:printf在内存中接收指针并开始逐个“打印”字符,直到遇到NULL。所以NULL终止字符串。 NULL之后的所有内容都不会被考虑在内
在这种情况下,append()将开始在前一个字符的末尾放置字符。哪个是“val1”之后的第一个NULL
希望有所帮助