日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

指針對于C來說太重要。然而,想要全面理解指針,除了要對C語言有熟練的掌握外,還要有計算機硬件以及操作系統(tǒng)等方方面面的基本知識。所以本文盡可能的通過一篇文章完全講解指針。

為什么需要指針?

指針解決了一些編程中基本的問題。

第一,指針的使用使得不同區(qū)域的代碼可以輕易的共享內(nèi)存數(shù)據(jù)。當(dāng)然小伙伴們也可以通過數(shù)據(jù)的復(fù)制達到相同的效果,但是這樣往往效率不太好。
因為諸如結(jié)構(gòu)體等大型數(shù)據(jù),占用的字節(jié)數(shù)多,復(fù)制很消耗性能。
但使用指針就可以很好的避免這個問題,因為任何類型的指針占用的字節(jié)數(shù)都是一樣的(根據(jù)平臺不同,有4字節(jié)或者8字節(jié)或者其他可能)。

第二,指針使得一些復(fù)雜的鏈接性的數(shù)據(jù)結(jié)構(gòu)的構(gòu)建成為可能,比如鏈表,鏈式二叉樹等等。

第三,有些操作必須使用指針。如操作申請的堆內(nèi)存。
還有:C語言中的一切函數(shù)調(diào)用中,值傳遞都是“按值傳遞”的。
如果我們要在函數(shù)中修改被傳遞過來的對象,就必須通過這個對象的指針來完成。


計算機是如何從內(nèi)存中進行取指的?

計算機的總線可以分為3種:數(shù)據(jù)總線,地址總線和控制總線。這里不對控制總線進行描述。數(shù)據(jù)總線用于進行數(shù)據(jù)信息傳送。數(shù)據(jù)總線的位數(shù)一般與CPU的字長一致。一般而言,數(shù)據(jù)總線的位數(shù)跟當(dāng)前機器int值的長度相等。例如在16位機器上,int的長度是16bit,32位機器則是32bit。這個計算機一條指令最多能夠讀取或者存取的數(shù)據(jù)長度。大于這個值,計算機將進行多次訪問。這也就是我們說的64位機器進行64位數(shù)據(jù)運算的效率比32位要高的原因,因為32位機要進行兩次取指和運行,而64位機卻只需要一次!


地址總線專門用于尋址,CPU通過該地址進行數(shù)據(jù)的訪問,然后把處于該地址處的數(shù)據(jù)通過數(shù)據(jù)總線進行傳送,傳送的長度就是數(shù)據(jù)總線的位數(shù)。地址總線的位數(shù)決定了CPU可直接尋址的內(nèi)存空間大小,比如CPU總線長32位,其最大的直接尋址空間長232KB,也就是4G。這也就是我們常說的32位CPU最大支持的內(nèi)存上限為4G(當(dāng)然,實際上支持不到這個值,因為一部分尋址空間會被映射到外部的一些IO設(shè)備和虛擬內(nèi)存上。現(xiàn)在通過一些新的技術(shù),可以使32位機支持4G以上內(nèi)存,但這個不在這里的討論范圍內(nèi))。

一般而言,計算機的地址總線和數(shù)據(jù)總線的寬度是一樣的,我們說32位的CPU,數(shù)據(jù)總線和地址總線的寬度都是32位。


計算機訪問某個數(shù)據(jù)的時候,首先要通過地址總線傳送數(shù)據(jù)存儲或者讀取的位置,然后在通過數(shù)據(jù)總線傳送需要存儲或者讀取的數(shù)據(jù)。一般地,int整型的位數(shù)等于數(shù)據(jù)總線的寬度,指針的位數(shù)等于地址總線的寬度。

 

計算機的基本訪問單元

學(xué)過C語言的人都知道,C語言的基本數(shù)據(jù)類型中,就屬char的位數(shù)最小,是8位。我們可以認為計算機以8位,即1個字節(jié)為基本訪問單元。小于一個字節(jié)的數(shù)據(jù),必須通過位操作來進行訪問。

內(nèi)存訪問方式

如圖1所示,計算機在進行數(shù)據(jù)訪問的時候,是以字節(jié)為基本單元進行訪問的,所以可以認為,計算每次都是從第p個字節(jié)開始訪問的。訪問的長度將由編譯器根據(jù)實際類型進行計算,這在后面將會進行講述。

C語言指針難嗎?紙老虎而已,純干貨講解

 

內(nèi)存訪問方式

想要了解更多,就去翻閱計算機組成原理和編譯原理吧。

sizeof關(guān)鍵字

sizeof關(guān)鍵字是編譯器用來計算某些類型的數(shù)據(jù)的長度的,以字節(jié)為基本單位。例如:

sizeof(char)=1; sizeof(int)=4;


sizeof(Type)的值是在編譯的時候就計算出來了的,可以認為這是一個常量!

指針是什么?

我們知道:C語言中的數(shù)組是指一類類型,數(shù)組具體區(qū)分為 int 類型數(shù)組,double類型數(shù)組,char數(shù)組 等等。
同樣指針這個概念也泛指一類數(shù)據(jù)類型,int指針類型,double指針類型,char指針類型等等。

通常,我們用int類型保存一些整型的數(shù)據(jù),如 int num = 97 , 我們也會用char來存儲字符:char ch = 'a'。

我們也必須知道:任何程序數(shù)據(jù)載入內(nèi)存后,在內(nèi)存都有他們的地址,這就是指針。
而為了保存一個數(shù)據(jù)在內(nèi)存中的地址,我們就需要指針變量。

因此:指針是程序數(shù)據(jù)在內(nèi)存中的地址,而指針變量是用來保存這些地址的變量。

 

C語言指針難嗎?紙老虎而已,純干貨講解

 

在我個人的理解中,可以將指針理解成int整型,只不過它存放的數(shù)據(jù)是內(nèi)存地址,而不是普通數(shù)據(jù),我們通過這個地址值進行數(shù)據(jù)的訪問,假設(shè)它的是p,意思就是該數(shù)據(jù)存放位置為內(nèi)存的第p個字節(jié)。


當(dāng)然,我們不能像對int類型的數(shù)據(jù)那樣進行各種加減乘除操作,這是編譯器不允許的,因為這樣錯是非常危險的!


圖2就是對指針的描述,指針的值是數(shù)據(jù)存放地址,因此,我們說,指針指向數(shù)據(jù)的存放位置。

 

C語言指針難嗎?紙老虎而已,純干貨講解

 

指針的長度

我們使用這樣的方式來定義一個指針:

Type *p;


我們說p是指向type類型的指針,type可以是任意類型,除了可以是char,short, int, long等基本類型外,還可以是指針類型,例如int *, int **, 或者更多級的指針,也可是是結(jié)構(gòu)體,類或者函數(shù)等。于是,我們說:

int * 是指向int類型的指針;

int **,也即(int *) *,是指向int *類型的指針,也就是指向指針的指針;

int ***,也即(int **) *,是指向int**類型的指針,也就是指向指針的指針的指針;

…我想你應(yīng)該懂了

struct xxx *,是指向struct xxx類型的指針;

其實,說這么多,只是希望大家在看到指針的時候,不要被int ***這樣的東西嚇到,就像前面說的,指針就是指向某種類型的指針,我們只看最后一個*號,前面的只不過是type類型罷了。

細心一點的人應(yīng)該發(fā)現(xiàn)了,在“什么是指針”這一小節(jié)當(dāng)中,已經(jīng)表明了:指針的長度跟CPU的位數(shù)相等,大部分的CPU是32位的,因此我們說,指針的長度是32bit,也就是4個字節(jié)!注意:任意指針的長度都是4個字節(jié),不管是什么指針!(當(dāng)然64位機自己去測一下,應(yīng)該是8個字節(jié)吧。。。)

于是:

Type *p;

izeof(p)的值是4,Type可以是任意類型,char,int, long, struct, class, int **…

以后大家看到什么sizeof(char*), sizeof(int *),sizeof(xxx *),不要理會,統(tǒng)統(tǒng)寫4,只要是指針,長度就是4個字節(jié),絕對不要被type類型迷惑!

為什么程序中的數(shù)據(jù)會有自己的地址?

弄清這個問題我們需要從操作系統(tǒng)的角度去認知內(nèi)存。

電腦維修師傅眼中的內(nèi)存是這樣的:內(nèi)存在物理上是由一組DRAM芯片組成的。

 

C語言指針難嗎?紙老虎而已,純干貨講解

 

而作為一個程序員,我們不需要了解內(nèi)存的物理結(jié)構(gòu),操作系統(tǒng)將RAM等硬件和軟件結(jié)合起來,給程序員提供的一種對內(nèi)存使用的抽象。
這種抽象機制使得程序使用的是虛擬存儲器,而不是直接操作和使用真實存在的物理存儲器。
所有的虛擬地址形成的集合就是虛擬地址空間。

 

C語言指針難嗎?紙老虎而已,純干貨講解

 

在程序員眼中的內(nèi)存應(yīng)該是下面這樣的。

 

C語言指針難嗎?紙老虎而已,純干貨講解

 

也就是說,內(nèi)存是一個很大的,線性的字節(jié)數(shù)組(平坦尋址)。每一個字節(jié)都是固定的大小,由8個二進制位組成。
最關(guān)鍵的是,每一個字節(jié)都有一個唯一的編號,編號從0開始,一直到最后一個字節(jié)。
如上圖中,這是一個256M的內(nèi)存,他一共有256x1024x1024 = 268435456個字節(jié),那么它的地址范圍就是 0 ~268435455 。

由于內(nèi)存中的每一個字節(jié)都有一個唯一的編號。
因此,在程序中使用的變量,常量,甚至數(shù)函數(shù)等數(shù)據(jù),當(dāng)他們被載入到內(nèi)存中后,都有自己唯一的一個編號,這個編號就是這個數(shù)據(jù)的地址。
指針就是這樣形成的。

下面用代碼說明

#include <stdio.h>int main(void){ char ch = 'a'; int num = 97; printf("ch 的地址:%p",&ch); //ch 的地址:0028FF47 printf("num的地址:%p",&num); //num的地址:0028FF40 return 0;}
C語言指針難嗎?紙老虎而已,純干貨講解

 

指針的值實質(zhì)是內(nèi)存單元(即字節(jié))的編號,所以指針單獨從數(shù)值上看,也是整數(shù),他們一般用16進制表示。
指針的值(虛擬地址值)使用一個機器字的大小來存儲。
也就是說,對于一個機器字為w位的電腦而言,它的虛擬地址空間是0~2w - 1 ,程序最多能訪問2w個字節(jié)。
這就是為什么xp這種32位系統(tǒng)最大支持4GB內(nèi)存的原因了。

我們可以大致畫出變量ch和num在內(nèi)存模型中的存儲。(假設(shè) char占1個字節(jié),int占4字節(jié))

 

C語言指針難嗎?紙老虎而已,純干貨講解

 

變量和內(nèi)存

為了簡單起見,這里就用上面例子中的 int num = 97 這個局部變量來分析變量在內(nèi)存中的存儲模型。

 

C語言指針難嗎?紙老虎而已,純干貨講解

 

已知:num的類型是int,占用了4個字節(jié)的內(nèi)存空間,其值是97,地址是0028FF40。我們從以下幾個方面去分析。

1、內(nèi)存的數(shù)據(jù)

內(nèi)存的數(shù)據(jù)就是變量的值對應(yīng)的二進制,一切都是二進制。
97的二進制是 : 00000000 00000000 00000000 0110000 , 但使用的小端模式存儲時,低位數(shù)據(jù)存放在低地址,所以圖中畫的時候是倒過來的。

2、內(nèi)存數(shù)據(jù)的類型

內(nèi)存的數(shù)據(jù)類型決定了這個數(shù)據(jù)占用的字節(jié)數(shù),以及計算機將如何解釋這些字節(jié)。
num的類型是int,因此將被解釋為 一個整數(shù)。

3、內(nèi)存數(shù)據(jù)的名稱

內(nèi)存的名稱就是變量名。實質(zhì)上,內(nèi)存數(shù)據(jù)都是以地址來標識的,根本沒有內(nèi)存的名稱這個說法,這只是高級語言提供的抽象機制 ,方便我們操作內(nèi)存數(shù)據(jù)。
而且在C語言中,并不是所有的內(nèi)存數(shù)據(jù)都有名稱,例如使用malloc申請的堆內(nèi)存就沒有。

4、內(nèi)存數(shù)據(jù)的地址

如果一個類型占用的字節(jié)數(shù)大于1,則其變量的地址就是地址值最小的那個字節(jié)的地址。
因此num的地址是 0028FF40。內(nèi)存的地址用于標識這個內(nèi)存塊。

5、內(nèi)存數(shù)據(jù)的生命周期

num是main函數(shù)中的局部變量,因此當(dāng)main函數(shù)被啟動時,它被分配于棧內(nèi)存上,當(dāng)main執(zhí)行結(jié)束時,消亡。

如果一個數(shù)據(jù)一直占用著他的內(nèi)存,那么我們就說他是“活著的”,如果他占用的內(nèi)存被回收了,則這個數(shù)據(jù)就“消亡了”。
C語言中的程序數(shù)據(jù)會按照他們定義的位置,數(shù)據(jù)的種類,修飾的關(guān)鍵字等因素,決定他們的生命周期特性。
實質(zhì)上我們程序使用的內(nèi)存會被邏輯上劃分為:棧區(qū),堆區(qū),靜態(tài)數(shù)據(jù)區(qū),方法區(qū)。
不同的區(qū)域的數(shù)據(jù)有不同的生命周期。


無論以后計算機硬件如何發(fā)展,內(nèi)存容量都是有限的,因此清楚理解程序中每一個程序數(shù)據(jù)的生命周期是非常重要的。


指針運算

N多的面試會考這種東西了:

??????Type *p; p++;

然后問你p的值變化了多少。

其實,也可以認為這是在考編譯器的基本知識。因此p的值并不像表面看到的+1那么簡單,編譯器實際上對p進行的是加sizeof(Type)的操作。

看一個一段代碼的測試結(jié)果:

C語言指針難嗎?紙老虎而已,純干貨講解

 

這里注釋掉char一行的原因是因為cout<<(char*)會被當(dāng)成字符串輸出,而不是char的地址)

執(zhí)行結(jié)果:

C語言指針難嗎?紙老虎而已,純干貨講解

 

觀察結(jié)果,可以看出,他們的增長結(jié)果分別是:

2(sizeof(short)) 4(sizeof(int)) 4(sizeof(long)) 8(sizeof(long long)) 4(sizeof(float)) 8(sizeof(double)) 12(sizeof(long double))


喏,增加的值是不是sizeof(Type)呢?別的什么struct,class之類的,就不驗證你,有興趣的自己去驗證。

我們再對這樣的一段代碼進行匯編,查看編譯器是如何進行指針的加法操作的:

 

C語言指針難嗎?紙老虎而已,純干貨講解

 

匯編結(jié)果:

C語言指針難嗎?紙老虎而已,純干貨講解

 


C語言指針難嗎?紙老虎而已,純干貨講解

 

注意看注釋部分的結(jié)果,我們看到,piv的值顯示加了4(sizeof(int)),然后又加了16(4*sizeof(int))。


指針變量和指向關(guān)系

用來保存指針的變量,就是指針變量。
如果指針變量p1保存了變量 num的地址,則就說:p1指向了變量num,也可以說p1指向了num所在的內(nèi)存塊 ,這種指向關(guān)系,在圖中一般用 箭頭表示。

 

C語言指針難嗎?紙老虎而已,純干貨講解

 

上圖中,指針變量p1指向了num所在的內(nèi)存塊 ,即從地址0028FF40開始的4個byte 的內(nèi)存塊。

定義指針變量

C語言中,定義變量時,在變量名前寫一個 * 星號,這個變量就變成了對應(yīng)變量類型的指針變量。必要時要加( ) 來避免優(yōu)先級的問題。

引申:C語言中,定義變量時,在定義的最前面寫上typedef ,那么這個變量名就成了一種類型,即這個類型的同義詞。

int a ; //int類型變量 aint *a ; //int* 變量aint arr[3]; //arr是包含3個int元素的數(shù)組int (* arr )[3]; //arr是一個指向包含3個int元素的數(shù)組的指針變量

//-----------------各種類型的指針------------------------------
int* p_int; //指向int類型變量的指針 
double* p_double; //指向idouble類型變量的指針 
struct Student *p_struct; //結(jié)構(gòu)體類型的指針
int(*p_func)(int,int); //指向返回類型為int,有2個int形參的函數(shù)的指針 
int(*p_arr)[3]; //指向含有3個int元素的數(shù)組的指針 
int** p_pointer; //指向 一個整形變量指針的指針

指針的2個重要屬性

指針也是一種數(shù)據(jù),指針變量也是一種變量,因此指針 這種數(shù)據(jù)也符合前面變量和內(nèi)存主題中的特性。
這里要強調(diào)2個屬性:指針的類型,指針的值。

int main(void){ int num = 97; int *p1 = # char* p2 = (char*)(&num);
 printf("%d",*p1); //輸出 97 putchar(*p2); //輸出 a return 0;}

指針的值:很好理解,如上面的num 變量 ,其地址的值就是0028FF40 ,因此 p1的值就是0028FF40。
數(shù)據(jù)的地址用于在內(nèi)存中定位和標識這個數(shù)據(jù),因為任何2個內(nèi)存不重疊的不同數(shù)據(jù)的地址都是不同的。

指針的類型:指針的類型決定了這個指針指向的內(nèi)存的字節(jié)數(shù)并如何解釋這些字節(jié)信息。
一般指針變量的類型要和它指向的數(shù)據(jù)的類型匹配。

由于num的地址是0028FF40,因此 p1 和 p2 的值都是0028FF40

*p1 : 將從地址0028FF40 開始解析,因為p1是int類型指針,int占4字節(jié),因此向后連續(xù)取4個字節(jié),并將這4個字節(jié)的二進制數(shù)據(jù)解析為一個整數(shù) 97。

*p2 : 將從地址0028FF40 開始解析,因為p2是char類型指針,char占1字節(jié),因此向后連續(xù)取1個字節(jié),并將這1個字節(jié)的二進制數(shù)據(jù)解析為一個字符,即'a'。

同樣的地址,因為指針的類型不同,對它指向的內(nèi)存的解釋就不同,得到的就是不同的數(shù)據(jù)。

取地址

既然有了指針變量,那就得讓他保存其它變量的地址,使用& 運算符取得一個變量的地址。

int add(int a , int b){ return a + b;}
int main(void){ int num = 97; float score = 10.00F; int arr[3] = {1,2,3};
 //-----------------------
 int* p_num = # float* p_score = &score; int (*p_arr)[3] = &arr; int (*fp_add)(int ,int ) = add; //p_add是指向函數(shù)add的函數(shù)指針 return 0;}

特殊的情況,他們并不一定需要使用&取地址:

  • 數(shù)組名的值就是這個數(shù)組的第一個元素的地址。
  • 函數(shù)名的值就是這個函數(shù)的地址。
  • 字符串字面值常量作為右值時,就是這個字符串對應(yīng)的字符數(shù)組的名稱,也就是這個字符串在內(nèi)存中的地址。
int add(int a , int b){ return a + b;}int main(void){ int arr[3] = {1,2,3}; //----------------------- int* p_first = arr; int (*fp_add)(int ,int ) = add; const char* msg = "Hello world"; return 0;}

解地址

我們需要一個數(shù)據(jù)的指針變量干什么?
當(dāng)然使用通過它來操作(讀/寫)它指向的數(shù)據(jù)啦。
對一個指針解地址,就可以取到這個內(nèi)存數(shù)據(jù),解地址的寫法,就是在指針的前面加一個*號。

解指針的實質(zhì)是:從指針指向的內(nèi)存塊中取出這個內(nèi)存數(shù)據(jù)。

int main(void){ int age = 19; int*p_age = &age; *p_age = 20; //通過指針修改指向的內(nèi)存數(shù)據(jù)
 printf("age = %d",*p_age); //通過指針讀取指向的內(nèi)存數(shù)據(jù) printf("age = %d",age);
 return 0;}

指針之間的賦值

指針賦值和int變量賦值一樣,就是將地址的值拷貝給另外一個。
指針之間的賦值是一種淺拷貝,是在多個編程單元之間共享內(nèi)存數(shù)據(jù)的高效的方法。

??????int* p1 = & num;int* p3 = p1;
//通過指針 p1 、 p3 都可以對內(nèi)存數(shù)據(jù) num 進行讀寫,如果2個函數(shù)分別使用了p1 和p3,那么這2個函數(shù)就共享了數(shù)據(jù)num。

 

C語言指針難嗎?紙老虎而已,純干貨講解

 

空指針(NULL指針)

NULL是C語言標準定義的一個值,這個值其實就是0,只不過為了使得看起來更加具有意義,才定義了這樣的一個宏,中文的意思是空,表明不指向任何東西。你懂得。不過在此不討論空和零的區(qū)別。
在C語言中,我們讓指針變量賦值為NULL表示一個空指針,而C語言中,NULL實質(zhì)是((void*)0),就像前面說的指針可以理解成特殊的int,它總是有值的,p=NULL,其實就是p的值等于0。對于不多數(shù)機器而言,0地址是不能直接訪問的,設(shè)置為0,就表示該指針哪里都沒指向。而在C++中,NULL實質(zhì)是0。

換種說法:任何程序數(shù)據(jù)都不會存儲在地址為0的內(nèi)存塊中,它是被操作系統(tǒng)預(yù)留的內(nèi)存塊。
下面代碼摘自 stdlib.h

#ifdef __cplusplus #define NULL 0#else #define NULL ((void *)0)#endif

當(dāng)然,就機器內(nèi)部而言,NULL指針的實際值可能與此不同,這種情況下,編譯器將負責(zé)零值和內(nèi)部值之間的翻譯轉(zhuǎn)換。

NULL指針的概念非常有用,它給了你一種方法,表示某個特定的指針目前并未指向任何東西。例如,一個用于在某個數(shù)組中查找某個特定值的函數(shù)可能返回一個指向查找到的數(shù)組元素的指針。如果沒找到,則返回一個NULL指針。

在內(nèi)存的動態(tài)分配上,NULL的意義非同凡響,我們使用它來避免內(nèi)存被多次釋放,造成經(jīng)常性的段錯誤(segmentation fault)。一般,在free或者delete掉動態(tài)分配的內(nèi)存后,都應(yīng)該立即把指針置空,避免出現(xiàn)所以的懸掛指針,致使出現(xiàn)各種內(nèi)存錯誤!例如:

C語言指針難嗎?紙老虎而已,純干貨講解

 

free函數(shù)是不會也不可能把p置空的。像下面這樣的代碼就會出現(xiàn)內(nèi)存段錯誤:

C語言指針難嗎?紙老虎而已,純干貨講解

 

因為,第一次free操作之后,p指向的內(nèi)存已經(jīng)釋放了,但是p的值還沒有變化,free函數(shù)改不了這個值,再free一次的時候,p指向的內(nèi)存區(qū)域已經(jīng)被釋放了,這個地址已經(jīng)變成了非法地址,這個操作將導(dǎo)致段錯誤的發(fā)生(此時,p指向的區(qū)域剛好又被分配出去了,但是這種概率非常低,而且對這樣一塊內(nèi)存區(qū)域進行操作是非常危險的!)
但是下面這段代碼就不會出現(xiàn)這樣的問題:

C語言指針難嗎?紙老虎而已,純干貨講解

 

因為p的值編程了NULL,free函數(shù)檢測到p為NULL,會直接返回,而不會發(fā)生錯誤。

這里順便告訴大家一個內(nèi)存釋放的小竅門,可以有效的避免因為忘記對指針進行置空而出現(xiàn)各種內(nèi)存問題。這個方法就是自定義一個內(nèi)存釋放函數(shù),但是傳入的參數(shù)不知指針,而是指針的地址,在這個函數(shù)里面置空,如下:
 

C語言指針難嗎?紙老虎而已,純干貨講解

 

結(jié)果:

C語言指針難嗎?紙老虎而已,純干貨講解

 

my_free調(diào)用了之后,p的值就變成了0(NULL),調(diào)用多少次free都不會報錯了!

另外一個方式也非常有效,那就是定義FREE宏,在宏里面對他進行置空。例如
 

C語言指針難嗎?紙老虎而已,純干貨講解

 

執(zhí)行結(jié)果同上面一樣,不會報段錯誤:

 

C語言指針難嗎?紙老虎而已,純干貨講解

 

(關(guān)于內(nèi)存的動態(tài)分配,這是個比較復(fù)雜的話題,有機會再專門開辟一章給各位講述一下吧,寫個帖子還是很花費時間和精力的,呵呵,寫過的童鞋應(yīng)該都很清楚,所以順便插一句,轉(zhuǎn)帖可以,請注明出處,畢竟,大家都是本著共享的精神來討論問題的,寫的好壞都沒有向你所要什么,請尊重每個人的勞動成果。)

指向空,或者說不指向任何東西。
壞指針

指針變量的值是NULL,或者未知的地址值,或者是當(dāng)前應(yīng)用程序不可訪問的地址值,這樣的指針就是壞指針。
不能對他們做解指針操作,否則程序會出現(xiàn)運行時錯誤,導(dǎo)致程序意外終止。

任何一個指針變量在做解地址操作前,都必須保證它指向的是有效的,可用的內(nèi)存塊,否則就會出錯。
壞指針是造成C語言Bug的最頻繁的原因之一。

??????下面的代碼就是錯誤的示例。
void opp(){ int*p = NULL; *p = 10; //Oops! 不能對NULL解地址}
void foo(){ int*p; *p = 10; //Oops! 不能對一個未知的地址解地址}
void bar(){ int*p = (int*)1000; *p =10; //Oops! 不能對一個可能不屬于本程序的內(nèi)存的地址的指針解地址}

分享到:
標簽:指針 語言
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定