c++中指针与引用的

翻译自 http://www.geeksforgeeks.org/references-in-c/

原文:

References vs Pointers
Both references and pointers can be used to change local variables of one function inside another function. Both of them can also be used to save copying of big objects when passed as arguments to functions or returned from functions, to get efficiency gain.
Despite above similarities, there are following differences between references and pointers.

A pointer can be declared as void but a reference can never be void
For example

int a = 10;
void* aa = &a;. //it is valid
void &ar = a; // it is not valid

References are less powerful than pointers
1) Once a reference is created, it cannot be later made to reference another object; it cannot be reseated. This is often done with pointers.
2) References cannot be NULL. Pointers are often made NULL to indicate that they are not pointing to any valid thing.
3) A reference must be initialized when declared. There is no such restriction with pointers

Due to the above limitations, references in C++ cannot be used for implementing data structures like Linked List, Tree, etc. In Java, references don’t have above restrictions, and can be used to implement all data structures. References being more powerful in Java, is the main reason Java doesn’t need pointers.

References are safer and easier to use:
1) Safer:
 Since references must be initialized, wild references like wild pointers are unlikely to exist. It is still possible to have references that don’t refer to a valid location (See questions 5 and 6 in the below exercise )
2) Easier to use: References don’t need dereferencing operator to access the value. They can be used like normal variables. ‘&’ operator is needed only at the time of declaration. Also, members of an object reference can be accessed with dot operator (‘.’), unlike pointers where arrow operator (->) is needed to access members.

Together with the above reasons, there are few places like copy constructor argument where pointer cannot be used. Reference must be used pass the argument in copy constructor. Similarly references must be used for overloading some operators like ++.

译文:

引用VS指针

相同点:

  1. 都可以在一个函数中修改位于另一个函数内的局部变量。
  2. 都可以以“按引用传递”的方式传递函数参数,避免了“按值传递”方式向函数传递/从函数返回自定义类型的数据时调用复制构造函数,以及复制大量数据,从而提高了时间和空间效率。
不同点:
  1. 指针可以是void* 类型的,引用则不可以
  2. 引用的对象在初始化以后就不可以再修改,相当于 TYPE *const ptr_name    (指针常量)
  3. 指针可以设置为NULL,表示不指向任何有效的对象,而必须有效的初始化,不能设置为NULL
  4. 引用在声明时必须初始化,而指针没有这个限制
引用比指针更安全和更易用:
更安全:因为引用必须初始化,所以类似于“野指针”的“野引用”是不存在的,但仍然会没有引用到有效地址。比如下面的5,6
更易用:引用在访问值的时候不必解引用。&操作符只有在声明引用的时候使用。同样,在访问一个对象的成员时,使用(.)操作符,指针需要使用(->)操作符访问对象的成员

由于以上原因,指针几乎可以用在所有的场合,除了复制构造函数的参数中,复制构造函数的参数必须使用引用,同理,引用也必须用在重载某些操作符时,比如++


Exercise:
Predict the output of following programs. If there are compilation errors, then fix them.

Question 1

#include<iostream>
using namespace std;
 
int &fun()
{
    static int x = 10;
    return x;
}
int main()
{
    fun() = 30;
    cout << fun();
    return 0;
}
Question 2

#include<iostream>
using namespace std;
 
int fun(int &x)
{
    return x;
}
int main()
{
    cout << fun(10);
    return 0;
}
Question 3
#include<iostream>
using namespace std;
 
void swap(char * &str1, char * &str2)
{
  char *temp = str1;
  str1 = str2;
  str2 = temp;
}
 
int main()
{
  char *str1 = "GEEKS";
  char *str2 = "FOR GEEKS";
  swap(str1, str2);
  cout<<"str1 is "<<str1<<endl;
  cout<<"str2 is "<<str2<<endl;
  return 0;
}
Question 4
#include<iostream>
using namespace std;
 
int main()
{
   int x = 10;
   int *ptr = &x;
   int &*ptr1 = ptr;
}
Question 5
#include<iostream>
using namespace std;
 
int main()
{
   int *ptr = NULL;
   int &ref = *ptr;
   cout << ref;
}//错误:给引用赋值 NULL

Question 6
#include<iostream>
using namespace std;
 
int &fun()
{
    int x = 10;
    return x;
}
int main()
{
    fun() = 30;
    cout << fun();
    return 0;
}//返回的是局部变量的引用,编译器会报错

warning: reference to local variable 'x' returned [-Wreturn-local-addr]

指针引用

#include<iostream>
using std::cout;
using std::endl;
void increament(int *&i){i++;}

int main(){
  int *i = 0;
  cout<<"i = "<<i<<endl;
  increament(i);
  cout<<"i = "<<i<<endl;
}

输出结果
i = 0
i = 0x4




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值