C語言指針原來也可以這樣了解
什么是指針
指針是應該對象,可以直接指向電腦存儲器中的某個地方,這個地方就是內存單元,指針指向的是一個對象的地址。地址的指向就是內存單元,一個內存單元是一個字節(jié),在32位平臺上面,一個指針是4個字節(jié)。因為32位的平臺有32根地址線,每根地址線是 1 bit,所以32位平臺的指針大小是 4 個字節(jié)。同理,64位平臺的指針大小就是 8 個字節(jié)。
指針的應用
指針用于指向某個對象的地址,也可以通過指針解引用來修改對象。
int main()
{
int a = 10;
int* p = &a;
printf("%d\n", *p); //10
return 0;
}
&a 就是把 a 的地址取出來。int* 說明 p 是指針變量,指向的對象是整型。所以 *p 指向的就是 a 的地址,打印出來也是10。因為 *p和 a 指向的是同一塊內存,所以對 *p修改也就是對 a 的值進行修改。
int main()
{
int a = 10;
int* p = &a;
*p = 20;
printf("%d\n", a); //20
return 0;
}
這里就是通過 *p 對 a 的值進行修改。
指針 ± 整數
指針 + 指針
指針指向的是一個對象。比如指針 + 1,就是指向后一個元素,拿數組舉例。
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n", *arr);
printf("%d\n", *(arr + 1));
printf("%d\n", *(arr + 2));
return 0;
}

從圖片可知,指針每次 + 1,都會指向數組的下一個元素。如果是對數組取地址再 + 1的話,就會跳過整個數組,指向整個數組后面的地址。所以使用指針加減和取地址加減的時候,一定要注意。
指針 - 指針
指針 - 指針算的是兩個指針之間的元素個數。
int my_strlen(char* s)
{
char* p = s;
while (*p != '\0')
p++;
return p - s;
}
int main()
{
char arr[10] = "abcdef";
int ret = my_strlen(arr);
printf("%d\n", ret); //6
return 0;
}
算的結果是 6,因為指針相減,得到了差的元素個數。
野指針
野指針就是指針執(zhí)行的位置使隨機的,是沒有被分配的內存空間。
野指針成因
野指針是由于指針未初始化,指針越界訪問造成的。野指針也是經常導致程序崩潰的原因。
指針未初始化
int main()
{
int* p;
*p = 20;
return 0;
}
這里的指針就沒有初始化,沒有初始化指向的內容,就是野指針,而且這里連編譯也完成不了。
指針越界訪問
指針越界訪問是一件非??膳碌氖虑?,會導致程序崩潰,程序死循環(huán)。
int main()
{
int i = 0;
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (i = 0; i <= 12; i++)
{
arr[i] = 0;
printf("haha\n");
}
return 0;
}
上面這個代碼就死循環(huán)了,因為指針越界訪問,造成了死循環(huán).這里是一個壓棧的情況造成的。用下面這張圖來解釋:

上面這張圖就描述了這個死循環(huán)的過程。
指針和數組
數組名其實表示的就是首元素的地址,傳參的時候傳數組名就等于是傳了數組的首元素地址。因為數組在內存當中是連續(xù)存儲的,所以只要把首元素地址傳過去就可以了。
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%p\n", &arr[0]);
printf("%p\n", arr);
return 0;
}

通過圖片就可以看出。
指針 ± 和數組的關系
當指針 ± 的時候,解引用指向數組的元素也在發(fā)生改變,+1,表示向后移動一個元素。
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
int* p = arr; //用指針來存放數組首元素的地址
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("&arr[%d] = %p <====> p+%d = %p\n", i, &arr[i], i, p + i);
}
return 0;
}
使用數組的時候,也可以換做指針來使用,看起來會整潔一些。
二級指針
因為指針變量也是變量,是變量就會有地址,那么指針變量的地址就可以用二級指針來描述。就是把一個變量的地址放在指針里面,然后再把指針的地址放在二級指針里面。所以就可以通過對二級指針解引用拿到一級指針的地址,對二級指針兩次解引用,就拿到變量的地址了。
int main()
{
int a = 10;
int* p = &a;
int** pp = &p;
printf("%p\n", a);
printf("%p\n", *p);
printf("%p\n", **pp);
return 0;
}

既然能拿到地址,那么對pp解引用之后修改,也就修改了a的值。
int main()
{
int a = 10;
int* p = &a;
int** pp = &p;
**pp = 20;
printf("%d\n", a);
return 0;
}

所以在使用二級指針的時候,也可以直接對變量進行修改。
總結
本篇文章就到這里了,希望能給你帶來幫助,也希望能夠您能夠關注腳本之家的更多內容!

