c语言 指针_C语言——指针
學習階段:高中信競、大學編程。
前置知識:二進制與十六進制,C語言基礎,數組。
指針初學可能比較難理解,我這篇文章盡量用通俗易懂的方式來講解。
1. 指針概述
為什么有指針這個東西?因為指針很貼近計算機內部的實際工作原理,與內存實際的尋址方式類似。C語言可以說是高級語言中最貼近機器的語言,而像Python、JavaScript這種更親和于人類的語言與機器的關系則比較遠了,甚至它們本身可能還是用C語言寫出來的呢。
指針可以形象地比喻為在內存中定位的導航員。內存那么大,怎么知道我需要的東西存在哪里呢?可以讓指針來記錄與導航。我們先來了解一下內存。
2. 預備知識
2.1 內存
研究過組裝機、電腦配件的話,一定知道內存條這個東西。現在這個時代,一臺家用電腦的內存一般是2GB、4GB、8GB、16GB、32GB、64GB等等。
把CPU比作干活的人,則內存就相當于工作臺。CPU在跑的程序以及很多相關數據都存在內存內,這就相當于人在干活時要把相關資料放在工作臺上使用。
內存可以看成是一個巨大的數組,我這里記為
memory[0..n]memory的每一個單元存1B=8bit,memory[0]就是內存的第一個單元。這個中括號里面的數,即數組下標,被稱為內存地址,簡稱為地址。我確定了一個地址,也就相當于確定了內存中的一個單元。
通常,我們說的32位機器,意思就是地址是32bit的,最大支持的內存是
memory[0x00000000..0xFFFFFFFF]最小地址是0,最大地址是0xFFFFFFFF=2^32-1,最大支持
也就是說32位機器理論上最大支持4GB的內存,這就是它逐漸被淘汰的原因。
而64位機器理論上最大支持的內存是
這個量級遠大于目前的需求,因此128位機器在相當長的時間內不會出現。
2.2 變量與數據類型
C語言有很多數據類型,不同的數據類型在內存中的占用空間和存儲格式也不一樣。不同數據類型的存儲格式比較復雜,這里不詳述。我只談談不同的占用空間。
一個變量在內存中占用都是連續空間,記T類型的變量在內存中占用sizeof(T)字節的空間。當我聲明一個T類型的變量a時,內存會尋找連續且可用的sizeof(T)個單元,把它們分配給變量a,比如說是memory[100..103]這4B的空間。此后我對變量a進行讀寫,也就相當于對memory[100..103]這4B的空間進行讀寫。
某些數據類型的占用空間:short短整形占用2B,int整形占用4B;float浮點形占用4B,double雙浮點型占用8B;char字符型占用1B.
3. 指針
指針是一種特殊的數據類型,指針類型的變量應存儲的是內存地址。在32位機器上,任何一個內存地址都是32bit=4B,故任何一個指針型變量都占用4B.
現在問題來了,指針指向內存中的一個單元,我怎么知道這個單元里面存的是什么東西,是什么類型的數據?因此,在聲明指針變量的時候,也要聲明這個指針指向數據的類型,比如int型指針、char型指針等。
3.1 指針的聲明
在語法上,聲明指針類型使用*符號,例如
int *a, b, *c; //a和c是指針,b不是指針 char *ch;這兩句代碼聲明了int*型的變量a與c、int型變量b以及char*型變量ch. 根據語法,我們習慣上稱T型指針為T*型,含義就是T*型變量是指針,其所指的相關內存單元存的是T型數據。 (注意,這里的b變量不是指針,僅僅為普通的int整形。)
3.2 指針的使用
指針有很多種使用方式,包括動態申請內存、函數地址傳參等等。我這里僅介紹最簡單的使用方式。我提供一份例程,可直接從例程中學習指針的聲明與使用。
例程:
int x=1, y=2; //聲明x與y并賦初值 int *p=&x; //聲明p且p指向x *p=11; //p修改x p=&y; //p指向y *p=12; //p修改y printf("x=%d, y=%d", x, y); //打印x與y第一行,在內存中申請連續的4B區域存入int型數據1,記為變量x;再在內存中申請連續的4B區域存入int型數據2,記為變量y. 假設x對應內存區域memory[100..103],y對應內存區域memory[200..203]. 第一行執行完畢,內存如圖1所示:
圖1 第一行執行完畢第二行, 在內存中申請連續的4B區域存入int*型地址數據100,記為變量p. 這里&符號是取地址運算符,表示取變量x的首地址,在本例中就是100. 這一行代碼是聲明指針同時賦初值,相當于以下兩行代碼:
int *p; p=&x;第二行執行完畢,內存如圖2所示(100的十六進制是0x64):
圖2 第二行執行完畢第三行,將p所指的地址起4B空間內存入int型數據11. 這里*是解地址運算符, 表示取得指針所指的內存空間。 第三行執行完畢,內存如圖3所示:
圖3 第三行執行完畢如果第三行改為執行p=(int*)11;,則是先把int型數據11強制轉換為int*型數據11,然后賦值給p,如圖3.2所示:
圖3.2 第三行改為執行p=(int*)11;此時p所指的內存空間不一定是可用的。因此像這樣直接給指針賦值一個常數的情況非常罕見。
第四行,p存y的首地址。第四行執行完畢,內存如圖4所示:
圖4 第四行執行完畢第五行,把變量y的值改為12. 第五行執行完畢,內存如圖5所示:
圖5 第五行執行完畢第六行,打印x與y的值,打印結果應為:
x=11, y=124. 多級指針
指針也可以指向指針,稱為多級指針。
例程:
int x=1; int *p=&x; int **p2=&p;這里p2就是一個二級指針,它的類型是int**,它也存了一個地址,但是這個地址是某個int*型變量的地址,在這里是存了int*型變量p的地址。
假設x的首地址是0x10,p的首地址是0x20,那么內存的情況如圖6所示:
圖6 多級指針示例三級、四級等等更多級的指針也是存在的,但是幾乎不會用到。二級指針一般只在二維數組中會用到,其他情況也很少見。盡量不要使用多級指針,不然真的容易弄暈自己。
5. 答疑
5.1 星號*的不同作用
在指針聲明、數據類型中,*表示是指針類型;在已聲明變量前面的*是解地址運算符,比如說*p就是用p的內容求得其所指的區域;當然,*還有算數乘法等含義。
總結
以上是生活随笔為你收集整理的c语言 指针_C语言——指针的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 北京环球影城速通卡怎么买
- 下一篇: 《楚乔传》楚乔母亲是青山院婢女 宇文灼曾