當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]指向數(shù)組元素的指針和運(yùn)算法則所謂指向數(shù)組元素的指針,其本質(zhì)還是變量的指針。因?yàn)閿?shù)組中的每個(gè)元素,其實(shí)都可以直接看成是一個(gè)變量,所以指向數(shù)組元素的指針,也就是變量的指針。指向數(shù)組元素的指針不難,但很常用

指向數(shù)組元素的指針和運(yùn)算法則


所謂指向數(shù)組元素的指針,其本質(zhì)還是變量的指針。因?yàn)閿?shù)組中的每個(gè)元素,其實(shí)都可以直接看成是一個(gè)變量,所以指向數(shù)組元素的指針,也就是變量的指針。


指向數(shù)組元素的指針不難,但很常用。我們用程序來(lái)解釋會(huì)比較直觀(guān)一些。

unsigned char number[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

unsigned char *p;

如果我們寫(xiě) p = &number[0];那么指針 p 就指向了 number 的第 0 號(hào)元素,也就是把number[0]的地址賦值給了 p,同理,如果寫(xiě) p = &number[1];p 就指向了數(shù)組 number 的第 1號(hào)元素。p = &number[x];其中 x 的取值范圍是 0~9,就表示 p 指向了數(shù)組 number 的第 x 號(hào)元素。指針本身,也可以進(jìn)行幾種簡(jiǎn)單的運(yùn)算,這幾種運(yùn)算對(duì)于數(shù)組元素的指針來(lái)說(shuō)應(yīng)用最多。

比較運(yùn)算。比較的前提是兩個(gè)指針指向同種類(lèi)型的對(duì)象,比如兩個(gè)指針變量 p 和 q它們指向了具有同種數(shù)據(jù)類(lèi)型的數(shù)組,那它們可以進(jìn)行 <,>,>=,<=,==等關(guān)系運(yùn)算。如果 p==q 為真的話(huà),表示這兩個(gè)指針指向的是同一個(gè)元素。

指針和整數(shù)可以直接進(jìn)行加減運(yùn)算。比如還是上邊我們那個(gè)指針 p 和數(shù)組 number,如果 p = &number[0],那么 p+1 就指向了 number[1],p+9 就指向了 number[9]。當(dāng)然了,如果 p = &number[9],p-9 也就指向了 number[0]。

兩個(gè)指針變量在一定條件下可以進(jìn)行減法運(yùn)算。如 p = &number[0]; q = &number[9];那么 q-p 的結(jié)果就是 9。但是這個(gè)地方大家要特別注意,這個(gè) 9 代表的是元素的個(gè)數(shù),而不是真正的地址差值。如果我們的 number 的變量類(lèi)型是 unsigned int 型,占 2 個(gè)字節(jié),q-p 的結(jié)果依然是 9,因?yàn)樗淼氖菙?shù)組元素的個(gè)數(shù)。


在數(shù)組元素指針這里還有一種情況,就是數(shù)組名字其實(shí)就代表了數(shù)組元素的首地址,也就是說(shuō):

p = &number[0];

p = number;

這兩種表達(dá)方式是等價(jià)的,因此以下幾種表達(dá)形式和內(nèi)容需要大家格外注意一下。


根據(jù)指針的運(yùn)算規(guī)則,p+x 代表的是 number[x]的地址,那么 number+x 代表的也是number[x]的地址。或者說(shuō),它們指向的都是 number 數(shù)組的第 x 號(hào)元素。


*(p+x)和*(number+x)都表示 number[x]。


指向數(shù)組元素的指針也可以表示成數(shù)組的形式,也就是說(shuō),允許指針變量帶下標(biāo),即 p[i]和*(p+i)是等價(jià)的。但是為了避免混淆與規(guī)范起見(jiàn),這里我們建議大家不要寫(xiě)成前者,而一律采用后者的寫(xiě)法。但如果看到別人那么寫(xiě),也知道是怎么回事即可。


二維數(shù)組元素的指針和一維數(shù)組類(lèi)似,需要介紹的內(nèi)容不多。假如現(xiàn)在一個(gè)指針變量 p和一個(gè)二維數(shù)組 number[3][4],它的地址的表達(dá)方式也就是 p=&number[0][0],有一個(gè)地方要注意,既然數(shù)組名代表了數(shù)組元素的首地址,那么也就是說(shuō) p 和 number 都是指數(shù)組的首地址。對(duì)二維數(shù)組來(lái)說(shuō),number[0],number[1],number[2]都可以看成是一維數(shù)組的數(shù)組名字,所以 number[0]等價(jià)于 &number[0][0], number[1]等價(jià)于 &number[1][0], number[2]等價(jià)于&number[2][0]。加減運(yùn)算和一維數(shù)組是類(lèi)似的,不再詳述。

指向數(shù)組元素指針的實(shí)例


在 C 語(yǔ)言里邊,sizeof()可以用來(lái)獲取括號(hào)內(nèi)的對(duì)象所占用的內(nèi)存字節(jié)數(shù),雖然它寫(xiě)作函數(shù)的形式,但它并不是一個(gè)函數(shù),而是 C 語(yǔ)言的一個(gè)關(guān)鍵字,sizeof()整體在程序代碼中就相當(dāng)于一個(gè)常量,也就是說(shuō)這個(gè)獲取操作是在程序編譯的時(shí)候進(jìn)行的,而不是在程序運(yùn)行的時(shí)候進(jìn)行。這是一個(gè)實(shí)際編程中很有用的關(guān)鍵字,靈活運(yùn)用它可以為程序帶來(lái)更好的可讀性、易維護(hù)性和可移植性,在后續(xù)的例程學(xué)習(xí)中將會(huì)慢慢有所體會(huì)的。


sizeof()括號(hào)中可以是變量名,也可以是變量類(lèi)型名,其結(jié)果是等效的。而其更大的用處是與數(shù)組名搭配使用,這樣可以獲取整個(gè)數(shù)組占用的字節(jié)數(shù),就不用自己動(dòng)手計(jì)算了,可以避免錯(cuò)誤,而如果日后改變了數(shù)組的維數(shù)時(shí),也不需要再到執(zhí)行代碼中逐個(gè)修改,便于程序的維護(hù)和移植。


下面我們提供了一個(gè)簡(jiǎn)單的串口演示例程,可以體驗(yàn)一下指針和 sizeof()的用法。例程首先接收上位機(jī)下發(fā)的命令,根據(jù)命令值分別把不同數(shù)組的數(shù)據(jù)回發(fā)給上位機(jī),程序還用到了指針的自增運(yùn)算,也就是+1 運(yùn)算,大家可以認(rèn)真考慮一下指針 ptrTxd 在串口發(fā)送的過(guò)程中的指向是如何變化的。在上位機(jī)串口調(diào)試助手中分別下發(fā) 1、2、3、4,就會(huì)得到不同的數(shù)組回發(fā),注意這里都用十六進(jìn)制發(fā)送和十六進(jìn)制顯示。


此外,這個(gè)程序還應(yīng)用到一個(gè)小技巧,大家要學(xué)會(huì)使用。我們前邊講了串口發(fā)送中斷標(biāo)志位 TI 是硬件置位,軟件清零的。通常來(lái)講,我們想一次發(fā)送多個(gè)數(shù)據(jù)的時(shí)候,就需要把第一個(gè)字節(jié)寫(xiě)入 SBUF,然后再等待發(fā)送中斷,在后續(xù)中斷中再發(fā)送剩余的數(shù)據(jù),這樣我們的數(shù)據(jù)發(fā)送過(guò)程就被拆分到了兩個(gè)地方——主循環(huán)內(nèi)和中斷服務(wù)函數(shù)內(nèi),無(wú)疑就使得程序結(jié)構(gòu)變得零散了。這個(gè)時(shí)候,為了使程序結(jié)構(gòu)盡量緊湊,在啟動(dòng)發(fā)送的時(shí)候,不是向 SBUF 中寫(xiě)入第一個(gè)待發(fā)的字節(jié),而是直接讓 TI=1,注意,這時(shí)候會(huì)馬上進(jìn)入串口中斷,因?yàn)橹袛鄻?biāo)志位置 1 了,但是串口線(xiàn)上并沒(méi)有發(fā)送任何數(shù)據(jù),于是,我們所有的數(shù)據(jù)發(fā)送都可以在中斷中進(jìn)行,而不用再分為兩部分了。大家可以在程序中體會(huì)一下這個(gè)技巧的好處。

純文本復(fù)制

#include

bit cmdArrived = 0; //命令到達(dá)標(biāo)志,即接收到上位機(jī)下發(fā)的命令

unsigned char cmdIndex = 0; //命令索引,即與上位機(jī)約定好的數(shù)組編號(hào)

unsigned char cntTxd = 0; //串口發(fā)送計(jì)數(shù)器

unsigned char *ptrTxd; //串口發(fā)送指針

unsigned char array1[1] = {1};

unsigned char array2[2] = {1,2};

unsigned char array3[4] = {1,2,3,4};

unsigned char array4[8] = {1,2,3,4,5,6,7,8};

void ConfigUART(unsigned int baud);

void main(){

EA = 1; //開(kāi)總中斷

ConfigUART(9600); //配置波特率為 9600

while (1){

if (cmdArrived){

cmdArrived = 0;

switch (cmdIndex){

case 1:

ptrTxd = array1; //數(shù)組 1 的首地址賦值給發(fā)送指針

cntTxd = sizeof(array1); //數(shù)組 1 的長(zhǎng)度賦值給發(fā)送計(jì)數(shù)器

TI = 1; //手動(dòng)方式啟動(dòng)發(fā)送中斷,處理數(shù)據(jù)發(fā)送

break;

case 2:

ptrTxd = array2;

cntTxd = sizeof(array2);

TI = 1;

break;

case 3:

ptrTxd = array3;

cntTxd = sizeof(array3);

TI = 1;

break;

case 4:

ptrTxd = array4;

cntTxd = sizeof(array4);

TI = 1;

break;

default:

break;

}

}

}

}

/* 串口配置函數(shù),baud-通信波特率 */

void ConfigUART(unsigned int baud){

SCON = 0x50; //配置串口為模式 1

TMOD &= 0x0F; //清零 T1 的控制位

TMOD |= 0x20; //配置 T1 為模式 2

TH1 = 256 - (11059200/12/32)/baud; //計(jì)算 T1 重載值

TL1 = TH1; //初值等于重載值

ET1 = 0; //禁止 T1 中斷

ES = 1; //使能串口中斷

TR1 = 1; //啟動(dòng) T1

}

/* UART 中斷服務(wù)函數(shù) */

void InterruptUART() interrupt 4{

if (RI){ //接收到字節(jié)

RI = 0; //清零接收中斷標(biāo)志位

cmdIndex = SBUF; //接收到的數(shù)據(jù)保存到命令索引中

cmdArrived = 1;//設(shè)置命令到達(dá)標(biāo)志

}

if (TI){ //字節(jié)發(fā)送完畢

TI = 0; //清零發(fā)送中斷標(biāo)志位

if (cntTxd > 0){ //有待發(fā)送數(shù)據(jù)時(shí),繼續(xù)發(fā)送后續(xù)字節(jié)

SBUF = *ptrTxd; //發(fā)出指針指向的數(shù)據(jù)

cntTxd--; //發(fā)送計(jì)數(shù)器遞減

ptrTxd++; //發(fā)送指針遞增

}

}

}


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀(guān)點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶(hù)希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱(chēng),數(shù)字世界的話(huà)語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱(chēng)"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉