c++指標的應用及注意問題

來源:互聯網
上載者:User

c++指標的應用及注意問題

  指標是c/c++學習一個比較讓人頭痛的問題,在程式設計過程中,指標也往往是產生隱含bug的原因。下面就來談談指標的應用以及需要注意的一些問題,裡面也許就有你平時沒有注意到的問題,希望能協助各位讀者理解好指標。

  一、我們先來回憶一下指標的概念吧,方便下面的介紹

  指標是存放地址值的變數或者常量。例如:int a=1;&a就表示指標常量(“&”表示取地址運算子,也即引用)。int *b,b表示的是指標變數(注意,是b表示指標變數而不是*b),*表示要說明的是指標變數。大家注意int *b[2]和int(*b)[2]是不同的,int *b表示一個指標數組,而int (*b)[2]表示含有兩個元素的int指標,這裡要注意運算優先順序問題,有助於理解指標問題。

  在這裡大概介紹基本概念就夠了,至於具體使用方法,如賦值等,很多書都有介紹,我就不多說了。

  二、應用以及注意的問題

  1、 理解指標的關鍵所在——對指標類型和指標所指向的類型的理解

  ①、 指標類型:可以把指標名字去掉,剩下的就是這個指標

  例如:int *a;//指標類型為int *

  int **a;//指標類型為int **

  int *(*a)[8];//指標類型為 int *(*)[8]

  ②、 指標所指向的類型:是指編譯器將把那一片記憶體所看待成的類型。這裡只要把指標聲明語句中的指標名字和名字右邊的“*”號去掉就可以了,剩下的就是指標所指向的類型。

  我之所以把他們放在第一位,是因為弄清楚他們是學c/c++指標的重點,正確理解他們才能使你打好c/c++的編程基礎。

  2、 指標的應用——傳遞參數。

  其實它可以相當於隱式的傳回值,這就比return的方法更加靈活了,可以返回更多的值,看看下面的例子自然就明白了:

  #include "iostream.h"

  void example(int *a1,int &b1,int c1)

  {

  *a1*=3;

  ++b1;

  ++c1;

  }

  void main()

  {

  int *a;

  int b,c;

  *a=6;

  b=7;c=10;

  example(a,b,c);

  cout 《"*a="《*a<

  cout 《"b="<

  cout 《"c="<

  }

  輸出:*a=18

  b=8

  c=10

  注意到沒有,*a和b的值都改變了,而c沒有變。這是由於a1是指向*a(=6)的指標,也即與a是指向同一個地址,所以當a1指向的值改變了,*a的值也就改變了。在函數中的參數使用了引用(int &b1),b1是b的別名,也可以把它當作特殊的指標來理解,所以b的值會改變。函數中的參數int c1隻是在函數中起作用,當函數結束時候便消失了,

  所以在main()中不起作用。

  3、 關於全域變數和局部變數的一個問題

  先不廢話了,先看看程式:

  #include “iostream.h”

  int a=5;

  int *example1(int b)

  {

  a+=b;

  return &a;

  }

  int *example2(int b)

  {

  int c=5;

  b+=c;

  return &b;

  }

  void main()

  {

  int *a1=example1(10);

  int *b1=example2(10);

  cout 《”a1=”《*a1<

  cout 《”b1=”《*b1<

  }

  輸出結果:

  a1=15

  b1=4135

  *b1怎麼會是4135,而不是15呢?是程式的問題?沒錯吧?

  由於a是全域變數,存放在全域變數的記憶體區,它一直是存在的;而局部變數則是存在於函數的棧區,當函數example2()調用結束後便消失,是b指向了一個不確定的地區,產生指標懸掛。

  下面是對example1()和example2()的反組譯碼(用TC++ 3.0編譯):

  example1():

  push bp;入棧

  mov bp,sp

  mov ax,[bp+04];傳遞參數

  add [00AA],ax;相加

  mov ax,00AA ;返回了結果所在的地址

  pop bp;恢複棧,出棧

  ret;退出函數

  example2():

  push bp;入棧

  mov bp,sp

  sub sp,02

  mov word ptr [bp-02],0005

  mov ax,[bp-02];傳遞參數

  add [bp+04],ax;相加

  lea ax,[bp+04];問題就出在這裡

  mov sp,bp

  pop bp;恢複棧,出棧

  ret;退出函數

  對比之後看出來了吧?ax應該是儲存的是結果的地址。而在example2()中,返回的卻是[bp+04]的內容,因此指標指向了一個不確定的地方,由此產生的指標懸掛。example1()中,ax返回了正確的結果的地址。

  4、 記憶體問題:使用指標注意記憶體的分配和邊界。

  使用指標過程中應該給變數一個適當的空間,以免產生不可見的錯誤。

  請看以下代碼:

  #include “iostream.h”

  void main()

  {

  char *a1;

  char *a2;

  cin 》a1;

  cin 》a2;

  cout 《”a1=”<

  cout 《”a2=”<

  }

  輸入:abc

  123

  輸出:

  a1=123

  a2=

  Null pointer assignment

  指標指向了“空”。解決辦法就是分配適當的記憶體給這兩個字串。修正後的代碼

  如下:

  #include “iostream.h”

  void main()

  {

  char *a1;

  char *a2;

  a1=new char [10];

  a2=new char [10];

  cin 》a1;

  cin 》a2;

  cout 《”a1=”< // cout 《”a2=”<

  delete(a1);注意,別忘了要釋放記憶體空間

  delete(a2);

  }

  到此就能輸出正確的結果了。

  分配了適當的記憶體之後要注意釋放內參空間,同時還應該注意不要超出所分配的記憶體的大小,否則會有溢出現象產生,導致不可預料的結果。

  5、 關於特殊的指標——引用

  引用有時候應用起來要比指標要靈活,用它做返回的時候是不產生任何變數的副本的這樣減小了記憶體的佔用,提高執行的速度。引用使用起來要比指標好理解,比較直觀。當引用作為參數時,不會改變參數的地址,因此可以作為左值。

  下面請看一個例子:

  #include “iostream.h”

  char ch[5]=”ABCD”;

  char &example(int b)

  {

  return ch;

  }

  void main()

  {

  cout 《”ch=”<

  example(2)=”c”;

  cout《”ch=”<

  }

  ch=ABCD

  ch=ABcD

  在實際編程過程中,可以靈活地引用或指標,盡量提高程式的可讀性和執行效率。

  三、小結

  指標是學習c/c++的重點痛點,主要原因是指標較為抽象,不容易理解。使用指標千萬要明白讓指標指向什麼地方,如何讓指標指向正確的地方。在深入系統底層之中需要應用到大量的指標,因此需要理解好指標的基本概念,例如:指標類型和指標所指向的類型。平時應該對留心觀察,瞭解程式的工作過程,必要時候可以對程式進行反組譯碼,加深對指標的理解,這種方法同樣適合學別的編程方面的知識。

  四、結束

  指標的應用是很廣泛的,利用指標可以做很多事情,要成為一個好的程式員,必須對指標有比較深刻的瞭解。寫本文的目的在於讓大家對指標有更深一層的瞭解,提高指標的應用能力,內容大都是我在實際編程中遇到的問題。相信能給大家一定的協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.