C语言——指针详解(必收藏)
目錄
1.什么是指針?
1.1概念
1.2指針的大小
??1.3指針類型的作用
2.野指針?
2.1野指針產生的原因
2.2 如何規避野指針
3.指針運算?
3.1指針+-整數
3.2指針-指針
3.3 指針的關系運算?
4. 二級指針
5. 數組名
*6.指針數組和數組指針?
6.1指針數組
*6.2數組指針?
?6.3舉例區別含義
7.數組參數和指針參數
7.1數組參數
7.2指針傳參
8.函數指針?
9.函數指針數組
9.1指向函數指針數組的指針
*10.回調函數
1.什么是指針?
1.1概念
簡單的來說,指針就是地址。我們口頭上說的指針其實指的是指針變量。指針變量就是一個存放地址的變量。
1.2指針的大小
?指針在32位機器下是4個字節,在64位機器下是8個字節。注:(指針的大小與類型無關)
?
?1.3指針類型的作用
上面涉及到指針的大小與指針類型無關,那么指針類型的作用是什么呢?
指針解引用訪問,使用的訪問權限是多少? ? 話不多說,上圖!
當一個int* 的指針+1,跳過4個字節;當一個char* 的指針+1,跳過1個字節。
同理,對于(指針+-整數)類的題也是如上的原理。
2.野指針?
野指針顧名思義,指針指向的位置不可知,就像沒有主人的流浪狗。
2.1野指針產生的原因
指針未被初始化
指針越界訪問
指針指向的空間釋放
對于前兩點比較好理解,下面對第三點進行解釋:
int* test( ) {int a = 5;return &a; } int main() {int* p = test();*p = 10;return 0; }變量a的地址只在test()函數內有效,當把a的地址傳給指針p時,因為出了test函數,變量a的空間地址釋放,導致p變成了野指針。
2.2 如何規避野指針
3.指針運算?
3.1指針+-整數
此部分內容跟指針類型那部分一致
3.2指針-指針
指針-指針的絕對值指的是兩個指針之間元素的個數。
前提:兩個指針必須指向同一空間
例如:&arr[9]-&arr[0]?
下面舉個例子實現my_strlen函數
int my_strlen(char str[]) {char* p = str;int count = 0;while (*p != '\0'){p++;count++;}return count; }int main() {char arr[] = "abcdef";printf("%d\n",my_strlen(arr));return 0; }3.3 指針的關系運算?
此部分內容很簡單,指針與指針之間比較大小就是指針的關系運算。
例如:定義int* p1,數組int arr[5],p1>&arr[5]。
但是要遵循一個標準:允許指針指向數組元素和指針指向數組最后一個元素后面的位置進行比較,不允許指針指向數組元素與指針指向數組第一個位置的前面進行比較。
4. 二級指針
二級指針就是存放指針地址的指針變量。就像有三個抽屜第一個抽屜的鑰匙放在第二個抽屜,第二個抽屜的鑰匙放在第三個抽屜。
例如:int a=10;int* p1=&a;int** p2=&p1;
對int* * 做解釋:第一個*號代表指針指向的類型是int*的,第二個*代表這個是指針。
5. 數組名
數組名大家都很熟悉,但要區分以下幾種情況:
其他情況數組名都表示數組首元素地址。
*6.指針數組和數組指針?
6.1指針數組
定義:存放指針的數組(int* arr[])。我們知道有整型類型的數組int arr[],還有字符類型的數組char arr[],指針數組就是指針類型的數組。
以下舉個例:
*6.2數組指針?
?6.3舉例區別含義
- int arr[5]? ? ? ? ? ? ? ?//名為arr的數組,數組里有5個元素,每個元素是int
- int* p1[5]? ? ? ? ? ? ? //指針數組,數組里有5個元素,每個元素是int*
- int (*p2)[5]? ? ? ? ? ? //數組指針,一個指向數組(里面有五個元素,每個元素是int)的指? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 針
- int (*p3[5])[5]? ? ? ? //p3[5]是一個有5個元素的數組,數組里每個元素是int(*)[5]
7.數組參數和指針參數
7.1數組參數
- 一維數組傳參:?int arr[10](形參部分數組大小可以不寫)、int* arr
- 二維數組傳參: int arr[3][5]、int arr[][5](行可以省略,列不能)、int (*arr)[5]? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 不能直接傳數組名,二維數組的首地址是第一行元素的首地址
7.2指針傳參
- 一級指針傳參:int* p
- 二級指針傳參:int** p
8.函數指針?
?**對下面代碼的理解:
(*(void(*)())0)()? ? ? ? ? ? ? ? ? ? ? ? ? ? //? ?將0處強制類型轉換為函數指針類型,再對0地址? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?進行調用
void(*signal(int,void(*)(int)))(int)? ? ? ??//這是函數的聲明,singal是一個函數,傳進去兩個? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數的類型是int和void(*)(int),signal函數的返回值? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 類型是void(*)(int)。
9.函數指針數組
9.1指向函數指針數組的指針
1.定義:int (*(*parr)[4])(int? int)=&parr
*10.回調函數
- qsort()函數:?是一個庫函數,基于快速排序算法實現的一個排序的函數。優點是,任意類型的數據都能排序。
- qsort()函數的形參定義:
void qsort(void* base(起始地址),size_t num(元素個數),size_t width(一個元素的字節長度),int (*cmp)(const void* e1,const void* e2)(自定義比較函數))
- qsort()函數應用:模擬計算器,排序結構體
總結
以上是生活随笔為你收集整理的C语言——指针详解(必收藏)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2021年广西高考成绩查询方法,2021
- 下一篇: [原]Jenkins(十二)---jen