淺析c/c++中的指標

來源:互聯網
上載者:User

在學習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返回了正確的結果的地址。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.