pointer和reference有什么差别呢? (C/C++)

C语言和其它程序性语言,如FORTRAN,Pascal,BASIC最大的差别就在于pointer,而pointer也是学习C语言最大的门坎,pointer的本意是希望function在传递数据时,不用将数据用copy的方式将数据copy进function的stack中,以加快程序执行速度和节省内存,如array通常占的内存都很大,若copy的方式势必降低速度且耗内存,但pointer的缺点就是程序不易阅读,需要一段时间去熟析这种怪异的语法。

C++为了解决pointer程序不易阅读的问题,增加了reference型别,C#/Java也取消了pointer,用reference取代pointer,但reference和pointer有什么不同呢?

Reference基本上存的也是『内存地址』,这和pointer一样,但pointer取值时,还必须dereference,也就是必须透过『*』才能取值,因此才会出现*** pointer to pointer to pointer这种难以理解的语法,但reference是一种『高级的pointer』,不需deference即可取值,所以不论是几层,仍然是reference这个变量而已,也因为不需dereference,所以书上都强调reference可视为变量的alias(别名、化名)(C++ Primer 4th P.59 A reference is an alias.),这使的reference骨子里存的是内存地址,但用起来却和一般变量一样方便,程序也漂亮许多,我们看一下(以下程序摘自 多型与虚拟 对象导向的精随 P.27侯俊杰)

 1 #include  < iostream >
 2
 3 int *  func1( int *  x);
 4 int &  func2( int &  x);
 5
 6 int  main()  {
 7  int a = 0;
 8
 9  std::cout << *func1(&a) << std::endl; // output : 1;
10
11  std::cout << func2(a) << std::endl;   // output : 2
12}

13
14 //  Use pointer
15 int *  func1( int *  x)  {
16  (*x)++;
17
18  return x;
19}

20
21 //  Use reference
22 int &  func2( int &  x)  {
23  x++;
24
25  return x;
26}


各位就可看到,若用reference写,程序是不是好看很多了?再举一个例子,将两个变量的内容交换:

 1 #include  < iostream >
 2
 3 void  swap1( int *  x,  int *  y);
 4 void  swap2( int &  x,  int &  y);
 5
 6 int  main()  {
 7  int x = 1;
 8  int y = 2;
 9
10  std::cout << "x=" << x << " y=" << y << std::endl; // Output : x=1 y=2
11  
12  // Use pointer
13  swap1(&x, &y);
14  std::cout << "x=" << x << " y=" << y << std::endl; // Output : x=2 y=1
15
16  // Use reference
17  swap2(x,y);
18  std::cout << "x=" << x << " y=" << y << std::endl; // Output : x=1 y=2
19}

20
21 void  swap1( int *  x,  int   * y)  {
22  int tmp = *y;
23  *= *x;
24  *= tmp;
25}

26
27 void  swap2( int &  x,  int &  y)  {
28  int tmp = y;
29  y = x;
30  x = tmp;
31}

32


以上的例子,都明显的发现reference的确比pointer优秀,但相信很多人跟我一样,基乎没有使用这种Call by pointer(reference)的方式传值,都使用Call by value的方式,因为怕的就是Side effect,由于argument和parameter的内存地址相同,若function中不小心改了parameter的变量,就造成argument变量值改变了,在其它语言的确没有解决的方案(C#/Java/VB),但在C++中,提供了const reference的方式,让parameter为只读,若程序不小心改了parameter,compiler会挡下来:

 1 #include  < iostream >
 2
 3 int  Add( const   int &  x,  const   int &  y);
 4
 5 int  main()  {
 6  int x = 1;
 7  int y = 2;
 8  int s = 0;
 9
10  s = Add(x,y);
11
12  std::cout << x << " + " << y << " = " << s << std::endl; // Output : 1 + 2 = 3
13}

14
15 int  Add( const   int &  x,  const   int &  y)  {
16  // x++; Compile error : you can not assign a varible that is const.
17  return x + y;
18}

19
20
21


所以为了程序效率以及节省内存,应该尽量使用reference来写程序,可以避免copy的动作,而且reference的写法程序的可读性远比pointer高,而写法基乎和一般变量一样,只有宣告reference时不一样而已。

Reference
C++ Primer 4th P.58
多型与虚拟 对象导向的精随 P.27 侯俊杰

你可能感兴趣的:(reference)