c++ primer plus笔记(2)指针与数组名

一、指针基础:

①指针的两种理解方法:

int* p = nullptr;

          C-style:     int   *p;      //指向int的指针p

          C++-style:   int*   p;      //int*型数据p

②指针算数:

1>减法:

同类型指针做减法时,得到这两个指针的间距,间距为整数(个单位距离);

int array_name[5] = {1,2,3,4,5};
int* p_a0 = &array_name[0];
int* p_a4 = &array_name[4];
int c = p_a4 - p_a0;          //得到p_a4与p_a0的间距,该间距是一个整数

 

//一般来说,指针减法运算只在同一数组范围内有实用意义;

 

2>加法:

指针只能与整数做加法,两个指针(即使为同类型)之间不可直接做加法;

int array_name[5] = {1,2,3,4,5};
int* p_a0 = &array_name[0];
int* p_a4 = &array_name[3];
p_a0 = p_a0 + 1;           //可行
p_a3 = p_a3 + 1;           //可行
int p_n = p_a0 + p_a3;     //不可行

二、指针与数组名:

int array_name[SIZE];           //数组名
int* p_array = new int[SIZE];   //指针操作的数组

//正如操作new得到的heap区内存一样,指针的一个很重要的用途是,直接操作没有命名的内存(块)

①共同点:

1>都可以使用[ ]下标方法或*解除引用访问数组元素:

array_name[i];  //同*(array_name + i)
p_array[i];     //同*(p_array + i)

//下标方法访问数组元素既然被解释为*(p_array + i),会不会导致指针实际位置移动呢?

#include "stdafx.h"
#include<iostream>

int main()
{
	//
	using std::cout;
	using std::endl;

	//
	int*p = new int[3];
	p[0] = 1;
	cout << "\t" << p[0] << "p:" << (void*)p << endl;
	p[1] = 2;
	cout << "\t" << p[1] << "p:" << (void*)p << endl;
	p[2] = 3;
	cout << "\t" << p[2] << "p:" << (void*)p << endl;

	//
	cout << *p << endl;
	delete []p;

	//
	system("pause");                                   //结论:对指针的类数组操作p[1],p[2],p[3]并不会导致指针实际移动
    return 0;
}

 

2>绝大部分情况下,都表示地址:

 

array_name和p_array都被解释为指针首元素的地址;

std::cout << array_name << std::endl;
std::cout << p_array << std::endl;
//输出结果都是数组首元素地址
//特殊的,对于char*和char[],二者都将输出整个字符串

②区别:

1>数组名的行为更接近const指针。数组名是常量,而(非const)指针可以修改指向;

array_name++;    //不允许
p_array++;       //允许

//array_name与&array_name的区别:

#include "stdafx.h"
#include<iostream>

int main()
{
	//
	using std::cout;
	using std::endl;

	//
	int array_name[5] = { 1,2,3,4,5 };
	cout << "\t" << "array_name:" << array_name << endl;
	cout << "\t" << "&array_name:" << &array_name << endl;              //输出结果数值一致

	//
	system("pause");
    return 0;
}

//但事实上只是数值上一致:array_name被解释为首元素地址,跳转单位为1个int;((array_name+1)跳转4byte)

                                         &array_name被解释为整个数组的地址,跳转单位为5个int;((&array+1)跳转20byte)

2>sizeof的结果不同:

sizeof(array_name);   //数组大小
sizeof(p_array);      //指针大小

三、智能指针:

智能指针是一类模板类,在头文件<memory>中被声明。

智能指针被提出的目的是简化new和delete的使用。

现有的三种智能指针模板类:

①auto_ptr<>:

auto_ptr<>是三种智能指针中最老式的版本,功能不完善,不能够处理所有权(ownership)问题:

auto_ptr<string> p1 = auto_ptr<string>(new string("some words"));
auto_ptr<string> p2 = p1;   //p1指向的字符串所有权转交给p2,p1不再指向该字符串

此时p1为NULL,这导致指针不可再用。

另外,auto_ptr<>只能管理使用new分配的内存,而不能用于管理使用new[]分配的内存。

②shared_ptr<>:

shared_ptr<>是稍优于auto_ptr<>的版本,在所有权问题上进行了改善:

shared_ptr<string> p1 = shared_ptr<string>(new string("some words"));
shared_ptr<string> p2 = p1;   //引用计数+1,p1和p2都指向同一个字符串

shared_ptr<>使用引用计数,在计数降至1之前将不会调用带有delete的析构函数,以此避免所有权矛盾。

和auto_ptr<>一样,shared_ptr<>也只能管理使用new分配的内存,而不能用于管理使用new[]分配的内存。

③unique_ptr<>:

unique_ptr<>不允许非临时的所有权的转让:

unique_ptr<string> p1 = unique_ptr<string>(new string("some words"));
unique_ptr<string> p2 = p1;   //不允许这样的赋值

和auto_ptr<>以及shared_ptr<>不同,unique_ptr既可用于管理new又可用于new[]分配的内存。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值