C++ 指针、数组和引用辨析

一、指针:内容是指示一个内存地址的变量;类型是指示编译器怎么解释指针内容指向地址中的内容,以及该内存区域有多大;

例子:

int i = 0;
int * pi = &i;
printf(“pi = %x  \n”, pi);     // 打印pi的内容: 0x2000
printf(“*pi= %d  \n” , *pi);   // 打印pi指向地址中的值: 5
printf(“&pi= %x  \n”, &pi);    // 打印pi的地址: 0x100



从汇编的角度来看,指针是这样的
int i = 0;
010E139E  mov         dword ptr [i],0  
int * pi = &i;
010E13A5  lea         eax,[i]  
010E13A8  mov         dword ptr [pi],eax


二、数组是一个单一数据类型对象的集合。其中单个对象没有被命名,通过索引访问。

数组名和指针的区别数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组。数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针常量。指向数组的指针则是另外一种变量类型,仅仅意味着数组的存放地址

注意:虽然数组名可以转换为指向其指代实体的指针,但是它只能被看作一个指针常量,不能被修改,如下:

   int intArray[10];
   intArray++; // 错误

“指针和数组等价”说的是什么索引操作相同,例如: p[2];  a[2];


三、 引用 reference )是一个对象的别名。用对象初始化引用后,对象的名字和引用都指向该对象;

引用是如何实现的? 从汇编语言的角度来看,指针和引用是一样的:
	int i = 0;
00E9139E  mov         dword ptr [i],0  
	int & ref = i;
00E913A5  lea         eax,[i]  
00E913A8  mov         dword ptr [ref],eax  
	int * pi = &i;
00E913AB  lea         eax,[i]  
00E913AE  mov         dword ptr [pi],eax 

指针和引用的区别(从C++ 使用角度来看)
  • 不存在空引用
  • 引用要初始化
  • 引用初始化后,不能指向另一个对象

这是由编译阶段保证的。


备注
1、一个指向非常量的引用不能用字面值或者临时值初始化;但是一个指向常量的引用可以。
例子:

double& d = 12.3;  // error!
const double& d = 12.3;
2、由于引用必须初始化,所以使用引用之前不需要测试其有效性,因此使用引用可能会比使用指针效率高。
3、当你实现一个操作符而其语法需求无法由指针完成时,应该选择引用,例如operator[]。operator[]能够出现在一个赋值操作符的左右两边,为了能在左边出现,它的返回值必须是左值,再考虑到使用的方便性,通常把其返回值指定为一个引用类型。
例子:
#include <cassert>

char& String::operator[](int elem) const
{
    assert(elem >= 0 && elem <= length());
    return _string[elem];
}
4、当你需要考虑不指向任何对象的可能性,或考虑在不同时候指向不同对象的能力时,应该使用指针。
5、引用的所有操作实际上都是应用在它所指的对象上,包括取地址操作符。
6、一些有些特殊的引用举例:
int  val = 10;
int* pval = &val;
int*& rpval = pval; // 指针引用

const int i = 10;
const int * const & ref = &i; // 指向常量对象地址的引用








评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值