指針:
一、聲明 一個 int 類型的 指針 然後 賦值。

二、聲明中直接賦值。

三、空指針

四、懸空指針 野指針:


懸空指針本質上就是 聲明了一個 指針類型的變量【如:int *p】,並且沒有賦值。在沒有賦初值的情況下,利用這個指針進行修改【如:*p=100】。就相當於這個指針指向了一個未知的地址。並且還做了修改。那如果這個地址是其他進程。還做了修改,就會造成系統的不穩定。因為這種不可靠的修改行為極其可怕,就好像呂伯奢開放了自己家給曹操,曹操進來以後胡亂的修改呂伯奢家人的數據,把是否存活全都置成了false.在dos版本的操作系統下,這種修改行為還是可以的。但是隨著後來越來越多的黑客想要修改操作系統的數據,就相當於我操作系統很大度,開放了我自己給你,你運行了一些東西,讓我這個操作系統土崩瓦解了。所以後來的操作系統做成了如下圖的樣子:

也就是隨著後來越來越多的這種可怕行徑,導致後來的法律發現如果你越界訪問的話,我們就認定你是非法入室罪名。就是有一個進程不斷地檢測,如果 有用戶進程非法訪問,就立刻把這個進程從內存中清楚,以保護操作系統的穩定。所以我們現在 是可以放心做這種懸空指針的案例演示的,不過就是 我們的進程遇到了問題,被迫中止而已。這是可以接受的。
五、指針的兼容問題

以下代碼:
#include <iostream>
void function1(void);
void function2(void);
void function3(void);
void function4(void);
void function5(void);
int main() {
function5();
return 0;
}
/**
聲明 一個 int 類型的 指針 然後 賦值。
*/
void function1(void){
int i= 10;
printf("修改前i的值為:%d\n",i);
int *p;//定義一個 執行int 類型的指針 變量名為p.
p = &i;//取i的地址 賦給 p。
*p = 100;//*p表示:訪問p中的內容,根據int 這個類型,來提取這個元素。
//又因為剛剛給這個裡面賦了i這個值 ,所以*p 相當於i。那麼i=100.
//所以 *p = 100 本質上是一個賦值語句,將i的值改成了100.
printf("修改後i的值為:%d\n",i);
}
/**
聲明中直接賦值。
*/
void function2(void){
int i =10;
int *p = &i;
printf("i的值為:%d\n",*p);
}
/**
空指針
*/
void function3(void){
//int b = NULL;
//printf("b的值為:%d\n",b);
int *p = NULL;//這就是傳說中的空指針,在java中報了錯比較常見這個東西的,
//就是因為在創建對象的時候,沒有給定一個初值,導致 報了那樣一個異常
printf("指針p的值為:%d,%p,%x",p,p,p);
}
/**
懸空指針,野指針 :其實 跟function1()的內容有相像的地方,就是聲明一個指針類型的變量,但是不賦值。
這個 編譯是可以通過的,但是運行的時候會報錯。在visual studio c++ 裡面編譯通不過。
這是因為。誰也不知道 到底讓p指向了一個什麼樣的內存單元。並且在不知情的情況下還給 它賦了100這個值,
那這樣就會極其不安全。
*/
void function4(void){
int *p;
*p = 100;
printf("懸空指針指向的地址的值是:%d\n",*p);
}
/**
指針的兼容問題
*/
void function5(void){
//前面在第一個案例的時候有特意提到聲明了一個 int類型的指針變量,是因為除此之外還有各種類型的指針變量。
//比如:
char *pc;
int array[10];
int *p =array;//這個我現在有點兒蒙。。。
double *pd;
//也就是我們說的,先去找到那個對應的元素然後按照 char 類型取pc裡面的內容
//按照double類型,取pd裡面的值
//所以對於指針來說 他們的大小都一樣:
printf("指針變量pc的大小:%d\n指針變量p的大小%d\n指針變量pd的大小%d\n",sizeof(pc),sizeof(p),sizeof(pd));
//【查看運行結果圖】,會發現在這台機器裡面,所有的指針變量都是8,說明這是一個64位的操作系統。
//如果這些數值都是4說明這是一個32位的操作系統。所以指針變量這個值的大小是操作系統相關的。
//所以,在取值的時候需要為這個被指向的對象指明一個類型,方便在取的時候,按照合理的類型把這個元素提取出來。
// 為了繼續進行先把這裡注釋掉,這裡很關鍵!一定要動手嘗試
//所以 如果是
int *p1;
char c;
//p1=&c;
//就會報一個這樣的錯誤: cannot convert 'char*' to 'int*' in assignment
int *p2;
unsigned int i1;
//p1=&i1;
//這個編譯還是很嚴格的,就是不行。在vs裡面這是被允許的。
//[Error] invalid conversion from 'unsigned int*' to 'int*' [-fpermissive]
//但是 如果聲明一個 指向空類型的 指針 在進行指向是被允許的。
void *pv;
pv=&c;
pv=&i1;
//這樣就是編譯通過的。
//p1 = pv;
//[Error] invalid conversion from 'unsigned int*' to 'int*' [-fpermissive]
}
上面是 main.cpp 的情況
下面是 main.c的情況:
#include <iostream>
int main() {
int *p;
unsigned int i;
//p=&i;
//[Error] invalid conversion from 'unsigned int*' to 'int*' [-fpermissive]
int ii;
p=ⅈ
void *p1;
p1 = p;
char *pc;
//pc = p1;
//[Error] invalid conversion from 'void*' to 'char*' [-fpermissive]
return 0;
}