初探指針
- 指針概念
- 指針和指針類型
- 指針類型意義
- 野指針
- 如何避免
- 指針運算
- 指針+-整數
- 指針-指針
- 指針的關系運算
- 指針和數組
- 二級指針
- 指針數組
指針概念
- 指針是內存中一個最小單元(1個字節)的編號,也就是地址
- 平時口語中說的指針,通常指的是指針變量,是用來存放內存地址的變量
int a = 10; //在內存中開辟空間,a是整型變量,占用4個字節的內存空間
int* p = &a; //使用&操作符,取出a的第一個內存單元地址,存放在指針變量pa中,pa的類型是int*
在32位的機器上,地址是32個0或者1組成二進制序列,那地址就得用4個字節的空間來存儲,所以
一個指針變量的大小就應該是4個字節
那如果在64位機器上,如果有64個地址線,那一個指針變量的大小是8個字節,才能存放一個地址
總結:
指針變量是用來存放地址的,地址是唯一標示一塊地址空間的
指針的大小在32位平臺是4個字節,在64位平臺是8個字節
指針和指針類型
指針的類型:char*、short*、int*、long*、……
指針類型意義
指針類型的意義1:
指針類型決定了指針在被解引用的時候訪問幾個字節
如果是int*的指針,解引用訪問4個字節,如果是char*的指針,解引用訪問1個字節
指針類型的意義2:
指針類型決定了指針±操作的時候,跳過幾個字節,決定了指針的步長
010FFE20 - 010FFE1C = 0x04
0減C,向高位借1,因為是16進制,所以就是16+0=16,16-12?=0x04,就是10進制的4
野指針
概念:野指針就是指針指向的位置是不可知的(隨機的、不正確的、沒有明確限制的)
如何避免
- 指針初始化
- 小心指針越界
- 指針指向空間釋放即使置NULL
- 避免返回局部變量的地址
- 指針使用之前檢查有效性
指針運算
指針±整數
#define N_VALUES 5
float values[N_VALUES];
float *vp;
//指針+-整數;指針的關系運算
for (vp = &values[0]; vp < &values[N_VALUES];)
{
*vp++ = 0;
}
*vp++*vp然后vp++雖然后置++的優先級高,但是后置++是先使用,后++
(vp)++是vp指向的內容++
指針-指針
指針-指針得到的是指針和指針之間的元素的個數
不是所有的指針都能相減,指向同一塊空間的2個指針才能相減
指針的關系運算
for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--)
{
*vp = 0;
}
實際在絕大部分的編譯器上是可以順利完成任務的,然而我們還是應該避免這樣寫,因為標準并不保證
它可行。
但是標準規定:
允許指向數組元素的指針與指向數組最后一個元素后面的那個內存位置的指針比較,但是不允許與
指向第一個元素之前的那個內存位置的指針進行比較。
指針和數組
數組名代表首元素的地址,除了
1.sizeof(數組名),計算整個數組的大小,sizeof內部單獨放一個數組名,數組名表示整個數組
2.&數組名,取出的是數組的地址,&數組名,數組名表示整個數組
二級指針
指針變量也是變量,是變量就有地址,那指針變量的地址存放在二級指針中
對ppa解引用*ppa得到的是pa的值,再解引用**ppa得到的是a的值
指針數組
是數組,是存放指針的數組,存放的類型是int*
#include <stdio.h>int main()
{int a = 1;int b = 2;int c = 3;int* pa = &a;int* pb = &b;int* pc = &c;int* parr[10] = { &a, &b, &c };int i = 0;for (i = 0; i < 3; i++){printf("%d ", *(parr[i]));//1 2 3}return 0;
}
模擬出二維數組
#include <stdio.h>int main()
{int arr1[4] = { 1, 1, 1, 1 };int arr2[4] = { 2, 2, 2, 2 };int arr3[4] = { 3, 3, 3, 3 };int* parr[4] = { arr1, arr2, arr3 };int i = 0;for (i = 0; i < 3; i++){int j = 0;for (j = 0; j < 4; j++){//printf("%d ", *(parr[i] + j));printf("%d ", parr[i][j]);}printf("\n");}return 0;
}
*(parr[i] + j) 和 parr[i][j]是等價的