每日诗词:
我见青山我妩媚,料青山见我应如是。
——《贺新郎·甚矣吾衰矣》【宋】辛弃疾
目录
补漏:
vector在分配新内存块后如何进行元素复制
在std::vector分配新的内存块以扩容后,它需要将旧内存块中的所有元素复制到新分配的内存块中。这个复制过程具体是如何进行的,取决于元素的类型和编译器/标准库的实现,但通常遵循以下原则:
1.元素类型:如果元素类型是简单类型(如int、float等),则复制过程通常是通过简单的内存拷贝操作完成的,比如使用memcpy或类似的函数。对于这些类型,不需要调用构造函数或析构函数。
2.复杂类型:如果元素类型是复杂类型(比如自定义的类或结构体),则复制过程需要更加小心。在这种情况下,元素的复制通常是通过调用元素的拷贝构造函数(或拷贝赋值运算符,具体取决于实现)来完成的。这意味着每个元素都会被单独复制,包括其所有成员变量。
3.C++11及以后:从C++11开始,移动语义被引入,这可能会影响vector扩容时的元素复制行为。如果元素类型支持移动操作(即定义了移动构造函数和移动赋值运算符),则vector可能会选择移动元素而不是复制元素,以提高效率。移动操作允许将资源(如动态分配的内存)从一个对象“转移”到另一个对象,而不是复制它们。这通常比复制更快,因为移动操作可以避免不必要的内存分配和释放。
在vector扩容时,一旦新内存块被分配,旧内存块中的所有元素就会按照上述原则被复制(或移动)到新内存块中。然后,旧内存块会被释放,以避免内存泄漏。最后,vector会更新其内部指针和容量值,以反映新的内存块和新的容量。vector扩容时内存分配的策略是什么?
正文:
字符串变量和常量
字符串变量:
- 字符串是以空字符('\0')结束的字符数组
- 空字符'\0'会自动添加到的内部表示中
- 在声明字符串变量时,应该为这个结束符预留一个元素的位置。
- 例如:char a[11]={"helloworld"};
#include<iostream>
using namespace std;
int main()
{
char a[10]={"helloworld"};
return 0;
}
请大家判断我上面的代码是对还是错。答案是错的。
解析:
这是因为我们要在数组中预留一个位置给空字符,我们可以不用写空字符,系统会给我们自动补上,但是我们要留一个位置给空字符。
字符串常量:
字符串常量是一对双引号括起来的字符序列。
字符串中的每一个字符作为一个数组的元素来存储。(所以我们可以通过数组的下标来定位这个元素的位置,对这个元素进行一些操作)
例如字符串"helloworld";
但是这个结束符也会导致字符串出现一些bug,会导致程序错误,结果不符。这个缺陷我在往期的文章中专门说过。C语言字符串缺陷
关于字符表示的说明:
- char c1=0 //0x00
- char c2='\0' //0x00
- char c3='0' //0x30
看上面的例子,大家思考一下他们之间相同吗,为什么?
每一行的后面我写上的注释是这些变量在计算机内部的机械码表示。这个0x是十六进制的表示。
所以我们可以看到1和2是相同的,3是不同的。这就说明0和\0在计算机中(字符串数组这部分)代表的意义相同。他们之间的本质就是后面地机械码(ASCII码表)的关系上。
大家看上面的拼图,这个就是那三个例子的机械码表示,这些是16进制表示,可以转换成十进制。所以它们三个在机械码中有着各自的含义。
ASCII码表
ASCII码表(American Standard Code for Information Interchange)是美国信息交换标准代码的缩写,它是一套电脑编码系统,主要用于显示现代英语和其他西欧语言中的字符。ASCII码表包含了128个字符,包括大小写英文字母、数字、标点符号、控制字符等,每个字符都对应着一个唯一的7位二进制数(或者说是一个介于0到127之间的十进制数)。这些字符按照一定的顺序排列在ASCII码表中,其中一些常用的字符。
如大写字母'A'到'Z'、小写字母'a'到'z'、数字'0'到'9'等,都有固定的ASCII码值与之对应。例如,大写字母'A'的ASCII码是65,小写字母'a'的ASCII码是97,数字'0'的ASCII码是48。
链接在这大家可以自行查看:ascii码对照表
但是由于计算机的普及这种由美国研制的码表就不那么通用了,下期我们会提到一个更通用的码表。
标签:vector,码表,元素,C++,详解,内存,字符串,ASCII From: https://blog.csdn.net/2301_81280642/article/details/141504037