指針的用法


指針是c語言的一個特色。

1 將地址形象的比喻為指針。

2 訪問的兩種形式:1 直接訪問:比如定義了變量a,然后通過變量名a直接訪問

      2 間接訪問:定義a,得知a的地址,由於地址指向變量,所以可以直接 訪問。

3 除了整型,實型,字符型,還有一種是存放地址的變量。Int * a;a= &p;

4 一個變量的地址我們稱之為指針;一個存放別的變量地址的變量叫做指針變量;指針變量的值就是指針(即地址);如果存放的指針指向的數據是整形,則我們說這個指針變量是指向整形變量的指針變量。

 

<重中之重>指針變量:1 程序中兩處 * :聲明與使用。

聲明: * 指示后面的變量是指針變量,且其基類型是前面的類型。

使用: * 運算符,把地址轉向所指向的變量。

 

  2可以在定義時同時對他進行初始化。

  3 必須指定基類型:因為他指代的數據類型有可能是int long 等等,而在后續要進行指針的加減,指針加一,如果是int 則增加24個字節,如果是long,則8個字節。所以一定要指定。

  4 賦給指針的變量一定是地址,而不能是其他數據類型。

  5 給指針變量賦值:1直接賦值 p=&a;

2 引用賦值 如果*p=1;之前必須p=&a;否則會因為不知道地址而有可能會占用有用的地址。

          6 注意指針變量也是一個變量,所以在指針變量的范疇內,各種變量的賦值都可以,就和變量一樣,而和普通變量交互,則需要有地址,有基變量。

 

<第一個重點>

重重重重:1 單向的值傳遞:即實參傳遞過去的形參,之后是形參來回變換,與實參無關。2 由於地址本身就存在,不存在什么變化,所以,只能夠通過地址指向的值來回改變。

          指針可以作為函數參數

要點:1(單向的值傳遞) 所有都要與之結合。

要點:2(址變換) 3(*址變換) 4(值變換)只有4不可以改變原值

重點:不可能通過調用函數來改變實參指針變量的值,但是可以實參指針變量所指向的值。

函數的參數不僅可以是整形,實數型,字符型,數組型,也可以是指針型。

他的目的是址傳遞。

 

<A>我們的問題是如何使原值改變。函數參數傳值,傳完之后回來,看是否原值改變。

以兩個數要變換為例。

首先采用(值傳遞),由於是單向傳遞,況且要想改變原數據,必須要從指針(地址)這方面下手,所以,即不可以改變原值;

然后是(址傳遞),由於傳過來之后,實參要賦給形參,而此時在變換函數(swap)形參來回變換,也就是實參不變換,而形參變換,所以沒用,且是單向的。所以不能改變原值。

然后是(*地址)傳遞,自己畫圖,實參傳過來之后,由於雖然還是改變形參,但是改變的是形參上對應的數字,即改變原地址上對應的數字,即可以改變原值。

 

 

 <誤區> 就是說以前雖然是值傳遞,但是值傳遞回來return之后賦給了新的變量,既然是新的變量,所以輸出了之后肯定是改變數據的,這就是產生錯覺的原因。

總結難點:1 單向的值傳遞:即實參傳遞過去的形參,之后是形參來回變換,與實參無關。2 由於地址本身就存在,不存在什么變化,所以,只能夠通過地址指向的值來回改變。

 

<第二個重點>:通過指針引用數組。

1 數組元素的指針就是數組元素的地址。

2 引用數組可以用下表法,也可以用指針法。

重:3 數組名(不包括形參的數組名)可以與首元素地址等價。即 int * p;p=ap=&a[0];

重:4 指針法   *a+i*(p+i);這兩者都是指向a[i]

5 指針運算:

1  首先指針運算的p++不是簡單地加一,而是根據變量類型的字節數去加一。如果是int 則可能是+2 +4,如果是float,則是+4

2  可以使用p++,因為他是變量,而不能使用a++,因為a是常量。

重:注意p+ia+i的區別,a+i是自身的地址直接加字節數,而p+i是把地址賦給另一個指針變量去進行加減。

6  寫程序時要注意此時指針的位置,因為就算超出,他實際上也不會報錯。

7  也可以使用p[i],但是注意此時一定要知道當前p在什么位置,如果一開始P指向a[2],p[3]則是a[5],所以不建議使用這種方式.

8 <重中之重>:用數組名做函數參數:

1  形參數組的值發生變化,實參也發生變化(注意:形參的值指的是指針的值而不是地址【上一節指針做參數的三種情況】)

重:2  void f(int arr[],int n)=====等價於void f(int * arr,int n);

3  指針變量在visual c++里占據4個字節。

4  實參數組名是一個常量,而形參數組名是一個變量,所以可以賦值,而常量不可以賦值即a=a+3(a是常量),不能使用,而(arr=arr+3)是可以的;

 

 

<第三個重點>:通過指針引用字符串

1 表示字符串的兩種方法:1 用字符數組2 用指針指向字符串的字符。

2 指針法:char * string=”I love china”; printf(“%s”,string);

3 不能夠重新賦值,因為字符常量是不能改變的。

重:4 實際上是把字符串的第一個字符的地址賦給指針變量,然后輸出會自加(這就是不用遍歷的原因),最后遇到\0會停止(這才是可以自加的真正原因吧,因為可以自動停止)。

重:5 為什么輸出地址就可以輸出字符?數組就需要*?

應該是編譯器的處理,因為字符數組即char a[]遍歷就需要*a.

6 輸出的時候還是用字符數組。

<重中之重>

1 傳遞參數可以用數組名,即地址,也可以用指針。

重:2 字符數組除了比數字數組多了一種方法,首先他倆同時都可以傳遞數組名和數組首地址,當然首地址是用另一個變量,並且由於他還可以這么定義char * string=”i love china”;所以還可以直接把string傳遞,其實本質是一樣的,都是地址,只不過編譯器對他進行了優化(遍歷,不用加*),所以其實都是一樣的。

 

實參形參的數組名與指針?

3 最后要自己加上\0;

4 最后就是寫法問題???

重:5作為實參,可以用數組名(不帶中括號),可以用char * p(其中p=a&a[0]),即變量;還可以用char * string=”aaaaaa”,直接把string傳入。當然,前兩種就是和數字數組是一樣的。即字符數組和數字數組基本上是一樣的,只不過多了一種寫法。

作為形參,本可以用數組名和指針變量,但是不知道為啥數組名行不通,暫且就是指針變量把。

6 字符數組可以再賦值,字符指針變量不可以。

 

 

重重重重:都是地址(基本上是一個,數組則是首地址)的傳入傳出,所以可以對原值改變。

重重重重:當想改變原值的時候,比如int a;在改變值的函數內部,一定要賦值,

舉個例子:#include<stdio.h>

 

int main(){

void change(int * m);

int a=10;

int *p;

p=&a;

change(p);

printf("%d",a);

return 0;

}

void change(int * m){

* m=* m+1;//注:這里一定要給*m賦值,之前的錯誤是只有*m+1,而沒有賦值,結果當然不會改變。

}

 

重重重重:字符型實參傳遞參數的形式:1 數組名 2 數組首地址 3 string 注:前兩種形式都是字符數組,最后一種是指針型字符數組。

字符型形參應該是 1 * 2 m[]:兩種都行,但是現在給第一種賦值遇到一些問題。

附代碼:#include<stdio.h>

int main()

{

void change(char * m);

char * string="Ia love China";

char a[19]="I love china";

//change(&a[0]);

change(string);

//傳遞參數的形式:1 數組名 2 數組首地址 3 string 注:前兩種形式都是字符數組,最后一種是指針型字符數組

//change(string);

printf("%s\n",a);

return 0;

}

void change(char  * m){

//形參應該是 1 * 2 m[]:兩種都行,但是現在給第一種賦值遇到一些問題。

*m='u';//這里現在遇到一些問題

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM