ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

char * 和 std::string

char * 和 std::string 1 char * 和 std::string 的区别char * 字符串是常量字符串不能修改std::string 指向的字符串可以修改实例代码如下图所示s1 和 s2 均是常量字符串字符串常量保存在只读数据区是只读的不能写代码中注释的那两行代码会导致段错误。s3 是字符数组字符数组是可以修改的std::string 类型的字符串也是可以修改的。#include stdlib.h #include stdio.h #include iostream #include string #include cstring int main() { char *s1 hello; char *s2 hello; char s3[] hello; std::string s4 hello; printf(s1 addr %p, s2 addr %p, s3 addr %p, s4 addr %p\n, s1, s2, s3, s4.c_str()); printf(sizeof(s1) %d, sizeof(s3) %d, sizeof(s4.c_str()) %d\n, sizeof(s1), sizeof(s3), sizeof(s4.c_str())); // s1[1] a; // s2[1] a; s3[1] a; s4[1] a; std::cout s1 s1 , s2 s2 , s3 s3 , s4 s4 std::endl; return 0; }代码运行之后可以看到 s1 和 s2 是常量字符串这两个指针指向的地址也是相同的。从 s1s2 的地址和 s3s4 的地址对比可以看出s3 和 s4 的地址相距比较近和 s1、s2 的地址相距比较远。s1、s2 和 s3、s4 保存的段都不一样前者保存在只读数据段后者保存在栈所以地址差距才会大。sizeof一个char*类型就是指针的大小在64位系统上是832位系统上是4sizeof s3返回的是一个数组的大小数组的大小就是这个数组所占的空间包含了字符串结尾的\0。strlen是纯字符串的长度不包含字符串结尾的\0。2 std::string 是深度拷贝如下图所示 有 3 个字符串s1、s2 和 s3。s2 是基于 s1 通过拷贝构造而来将 s2[1] 赋值为 a然后打印 s1 和 s2s1 仍为 hellos2 为 hallo说明 s1 和 s2 相互不影响是深拷贝。s3 被 s1 赋值将 s3[1] 赋值为 m然后打印 s1 和 s3s1 仍为 hellos3 为 hmllos1 和 s3 相互没有影响。#include iostream #include string int main() { std::string s1 hello; std::string s2 s1; std::cout 1, s2 s1 std::endl; s2[1] a; std::cout 2, s2 s2 , s1 s1 std::endl; std::string s3 aaa; s3 s1; std::cout 1, s3 s3 std::endl; s3[1] m; std::cout 2, s3 s3 , s1 s1 std::endl; return 0; }运行结果如下3 std::string capacity如下代码声明了一个空字符串 s1打印出来了 s1.capacity是 15也就是说 std::string 默认就会有 15 的空间。通过这样预申请空间的方式避免了小字符串申请内存也是一种用空间换时间的方法。如果字符串的大小不大于 15就不会申请堆空间如下代码可以验证。执行结果使用 gdb 调试对 malloc 设置断点可以查看上边的代码哪一行调用了 malloc()。第 11 行字符串长度是 16大于 15 了需要申请内存。第 12 行拷贝构造深拷贝长度大于 15需要申请内存。第 14 行赋值运算符长度大于 15需要申请内存。第 16 行新创建的 s6长度大于 15需要申请空间。代码第 17 行将 s4 赋值给 s6虽然 s4 的长度大于 15但是当前 s6 的 capacity() 是 20完全能够放得下 s4所以不需要再申请空间。4char数组#include stdlib.h #include stdio.h #include string.h #include iostream int main() { char a[] Hello; char b[] {H, e, l, l, o}; char *c Hello; int d 0; printf(sizeof(a) %d, sizeof(b) %d, sizeof(c) %d\n, sizeof(a), sizeof(b), sizeof(c)); std::cout a , b , c std::endl; printf(a: %s, b: %s, c: %s; a %p, b %p, c %p, d %p\n, a, b, c, a, b, c, d); return 0; }a和b都是char数组但是a和b所占用的内存空间是不一样的a最后有一个字符串结束符b没有。c是字符指针。a和b是数组可以修改c是字符指针指向只读内存不能修改。a、b、c都是保存大栈上并且对比3者的地址大小可以看大栈是向下生长的c指向只读数据区。打印b的时候因为b是字符串类型直到遇到字符串结束符才会结束所以会打印两个Hello把a指向的字符串也打印出来了。sizeof传入数组名的话返回的是数组的长度c就是一个指针大小与字长有关。
返回列表