1指針的聲明
int *a;
int* a;
int* a,b,c //注 *號是*a的一部分,只對標識符有用,所以b和c只是整形變量
int *a,*b,*c;
//也可以指定初始值
char *msg = “hello world”; == char *msg; msg = “hello world”;
注意:hello world看起來是賦值給 *msg的,其實是賦值給 msg 的
2 間接訪問操作符
指通過指針訪問它指向的地址的操作,也叫解引用指針。
int a = 10;
int *b = &a;
printf(*b);
a是一個整形變量,b是一個指針變量,b指向a地址,當使用*b時,訪問的是b所指向的地址內存儲的數據,也就是a,所以*b=10。
3初始化和非法指針
int *a;
*a=12;
創建了一個名爲a的指針變量,然後把12放到a的地址中。
注意:我們並沒有初始化指針a,所以我們不知道a所指向的地址,如果變量是靜態的,那麼a會指向0,如果變量是自動的,根本不會被初始化,a爲一個非法地址。這樣的做法是錯誤。
4 NULL指針
null指針式一個特殊指針,它並不指向任何值。對一個NULL指針進行引用操作是非法的。
5 指針的指針
int a = 12;
int *b = &a;
int **c = &b;
b表示指向a的指針,**c可以表示爲*(*c),*c表示b指針的值,就是a的地址,**c表示的就是a的地址的值,就是12。
6 實例
求字符串的長度。
int strlen1(char *str){
int len = 0;
while(*(str++) != '\0'){
len++;
}
return len;
}
查找字符
int find_char1(char *str,char c){
while(*(str++) != '\0'){
if(c==*str){
return 1;
}
}
return 0;
}
7 指針運算
當一個指針跟一個整數進行算術運算時,整數會根據指針類型進行動態調整。比如:
float *a = 3.14;
a = a + 1; //float佔4個字節,a+1的時候,會根據字節長度,調整爲 1*4實際上就是,
// a+4
所以,char類型的指針加1,就是指向下一個char,而float類型,就指向下一個float。
注意:指針的運算僅限於加減兩種。
8函數指針
1. 初始化函數指針
int f(int);
int *(pf)(int) = &f; // int *(pf)(int) = f;
這裏聲明瞭一個函數指針,*pf(int)通過賦值初始化,在函數指針初始化的時候,函數原型很重要,因爲編譯器要檢查函數指針的類型。
&操作符不重要,int *(pf)(int) = f; 編譯器在編譯的時候會自動加上&符號。
可以這麼調用
int a = f(25);
int b = *(pf)(25)
int c = pf(25);
第一行的執行過程是,函數名首先會轉換爲一個函數指針,指向的是函數在內存中的位置。
第二行的操作是,先通過指針pf取出函數名,再通過函數名執行第一行的過程,所以這麼寫是沒必要的。
第三行直接通過函數指針進行調用。
2. 回調函數
函數指針可以作爲回調函數參數,傳遞到函數中。