【C语言】全面解析指针,指针知识点整理
目錄
前言:
1.指針的概念
2.指針的類型
3.野指針
3.1野指針的成因:
?3.2如何避免野指針?
4.指針的運算
5.指針和數組
6.二級指針
7.指針數組
總結:?
?
前言:
對C語言來說,指針是一個難點,如果用C語言來寫數據結構的話,掌握指針的用法是必須的,如果指針沒學好,學數據結構很吃力。所以希望大家一定要掌握指針啊!!!
1.指針的概念
1.指針就是個變量,用來存放地址,地址唯一表示一塊內存空間。
ps:(內存編號 = 地址 = 指針)
2.指針的大小是固定的4/8個字節(32位平臺/64位平臺)
2.指針的類型
指針是有類型的,指針的類型決定了指針+-整數的步長,指針解引用時候的權限。
下面我來解釋一下上面的紅色部分的意思,舉個例子,看一下下面的代碼及運行結果:
#include<stdio.h> int main() {int a = 4;int* p1 = &a;char* p2 = &a;printf("%p\n", p1);printf("%p\n", p2);printf("%p\n", p1+1);printf("%p\n", p2+1);return 0; }?剛開始p1和p2地址是一樣的,但后面讓p1和p2分別進行+1,后面的結果就不同了,p1加的1是int類型的1,而p2+1加的是char類型的1。
上面我們說到指針的大小是固定的4/8個字節,假設是32位平臺,那么一個指針就占4個字節。如果這時我定義一個整型指針和字符指針,那么這個整型指針在解引用時就可以訪問4個字節,而字符指針就只能訪問1個字節。
3.野指針
野指針的概念就是:指針的位置是不可知的
3.1野指針的成因:
野指針的成因有兩個:1.指針未被初始化? ?2.指針的越界訪問
給大家解釋一下:
指針未被初始化
這個應該很好理解,就是我們在創建指針變量的時候沒有讓它指向任何對象
例如: int* p;? ?這樣p就是一個局部變量,p就是一個隨機值?
指針的越界訪問
看一下下面的代碼:
#include<stdio.h> int main() {int arr[5] = { 1,2,3,4,5 };int* p = arr;int i = 0;for (i = 0; i < 6; i++){printf("%d ", *p);p++;}return 0; }先給大家解釋一下這個代碼的原理,int* p = arr; 這里arr是數組名,數組名是首元素的地址
那么現在p就是首元素的地址? 對p進行解引用就是*p ,*p的值就是 1
p++;? 這行代碼就是讓p的地址++;指針的大小是固定的4/8個字節, int型數據在C語言中也是4/8個字節,我們拿到的指針都是數據第一個字節的地址,而數組在內存中又是連續的,p++就是剛好往后移動一個數據。
但是現在arr數組一共就只有5個元素,但是循環6次必然會導致數組的越界,那我們來看一下運行結果
前面5個數就是arr數組里面的數,第6個值就是一個隨機值。因為當循環到第6次時,p已經沒有指向的對象了,此時p就是一個野指針了。
?3.2如何避免野指針?
1.善于使用NULL,及時對指針進行初始化
如果你在定義指針變量的時候,就已經想到指針變量指向的對象,那就直接進行初始化。
如果你在定義的時候,還不清楚指針指向的對象,也不清楚后面要不要使用指針,那就對指針變量賦值為NULL? ?
NULL就是空的意思,如果int *p=NULL; 那么此時p就是一個空指針,后面可以重新賦值,并不影響后面的使用。如果一個指針是空指針,在你還沒初始化前不要使用它。
2.避免指針的越界
3.避免返回局部變量的地址
4.指針的運算
看下面這段代碼:
#include<stdio.h> int main() {//指針地址加減整數int arr[5] = { 1,2,3,4,5 };int* p1 = arr;int i = 0;for (i = 0; i < 5; i++){printf("%d ", *p1);p1++;}printf("\n");//解引用后的指針加減整數int b = 10;int* p2 = &b;(*p2)++;printf("%d", *p2);return 0; }p1++是對地址進行加減整數,上面已經介紹過了,現在就不過多介紹了
而(*p2)++, 我是定義了一個b變量,然后賦值給了10,然后把b的地址給了p2,*p2通過解引用得到的就是10,(*p)++? 相當于 10++ ,得到的就是11.
看一下運行結果:
?ps:指針可以比較大小
指針還可以減指針
舉個例子:
#include<stdio.h> int main() {int arr[5] = { 1,2,3,4,5 };printf("%d", &arr[4] - &arr[0]);return 0; }這里沒用指針變量相減,其實是一樣的。畢竟指針就是地址。
兩個指針指向同一塊空間時,指針減指針的絕對值得到的就是這兩個指針之間數據的個數。
注意這個不是 個數*數據類型的大小?C語言規定的
5.指針和數組
1.數組是可以通過指針來訪問的,可以參考我上面寫的代碼。
2.通常情況下 數組名是首元素的地址?
但凡事都有例外:
????????1.sizeof(數組名)? 得到的是整個數組的大小?
????????2.&+數組名 這里取出的是整個數組的地址。
3.在進行函數傳參時,如果形參是數組,可以把形參設計成指針,當然如果形參是數組,也可以傳指針作為實參。
6.二級指針
二級指針就是用來存放一級指針(指針變量)的地址。
#include<stdio.h> int main() {int a = 5;int* pa = &a;int** ppa = &pa;return 0; }此時pa是一級指針,ppa就是二級指針,ppa是把pa的地址取出來放在ppa里面
**ppa就是*pa找到pa,在對pa進行解引用找到a
7.指針數組
指針數組的定義:int* 數組名[大小]??
指針數組的用法:
#include<stdio.h> int main() {int arr1[3] = { 1,2,3 };int arr2[3] = { 4,5,6, };int* arr3[2] = {arr1,arr2};int i = 0;int j = 0;for (i = 0; i < 2; i++){for (j = 0; j < 3; j++){printf("%d ", *(arr3[i] + j));}printf("\n");} }對指針數組可以模擬是實現二維數組,arr[i]里面存放的是arr1和arr2的地址。+j是獲得每一位數組元素的地址,在來*解引用拿到里面的值。輸出那個地方也可以換成??printf("%d ", arr3[i][j]);效果是一樣的。
總結:?
指針真的很重要!指針真的很重要!指針真的很重要!(重要的事情說三遍)一定要掌握
希望這篇文章可以幫到你 (水平有限,如果有問題,歡迎大佬指正!感謝!)
?
總結
以上是生活随笔為你收集整理的【C语言】全面解析指针,指针知识点整理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: dropzonejs vue 使用_可能
- 下一篇: ubuntu15.10下安装wifi破解