C 中的指標

2021-04-03 01:19:52 字數 4033 閱讀 6362

在學習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、 指標的應用——傳遞引數。

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

四、結束:

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

C 中的this指標

當乙個成員函式被呼叫時,自動向它傳遞乙個隱含的引數,該引數是乙個指向接 受該函式的呼叫的物件的指標,在程式中可以使用關鍵字this指標來引用改制鎮,因此稱該指標為this指標。this指標是c 實現封裝的一種機制,它將成員和用於操作這些成員的成員函式聯絡在一起。例如 location類的成員函式in...

C 中的this指標

1.this 指標的引入 每個成員函式 static函式外 都有乙個額外的隱含的this指標,乙個類物件在條用成員函式時this指標初始化為呼叫函式物件的位址。例1 sales item.h class sales item sales item.cpp bool sales item same i...

C 中的This指標

c 中使用this指標來指向用來呼叫成員函 數的物件。乙個物件 的this指標並不是物件本身的一部分,不會影響sizeof 物件 的結果。this 作用域是在類內部,當在類的非靜態成員函式中訪問類的非靜態成員的時候,編譯器會自動將 物件本身的位址作為乙個隱含 引數傳遞 給函式。也就是說,即使你沒有寫...