---恢復內容開始---
一.運算子 &
• scanf(「%d」, &i);裡的&
• 獲得變數的位址,它的運算元必須是變數
• int i; printf(「%x」,&i);
• 位址的⼤大小是否與int相同取決於編譯器
• int i; printf(「%p」,&i);
• &不能對沒有位址的取位址
• &(a+b)?
• &(a++)?
• &(++a)?
二.指標初識
• 就是儲存位址的變數
int i;
int* p = &i;
int* p,q;
int *p,q;
指標變數
• 變數的值是記憶體的位址
• 普通變數的值是實際的值
• 指標變數的值是具有實際值的變數的位址
試試這些&
• 變數的位址
• 相鄰的變數的位址
• &的結果的sizeof
• 陣列的位址
• 陣列單元的位址
• 相鄰的陣列單元的位址
取陣列的位址
我們可以看到,&a==a==&a[0];而int陣列中的每個元素的位址永遠是相差4,也就是乙個sizeof(int)的大小
三.作為引數的指標
四.訪問那個位址上的變數*
• *是乙個單目運算子,用來訪問指標的值所表示的位址上的變數
• 可以做右值也可以做左值
• int k = *p;
• *p = k+1;
五.*左值之所以叫左值
• 是因為出現在賦值號左邊的不是變數,而是值,是表示式計算的結果:
• a[0] = 2;
• *p = 3;
• 是特殊的值,所以叫做左值
指標應用場景一
• 交換兩個變數的值
指標應用場景二
• 函式返回多個值,某些值就只能通過指標返回
• 傳入的引數實際上是需要儲存帶回的結果的變數
#include void minmax(int a,int len, int *max, int *min);int main(void);
intmin,max;
minmax(a,
sizeof(a)/sizeof(a[0]),&max,&min);
printf(
"min=%d,max=%d
",min,max);
}void minmax(int a,int len, int *max, int *min) //int a 就是指標,改成int *a也可以編譯成功
指標應用場景二b
• 函式返回運算的狀態,結果通過指標返回
• 常用的套路是讓函式返回特殊的不屬於有效範圍內的值來表示出錯:
• -1或0(在檔案操作會看到大量的例子)
• 但是當任何數值都是有效的可能結果時,就得分開返回了
• 後續的語言(c++,j**a)採用了異常機制來解決這個問題
#include //函式返回運算的狀態,結果通過指標返回
指標最常見的錯誤
• 定義了指標變數,還沒有指向任何變數,就開始使⽤指標
傳⼊入函式的數組成了什麼
• 函式引數表中的陣列實際上是指標
• sizeof(a) == sizeof(int*)
• 但是可以用陣列的運算子進行運算
六.陣列引數
• 以下四種函式原型是等價的:
• int sum(int *ar, int n);
• int sum(int *, int);
• int sum(int ar, int n);
• int sum(int , int);
七.陣列變數是特殊的指標
• 陣列變數本⾝身表達位址,所以
• int a[10]; int*p=a; // 無需用&取位址
• 但是陣列的單元表達的是變數,需要用&取位址
• a == &a[0]
• 運算子可以對陣列做,也可以對指標做:
• p[0] <==> a[0]
• *運算子可以對指標做,也可以對陣列做:
• *a = 25;
• 陣列變數是const的指標,所以不能被賦值
• int a <==> int * const a=… .
八.指標與const (c99 only)
指標是const
• 表示一旦得到了某個變數的位址,不能再指向其他變數
• int * const q = &i; // q 是 const
• *q = 26; // ok
• q++; // error
所指是const
• 表示不能通過這個指標去修改那個變數(並不能使得那個變數成為const)
• const int *p = &i;
• *p = 26; // error! (*p) 是 const
• i = 26; //ok
• p = &j; //ok
int i;
const int* p1 = &i; //指標所指不能修改
int const* p2 = &i;//指標所指不能修改
int *const p3 = &i; //指標不可修改
判斷哪個被const了的標誌是const在*的前面還是後面
轉換
• 總是可以把⼀乙個非const的值轉換成const的
void f(const int* x);
int a = 15;
f(&a); // ok
const int b = a;
!f(&b); // ok
b = a + 1; // error!
• 當要傳遞的引數的型別比位址大的時候,這是常用的手段:既能用比較少的位元組數傳遞值給引數,又能避免函式對外面的變數的修改
const陣列
• const int a = ;
• 陣列變數已經是const的指標了,這裡的const表明陣列的每個單元都是const int
• 所以必須通過初始化進行賦值
保護陣列值
• 因為把陣列傳入函式時傳遞的是位址,所以那個函式內部可以修改陣列的值
• 為了保護陣列不被函式破壞,可以設定引數為const
• int sum(const int a, int length);
---恢復內容結束---
C語言學習筆記 指標
若觸過組合語言,那麼理解學習c語言中指標就很簡單了。指標,在彙編裡面的表現形式,無非就是定址,直接定址和間接定址。先來學習下,c語言中的4大類資料型別 基本型別 int,long,float,char 構造型別 陣列,結構體 struct,聯合體 union,列舉型別 enum 指標型別 int l...
C語言學習 指標(10 19)
1.p是位址的轉義字元 2.位址值是用十六進製制的無符號整數表示的,其字長一般與主機的字長相同。3.int pa pa是乙個指標變數,它指向乙個整形變數 是指標型別說明符 4.習慣上在定義指標變數的同時將其初始化為null,未被初始化意味著它的值是乙個隨機值,無法預知它指向 會給系統帶來潛在危險。5...
C語言學習筆記 指標
c語言要玩的好,指標是核心,但是指標在學習的時候看教程往往感覺一看就明白,但是實際用的時候一用就錯,而且還不知道錯在哪。為了更加深刻的了解指標,將學習過程記錄下來,依次加深對指標的理解。先看看一段測試 void fun void int main void 定義乙個變數a,值為100,然後定義乙個一...