C語(yǔ)言深入講解指針與結(jié)構(gòu)體的使用
1 啥是指針
剛剛接觸指針的同學(xué)肯定會(huì)很懵逼,指針是啥?。恐改厢樄?,不和大家開(kāi)玩笑,我們進(jìn)行正題吧,指針是本質(zhì)是就是地址,但我們要注意我們口頭上常說(shuō)的指針并非指針,而是指針變量。
1.1指針與指針變量
指針:內(nèi)存中一個(gè)最小單元的編號(hào),也就是地址。
指針變量:是用來(lái)存放內(nèi)存地址的變量。
我們可以看下面的這張圖。
為了唯一標(biāo)識(shí)一塊內(nèi)存空間,在C語(yǔ)言中就用指針來(lái)標(biāo)記,就像我們的寢室的門(mén)牌號(hào)一樣,假設(shè)張三的寢室門(mén)排號(hào)是A602,A602就是地址也就是指針,為了讓張三的寢室被人,可以找到,我們我們肯定是要在系統(tǒng)是登記有怎么個(gè)寢室,下次來(lái)張三寢室也就方便,而在C語(yǔ)言中,就用指針變量來(lái)存放我們的地址(通常用&地址操作符來(lái)取出地址在存放在指針變量中)
#include<stdio.h> int main() { int a = 0; int* p = &a; *p = 1; return 0; }
從中我們可以看出,我們可以通過(guò)指針變量p解引用(*),來(lái)找到a從而更改a的值。
從上面圖中我們知道在內(nèi)存中的每一塊空間的大小都是一個(gè)字節(jié),那么對(duì)一個(gè)32平臺(tái)的機(jī)器,就有32根地址線,地址線上能產(chǎn)生高電平(1)和低電平(0),這樣的話就能產(chǎn)生2的32次方個(gè)地址。
2的32次方個(gè)地址
2^32Byte == 2^32/1024KB == 2^32/1024/1024MB==2^32/1024/1024/1024GB == 4GB),4G的空閑進(jìn)行編址
對(duì)于62位平臺(tái)
便有2的62地址
2^64Byte == 2^64/1024KB == 2^64/1024/1024MB==2^64/1024/1024/1024GB ==17,179,869,184GB這樣我們可以編碼的空間就會(huì)打的多。
1.2總結(jié)
1指針本質(zhì)是地址,指針變量是用來(lái)存放地址的。
2指針在32位平臺(tái)的大小為,4個(gè)字節(jié),在62位平臺(tái)為8個(gè)字節(jié)
2 指針和指針類型
指針的類型,其實(shí),和變量的類型差不多,就是變量了類型多個(gè)*號(hào)
常見(jiàn)的指針類型
har *pc = NULL;
int *pi = NULL;
short *ps = NULL;
long *pl = NULL;
float *pf = NULL;
double *pd = NULL;
2.1指針+-整數(shù)
指針的+-整數(shù)其實(shí)反應(yīng)的是指針跳過(guò)的字節(jié),決定了指針的步長(zhǎng)。
#include<stdio.h> int main() { int arr[5] = { 1,2,3,4,5 }; int* p = arr; printf("%d\n", *p); printf("%d\n", *(p + 1)); printf("%d\n", *(p + 2)); return 0; }
arr指的是首元素的地址,存放在指針變量p上,我們*p就可以找到數(shù)組的第一給元素,那么*(p+1)指的又是上面呢,其實(shí)他指的是跳過(guò)一個(gè)4個(gè)字節(jié),為什么是4個(gè)字節(jié)而不是一個(gè)字節(jié)呢,這就跟指針變量的類型有關(guān)系了,因?yàn)閜是int*s是4個(gè)字節(jié),如果是char*我們+1又會(huì)發(fā)生什么呢?
這時(shí)我們觀察到打印了0,我們*(p+4)才早的數(shù)組的第二個(gè)元素,這是因?yàn)閿?shù)組arr中的每個(gè)元素都是4個(gè)字節(jié)的,而char*p類型的指針加1只能跳過(guò)1個(gè)字節(jié),這時(shí)候找的首地址就不對(duì)了。
3 野指針
概念: 野指針就是指針指向的位置是不可知的(隨機(jī)的、不正確的、沒(méi)有明確限制的)
3.1 野指針的成因
1指針未初始化
2指針越界訪問(wèn)
3指針指向的空間釋放
這里雖然可以打印出6來(lái),但這樣的訪問(wèn)是非法的,因?yàn)樾螀⒃诔龊瘮?shù)就會(huì)銷毀。
3.2 如何避免野指針的出現(xiàn)
1. 指針初始化
2. 小心指針越界
3. 指針指向空間釋放即使置NULL
4. 避免返回局部變量的地址
5. 指針使用之前檢查有效性
其中我們可以養(yǎng)成一個(gè)習(xí)慣,當(dāng)我們不知道給指針初始化何值時(shí),我們可以初始化指針為NULL(0),在對(duì)指針賦值的時(shí)候在判斷一下,就可以一定程度上避免野指針。
4 二級(jí)指針
簡(jiǎn)單的說(shuō)就是存放一級(jí)指針的地址
圖中ppa便是二級(jí)指針變量,存的一級(jí)指針變量的地址。
5 指針數(shù)組
存放指針的數(shù)組,指針數(shù)組本質(zhì)是數(shù)組。
其中的parr變是指針數(shù)組,其中parr[10]等價(jià)于*(parr+10);
指針數(shù)組可以模擬一個(gè)二維數(shù)組
6 結(jié)構(gòu)體
結(jié)構(gòu)是一些值的集合,這些值稱為成員變量。結(jié)構(gòu)的每個(gè)成員可以是不同類型的變量。
6.1 結(jié)構(gòu)的聲明
struct tag
{
member-list;
}variable-list;
struct:是結(jié)構(gòu)體類型的關(guān)鍵字
struct tag:是用戶定義的結(jié)構(gòu)體類型
member-list:是結(jié)構(gòu)體成員
variable-list:結(jié)構(gòu)體類型變量
其中結(jié)構(gòu)的成員可以是標(biāo)量、數(shù)組、指針,甚至是其他結(jié)構(gòu)體。
6.2 結(jié)構(gòu)體變量的定義和初始化
結(jié)構(gòu)體變量的定義就是給結(jié)構(gòu)體類型取一個(gè)變量。
結(jié)構(gòu)體的初始化
6.3 結(jié)構(gòu)體的訪問(wèn)
結(jié)構(gòu)體變量成員用 .訪問(wèn)
結(jié)構(gòu)體變量指針->訪問(wèn)
6.4 結(jié)構(gòu)體傳參
傳參有二種,但對(duì)于結(jié)構(gòu)體來(lái)說(shuō)傳址調(diào)用是最好的,
函數(shù)傳參的時(shí)候,參數(shù)是需要壓棧的。 如果傳遞一個(gè)結(jié)構(gòu)體對(duì)象的時(shí)候,結(jié)構(gòu)體過(guò)大,參數(shù)壓棧的的系統(tǒng)開(kāi)銷比較大,所以會(huì)導(dǎo)致性能的下降。
所以:結(jié)構(gòu)體傳參的時(shí)候,要傳結(jié)構(gòu)體的地址。
到此這篇關(guān)于C語(yǔ)言深入講解指針與結(jié)構(gòu)體的使用的文章就介紹到這了,更多相關(guān)C語(yǔ)言指針與結(jié)構(gòu)體內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C語(yǔ)言示例講解結(jié)構(gòu)體的聲明與初始化方法
- C語(yǔ)言詳細(xì)分析結(jié)構(gòu)體的內(nèi)存對(duì)齊規(guī)則
- 詳解C語(yǔ)言中結(jié)構(gòu)體的使用
- C語(yǔ)言中的自定義類型之結(jié)構(gòu)體與枚舉和聯(lián)合詳解
- C語(yǔ)言結(jié)構(gòu)體數(shù)組常用的三種賦值方法(包含字符串)
- C語(yǔ)言深入回顧講解結(jié)構(gòu)體對(duì)齊
- C語(yǔ)言深入探究自定義類型之結(jié)構(gòu)體與枚舉及聯(lián)合
- C語(yǔ)言中結(jié)構(gòu)體的內(nèi)存對(duì)齊規(guī)則講解
- C語(yǔ)言全面梳理結(jié)構(gòu)體知識(shí)點(diǎn)
相關(guān)文章
c++類型轉(zhuǎn)換及RTTI運(yùn)行階段類型識(shí)別
這篇文章主要為大家介紹了c++類型轉(zhuǎn)換及RTTI運(yùn)行階段類型識(shí)別詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2023-05-05matlab鳥(niǎo)群算法求解車間調(diào)度問(wèn)題詳解及實(shí)現(xiàn)源碼
這篇文章主要為大家介紹了matlab鳥(niǎo)群算法求解車間調(diào)度的問(wèn)題分析及實(shí)現(xiàn)源碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02zlib庫(kù)壓縮和解壓字符串STL string的實(shí)例詳解
這篇文章主要介紹了zlib庫(kù)壓縮和解壓字符串STL string的實(shí)例詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-10-10C++利用兩個(gè)棧實(shí)現(xiàn)隊(duì)列的方法
這篇文章主要給大家介紹了關(guān)于C++利用兩個(gè)棧實(shí)現(xiàn)隊(duì)列的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05