您好,登錄后才能下訂單哦!
所謂指向數組元素的指針,其實質照樣變量的指針。由于數組中的每一個元素,其實都可以直接算作是一個變量,所以指向數組元素的指針,也就是變量的指針。
指向數組元素的指針不難,但很常用。我們用程序來說明會比擬直不雅一些。
unsigned char number[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; unsigned char *p;
假如我們寫 p = &number[0];那么指針 p 就指向了 number 的第 0 號元素,也就是把number[0]的地址賦值給了 p,同理,假如寫 p = &number[1];p 就指向了數組 number 的第 1號元素。p = &number[x];個中 x 的取值規模是 0~9,就表現 p 指向了數組 number 的第 x 號元素。指針自身,也可以停止幾種復雜的運算,這幾種運算關于數組元素的指針來說使用最多。
比擬運算。比擬的前提是兩個指針指向同品種型的對象,比方兩個指針變量 p 和 q它們指向了具有同種數據類型的數組,那它們可以停止 <,>,>=,<=,==等關系運算。假如 p==q 為真的話,表現這兩個指針指向的是統一個元素。
指針和整數可以直接停止加減運算。比方照樣上邊我們誰人指針 p 和數組 number,假如 p = &number[0],那么 p+1 就指向了 number[1],p+9 就指向了 number[9]。當然了,假如 p = &number[9],p-9 也就指向了 number[0]。
兩個指針變量在必定前提下可以停止減法運算。如 p = &number[0]; q = &number[9];那么 q-p 的后果就是 9。然則這個中央人人要特殊留意,這個 9 代表的是元素的個數,而不是真正的地址差值。假如我們的 number 的變量類型是 unsigned int 型,占 2 個字節,q-p 的后果仍然是 9,由于它代表的是數組元素的個數。
在數組元素指針這里還有一種狀況,就是數組名字其實就代表了數組元素的首地址,也就是說:
p = &number[0]; p = number;
這兩種表達方法是等價的,因而以下幾種表達方式和內容需求人人非分特別留意一下。
依據指針的運算規矩,p+x 代表的是 number[x]的地址,那么 number+x 代表的也是number[x]的地址。或許說,它們指向的多是 number 數組的第 x 號元素。
*(p+x)和*(number+x)都表現 number[x]。
指向數組元素的指針也可以表現成數組的方式,也就是說,許可指針變量帶下標,即 p[i]和*(p+i)是等價的。然則為了防止混雜與標準起見,這里我們建議人人不要寫成前者,而一概采取后者的寫法。但假如看到他人那么寫,也曉得是怎樣回事即可。
二維數組元素的指針和一維數組相似,需求引見的內容不多。假設如今一個指針變量 p和一個二維數組 number[3][4],它的地址的表達方法也就是 p=&number[0][0],有一個中央要留意,既然數組名代表了數組元素的首地址,那么也就是說 p 和 number 多是指數組的首地址。對二維數組來說,number[0],number[1],number[2]都可以算作是一維數組的數組名字,所以 number[0]等價于 &number[0][0], number[1]等價于 &number[1][0], number[2]等價于&number[2][0]。加減運算和一維數組是相似的,不再臚陳。
在 C 言語里邊,sizeof()可以用來獲取括號內的對象所占用的內存字節數,固然它寫作函數的方式,但它并不是一個函數,而是 C 言語的一個癥結字,sizeof()全體在程序代碼中就相當于一個常量,也就是說這個獲取操作是在程序編譯的時分停止的,而不是在程序運轉的時分停止。這是一個實踐編程中很有效的癥結字,靈敏應用它可認為程序帶來更好的可讀性、易保護性和可移植性,在后續的例程進修中將會漸漸有所領會的。
sizeof()括號中可所以變量名,也可所以變量類型名,其后果是等效的。而其更大的用途是與數組名搭配運用,如許可以獲取全部數組占用的字節數,就不必本人入手盤算了,可以防止毛病,而假如日后改動了數組的維數時,也不需求再到履行代碼中逐一修正,便于程序的保護和移植。
下面我們供給了一個復雜的串口演示例程,可以體驗一下指針和 sizeof()的用法。例程起首接納上位機下發的敕令,依據敕令值辨別把分歧數組的數據回發給上位機,程序還用到了指針的自增運算,也就是+1 運算,人人可以仔細思索一下指針 ptrTxd 在串口發送的進程中的指向是若何變更的。在上位機串口調試助手平分別下發 1、2、3、4,就會失掉分歧的數組回發,留意這里都用十六進制發送和十六進制顯示。
此外,這個程序還使用到一個小技能,人人要學會運用。我們前邊講了串口發送中綴標記位 TI 是硬件置位,軟件清零的。平日來講,我們想一次發送多個數據的時分,就需求把第一個字節寫入 SBUF,然后再等候發送中綴,在后續中綴中再發送殘剩的數據,如許我們的數據發送進程就被拆分到了兩個中央——主輪回內和中綴效勞函數內,無疑就使得程序構造變得零碎了。這個時分,為了使程序構造盡量緊湊,在啟動發送的時分,不是向 SBUF 中寫入第一個待發的字節,而是直接讓 TI=1,留意,這時分會立時進入串口中綴,由于中綴標記地位 1 了,然則串口線上并沒有發送任何數據,于是,我們一切的數據發送都可以在中綴中停止,而不必再分為兩局部了。人人可以在程序中領會一下這個技能的益處。
純文本復制
#include <reg52.h> bit cmdArrived = 0; //敕令抵達標記,即接納到上位機下發的敕令 unsigned char cmdIndex = 0; //敕令索引,即與上位機商定好的數組編號 unsigned char cntTxd = 0; //串口發送計數器 unsigned char *ptrTxd; //串口發送指針 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; //開總中綴 ConfigUART(9600); //設置裝備擺設波特率為 9600 while (1){ if (cmdArrived){ cmdArrived = 0; switch (cmdIndex){ case 1: ptrTxd = array1; //數組 1 的首地址賦值給發送指針 cntTxd = sizeof(array1); //數組 1 的長度賦值給發送計數器 TI = 1; //手動方法啟動發送中綴,處置數據發送 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; } } } } /* 串口設置裝備擺設函數,baud-通訊波特率 */ void ConfigUART(unsigned int baud){ SCON = 0x50; //設置裝備擺設串口為形式 1 TMOD &= 0x0F; //清零 T1 的掌握位 TMOD |= 0x20; //設置裝備擺設 T1 為形式 2 TH1 = 256 - (11059200/12/32)/baud; //盤算 T1 重載值 TL1 = TH1; //初值等于重載值 ET1 = 0; //制止 T1 中綴 ES = 1; //使能串口中綴 TR1 = 1; //啟動 T1 } /* UART 中綴效勞函數 */ void InterruptUART() interrupt 4{ if (RI){ //接納到字節 RI = 0; //清零接納中綴標記位 cmdIndex = SBUF; //接納到的數據保管到敕令索引中 cmdArrived = 1;//設置敕令抵達標記 } if (TI){ //字節發送終了 TI = 0; //清零發送中綴標記位 if (cntTxd > 0){ //有待發送數據時,持續發送后續字節 SBUF = *ptrTxd; //收回指針指向的數據 cntTxd--; //發送計數器遞加 ptrTxd++; //發送指針遞增 } } }
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。