c語言基礎 指標詳解

2021-08-23 14:36:26 字數 4387 閱讀 2219

目錄

一、理解指標

二、指標變數的宣告及初始化

三、通過指標訪問變數

四、指標鏈(指向指標的指標)

五、指標表示式

六、指標的遞增與比例因

七、指標與陣列和字串

1、指標與陣列

2、指標與字串

3、指標陣列

八、指標與函式

1、將指標作為函式的引數

2、函式返回指標

3、指向函式的指標

九、指標與結構體

當我們宣告乙個變數時,系統會在記憶體中分配適當的儲存空間,以儲存該變數的值,由於每乙個位元組都有唯一的位址編號,因而記憶體儲存空間都有自己的位址編號。又由於記憶體位址只是編號,因而又可以把它複製給變數,這種儲存位址的變數就稱為指標變數

我們並不關心指標的實際值,因為每次執行時,指標的值都會發生變化的(每次執行意味著變數重新分配位址)。

我們不能直接儲存位址的值,只能利用位址運算子(&),通過儲存在位址中的變數來獲得位址的值。位於變數之前的位址運算子(&)將可返回該變數的位址。運算子&只能用於單個變數或陣列元素。

int *p; //integer pointer  把變數p宣告為指標變數,指向整型資料
把變數的位址賦值給指標變數的過程稱為指標變數的初始化。

必須確保指標總是指向相應的資料型別。

指標可以初始化給變數,null,零。

指標很靈活,我們可以在不同的語句中使用同一指標指向不同的資料型別,也可以使用不同的指標指向同一資料變數。

我們可以用間接運算子『*』(反引用運算子)來實現對指標變數的值的訪問。 例如:

int quantity, *p, n;

quantity = 179;

p = &quantity;

n = *p;

故n==179。 特別注意:

*ptr = 25;
該語句把值25存放在位址等於ptr的值的記憶體中。

指向指標的指標變數必須在名稱的前面新增額外的間接運算子。例如:

int **p2;
該宣告語句告訴編譯器 p2 是指向int型別的指標的指標。

關於指標所指變數的值的表示式;例如:如果p1和p2都是宣告並初始化了得指標,那麼下面的語句是合法的:

y = *p1 * *p2; //第二個 * 是運算符號

sum = sum + *p1;

z = 5* - *p2/*p1;

*p2 = *p2 + 10;

關於關於指標的表示式 c語言允許對指標與整數進行運算;也可以在兩個指標之間進行減法運算。例如:

p1 - 2;

p1 - p2;

如果 p1 和 p2 指向相同的陣列,那麼p2-p1將給出p1與p2之間的元素數目(p1/p2、p1*p2、p1/3)。指標不能用於除法或乘法運算(p1+p2);類似地,不能對兩個指標進行加法操作。

還可以使用關係運算子進行指標的的比較。諸如p1 > p2、 p1 == p2和p1 != p2都是允許的。但是,指向不同或無關聯變數的指標間的比較沒有意義。比較可以用於處理陣列和字串。

在指標進行遞增時,所增加的值為該指標指向資料型別的「長度」。這種長度就稱為比例因子(scale factor)。例如:如果p1為整形指標,初始值為2800,那麼經過p1 = p1 + 1運算後p1的值為2802,而不是2801。

當宣告數時,編譯器在連續的記憶體空間分配基本位址和足夠的儲存空間,以容納陣列的所有元素。基本位址是陣列第乙個元素(索引為0)的儲存位置。編譯器還把陣列名定義為指向第乙個元素的常量指標。

如何表示元素a[i][j]的(其中:int *p; p = a;);01

2345

1234

int a[3][4] =,

,}

陣列a的儲存如下:

|15 |27| 11| 35 |22 |19 |31 |17 |31 |23 |14 |36 | |--

如果把 p 宣告為整型指標,並且初始位址為a[0][0](),那麼:

a[i][j] = *(p+4*i+j);
c語言支援另一種建立字串的方法,即使用char型別的指標變數。例如:

char *str = "good";
|g(str) | o | o | d | \0 | |--

由此,可以用指標訪問整個字串:

printf("%s",str);

put(str);

當然,也可以用指標來訪問字串中的單個字元。

指標的一項重要的應用就是處理字串表,特別是處理行的長度可變的「凹凸不平的陣列」時;例如:

char *name[3] = ;
上面的宣告語句只分配了28個字元,這足以儲存所有的字元,具體如下:

|n| e |w | |z |e |a |l |a| n| d| \0| |-- |a| u| s| t| r| a| l| i| a| \0| |i| n| d| i| a| \0| 下面的語句可以用來顯示著三個名稱:

for(i = 0; i <= 2; i++)  printf("%s\n",name[i]);
要訪問第 i 個名稱的第 j 個字元,可以這樣編寫語句:

char c = *(name[i]+j);
使用指標傳遞變數位址的函式呼叫過程稱為引用呼叫(我們已經說過,傳遞變數實際值的過程稱為 「按值呼叫」)。引用呼叫提供了一種機制,讓被呼叫的函式可以修改呼叫函式中儲存的值。 請注意以下**:

/例一

void exchange(int *a, int *b)

void main()

//例二

void exchange(int *a, int *b)

void main()

**例二並不會使x,y的值發生互換,因為當函式指標a,b獲得x,y的位址後,作為值進行儲存,交換a,b的值並沒有改變其值(x,y的位址)指向的x,y的值。

指標是c語言的一種資料型別,因此也可以使用函式返回乙個指向呼叫函式的指標。請看下面的**:

int  *larger(int* , int*);/*prototype*/

int main()

int *larger(int *x, int *y)

與變數一樣,函式也屬於某種資料型別,在記憶體中也需要有儲存位址。因此可以宣告乙個指向函式的指標。如同指向字元陣列的指標,可以接收任意大小的字元陣列一樣,指向函式的指標可以指向任意的函式,如此可以減少函式的數量,使函式的功能更加強大。指向函式的指標宣告如下:

type (*fptr)();
該語句告訴編譯器,fptr為指向函式的的指標,返回type型別的值。用括號把*fptr括起來是必要的。記住,下面的語句:

type *gptr();
表示的是把gptr宣告為函式,它返回乙個指向type型別的指標。

#include#include#define pi 3.1415926

double table(double (*f)(), double, double, double);

double y(double);

double cos(double);

double table(double (*f)(), double min, double max, double step)

}double y(double x)

void main()

在前面章節中,我們討論把結構體作為引數傳遞給函式。我們還看到這樣的例項,其中函式接收整個結構體的副本,並在執行後把他返回給呼叫函式。正如我們前面介紹的那樣,該方法無論是在執行速度還是在記憶體使用上都不是高效的。通過以指向結構體的指標作為傳遞引數,然後使用指標來操縱結構體成員,就可以克服該缺點。請看以下函式:

print_invent(struct *item)

該函式可以用下面的語句來呼叫:

print_invent(&product);
陣列名表示的是第0個元素的位址。結構體變數的陣列名也是如此;

運算子「->」、「.」、「()」和「」的有先級最高。正確理解優先順序及關聯性非常重要。

c語言指標詳解

一.指標的概念 指標是乙個特殊的變數,它裡面儲存的數值被解釋成為記憶體裡的乙個位址。要搞清乙個指標需要搞清指標的四方面的內容 指標的型別,指標所指向的型別,指標的值或者叫指標所指向的記憶體區,還有指標本身所佔據的記憶體區。1.指標的型別 從語法的角度看,你只要把指標宣告語句裡的指標名字去掉,剩下的部...

C語言指標詳解

類似於 int p char p 或者自定義型別的 person p struct p 這些都是基本的指標變數,不管什麼型別的指標變數都是乙個存位址的變數,所以它們的大小都是四個位元組 還有一種void p 型別,類似於 js 或者 c 的 var 可以傳入任何型別變數的位址,也可以轉換成任何型別變...

C語言指標詳解

c語言指標應用 一 指標是什麼 指標是乙個特殊的變數,它存的是記憶體裡的乙個位址。指標四要素 1.指標的型別 把指標名字去掉,剩下的部分就是這個指標的型別。這是指標本身所具有的型別如下 1 int p 指標的型別是int 2 char p 指標的型別是char 3 int p 指標的型別是int 4...