C++PrimerPlus跟读记录【第四章】复合类型(下)指针 new vector

目录

7、指针和自由存储空间

8、指针、数组和指针运算术

9、类型组合

10、vector array


7、指针和自由存储空间

计算机内存

  • 计算机存储数据时必须的基本属性:信息存储在何处、值是多少、什么类型。
  • 内存地址使用十六进制表示法,每个地址占1字节,8bit。
  • 两个地址间相差4是因为存储类型为int,占用4个字节。

运行阶段

  • 编译阶段:编译器将程序组合起来。声明数组必须指定数组长度,在编译阶段分配内存。
  • 变量:在编译时分配的有名称的内存。
  • 运行阶段:看情况判断,运行阶段决策。

指针

  • 指针是一个变量,存储的值是地址,而不是值本身。
  • 对常规变量采用地址运算符 & ,就可获得其位置。
  • 运算符 * 称为间接值或解除引用运算符,用于指针可以得到该地址存储的值。

声明与初始化

  • 指针声明必须指定指向的数据类型。
  • 没有初始化的指针不知道信息存储在哪,可能改写内存中的信息。
  • 声明时初始化

  • 指针没有初始化,可能指向任何值。
  • 一定要在使用 * 之前,将指针初始化为一个确定的地址
  • 指针不是整型,两者截然不同,数值当做地址必须经过强制类型转换。
int* ptr = (int*) 0xB8000000;

分配内存 new

  • 指针真正的用武之地在于,在运行阶段分配未命名的内存以存储值。
  • 变量:在编译时分配的有名称的内存。
  • 指针:直接访问内存的别名。
  • C语言中采用库函数malloc()分配内存,C++采用new运算符。使程序在内存管理方面有更大的控制权。
  • 通用格式: typeName* pointer_name = new typeName;
  • new将找到一个长度正确的内存块,并返回其地址。

   

  • pn的内存只能通过指针访问。
  • new分配的内存块与常规变量分配的内存不同:普通变量值存储在栈(stack)内存中,new从堆(heap)或自由存储区域(free store)分配内存。
  • C++中值为0的指针称为空指针(null pointer),不会指向有效的数据,用来表示运算符或函数失败。

释放内存delete

int* ptr = new int;
...
delete ptr;
  • delete 用来释放new分配的内存,且只能用于new分配的内存。
  • delete将释放ptr指向的内存,不会删除指针本身,可以将ptr指向新的内存。
  • delete 和 new 一定要配对使用,否则会发生内存泄漏(memory leak)。
  • 不要释放已经释放的内存块,否则什么情况都有可能发生。
  • delete 不能用于声明变量的内存,可以用于空指针。
  • 一般不要创建两个指向同一内存的指针。

new 创建动态数组

  • 静态联编(static binding):在编译时给数组分配内存。如果通过声明创建数组,则在程序编译时分配内存,不管程序最终是否使用,都占用了内存。
  • 动态联编(dynamic array):使用new创建动态数组:在运行阶段,如果使用则创建,不需要则不创建。
  • 静态联编时在编写程序时指定数组长度,动态联编时在运行阶段确定数组长度。
int* psome = new int[10];
delete [] psome;

int* pt = new int;
delete pt;
  • 在类型名后要声明包含的元素数目。
  • new 运算符返回第一个元素的地址。
  • 通用格式:type_name* pointer_name = new type_name [num_elements];
  • delete[] 表示释放整个数组,不仅仅是指针指向的元素。

小结

  • 不能使用sizeof运算符决定动态分配的数组包含的字节数。

访问动态数组

  • ptr指向第一个元素double[0],*ptr是第一个元素的值。
  • 访问元素只需将指针作为数组名使用即可。数组和指针基本等价是C和C++的优点之一。
double* ptr = new double[3];
ptr[0] = 0.2;
ptr[1] = 0.5;
ptr[2] = 0.8;

ptr = ptr + 1;
ptr = ptr - 1;

delete [] ptr;

  • ptr = ptr + 1;  将指针指向第二个元素。
  • 指针变量+1后,增加的值等于指向类型所占的字节数。
  • delete时,要保证指针提供正确的首元素的地址。

8、指针、数组和指针运算术

  • C++将数组名解释为数组第一个元素的地址。
  • 特殊情况:对数组使用sizeof()得到的是数组长度(单位为字节);对指针sizeof()得到指针本身的长度。
  • 特殊情况2:对数组取地址时,数组名不会被解释为地址。
  • 对数组名取地址得到整个数组的地址。

指针和字符串

  • 给cout提供一个字符的地址,将从该字符开始打印,直到空字符为止。
  • 如果要打印字符串地址,需要将指针强转:cout << (int *) ptr; 

  • "wren"的地址赋值给指针bird,cons关键字,使得可以用bird访问字符串,但不能修改。

strncpy()

  • strncpy(target,  source,  size);
  • 第三个参数是,要复制的最大字符数。
  • source长度小于size,复制后自动在结尾添加空字符。
  • source长度大于size,不会添加空字符,需要手动置空。

9、类型组合

10、vector array

模板类vector

  • 动态数组,可以在运行阶段改变vector对象长度
  • 使用new 、delete自动管理内存
  • #include <vector>
  • using namespace std;
  • vector<int> vi;
  • vector<int> vi[n];

模板类array

  • array 适合固定长度的数组,栈(静态内存分配)
  • 比数组方便安全
  • vector 功能强大,更方便安全,但,效率低
  • #include <array>
  • using namespace std;
  • array<int, 4> ai;
  • array<double, 3> ad = {1.2, 1.1, 1.3};

对比

  • array对象 和 数组 存储在栈内存区域
  • vector对象 存储在自由存储区或堆
  • 可以将array对象赋值给另一array对象,数组不可以
  • C++不检查超界错误,*(a1 - 2) = 2.2; 存储到数组外面。

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值