C語言初級階段7——指針1
地址與指針
1.地址:數據在內存中的存儲位置編號,是一個常量。
2.指針:指針的本質就是地址。
指針變量的定義和聲明
1.指針變量:存儲的數據是地址。
2.定義方法:類型*標識符
3.得到變量的地址:&
4.指針變量取了誰的地址,就指向誰。
5.*的作用:指針變量的標志
6.*:取內容,解引用
7.指針變量所占內存:一律占四個字節內存
8.注意:定義指針的時候,要馬上給指針變量賦值,防止出現野指針(沒有任何指向)。
9.NULL:空
10.數組名本身就表示是這個數組的首地址。
11.p += 8;指針的偏移。
12.指針也是有類型的,指針的類型就是定義的時候 類型*變量
13.產生野指針的幾種情況
(1)定義一個指針變量時沒有初始化
如:int *p;
都知道我們在定義一個非指針的變量時如果沒有初始化,則這個變量的值是隨機的(如:int a;)
指針變量同樣如此,指針變量的隨機值的意思就是說他指向的位置是隨機的
(2)動態開辟的內存空間在使用完后調用free函數釋放掉這段內存空間,卻沒有將對應的指針職位NULL。雖然開辟的空間被釋放掉但指針依舊存在。
如:int func()
{
int *p = malloc(sizeof(int));
free(p);//沒有將p值為NULL的操作
}
(3)對指針的操作已經超出了指針變量的作用域
比如通常我們實現了一個函數,該函數里創建了一個指針變量,而函數結束時最終返回這個指針變量,但是函數調用結束后,該函數的函數棧幀就會被銷毀,所以返回的這個指針變量所指向的空間已經被釋放了,因此這個指針變量指向的空間就變成了隨機的。
14.野指針的危害
(1)指向不可訪問的地址
危害:觸發段錯誤。
(2)指向一個可用的,但是沒有明確意義的空間
危害:程序可以正確運行,但通常這種情況下,我們就會認為我們的程序是正確的沒有問題的,然而事實上就是有問題存在,所以這樣就掩蓋了我們程序上的錯誤。
(3)指向一個可用的,而且正在被使用的空間
危害:如果我們對這樣一個指針進行解引用,對其所指向的空間內容進行了修改,但是實際上這塊空間正在被使用,那么這個時候變量的內容突然被改變,當然就會對程序的運行產生影響,因為我們所使用的變量已經不是我們所想要使用的那個值了。通常這樣的程序都會崩潰,或者數據被損壞。
15.避免方法
(1)定義一個指針變量時一定記得初始化
(2)動態開辟的內存空間使用完free之后一定將對應的指針置為NULL
(3)不要在函數中返回棧空間的指針和引用
(4)注意在使用時對指針的合法性的判斷
#include<stdio.h>
int main() {
int a = 10;
float b = 1.1f;
int* p = &a;
return 0;
}
#include<stdio.h>
int main() {
int a=10, b=20, c=30;
int* p1, * p2, * p3;
p1 = &a;
p2 = &b;
p3 = &c;
printf("%d\n", *p1);
int*a1=NULL;
float*a2=NULL;
double*a3=NULL;
char* a4;
printf("%d\n%d\n%d\n%d\n", sizeof(a1), sizeof(a2), sizeof(a3),sizeof(a4));
printf("%d\n%d\n%d\n%d\n",sizeof(*a1), sizeof(*a2), sizeof(*a3), sizeof(*a4));
return 0;
}
#include<stdio.h>
void fun(int* x, int* y)
{
*x = 3;
*y = 0;
}
int main() {
int a = 10, b = 20;
fun(&a, &b);
printf("%d\n%d\n", a, b);
return 0;
}
#include<stdio.h>
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (int i = 0; i < 10; i++)
{
printf("%p\n", &arr[i]);
}
int *p = arr;
printf("%d\n", *p);
p += 8;//等價于p = &arr[9]
printf("%d\n", *p);
return 0;
}
#include<stdio.h>
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (int i = 0; i < 10; i++)
{
printf("%p\n", &arr[i]);
}
int *p = arr+4;//指針的偏移
printf("%d\n", *p);
return 0;
}
#include<stdio.h>
#include<string.h>
int main() {
//常量字符串
const char * p1 = "Hello World";//正常可以去掉const但是VS2022需要加不然報錯
printf("%d\n", sizeof(p1));
printf("%d\n", strlen(p1));
p1 += 4;
printf("%c\n" , *p1);
return 0;
}
#include<stdio.h>
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
double* p2 = (double*)&arr[0];
p2++;
printf("%d\n", *((int*)p2));
char* p4 = (char*)&arr[0];
p4 += 4;
printf("%d\n", *((int*)p4));
printf("%d\n", *((int*)p2));
return 0;
}
浙公網安備 33010602011771號