【C語言】指標的算術運算(指標+/-整數、指標+/-指標)

文章推薦指數: 80 %
投票人數:10人

那問題就來了,是不是對指標的任何運算都是合法的呢? 答案是它可以執行某些運算,但並 非所有的運算都合法 。

(指標可以進行加減法,對於乘除 ... 程式人生>>【C語言】指標的算術運算(指標+/-整數、指標+/-指標) 【C語言】指標的算術運算(指標+/-整數、指標+/-指標) 阿新••發佈:2018-11-06 一、指標+/-整數  在之前學習指標時,我們知道指標其實也是一種特殊的變數,既然這樣,那麼指標應該和普通變數一樣,可以進行算術運算。

那問題就來了,是不是對指標的任何運算都是合法的呢? 答案是它可以執行某些運算,但並非所有的運算都合法。

(指標可以進行加減法,對於乘除法是非法的) 指標+/-整數是另一個指標,問題又來了:那它是怎樣加的呢?怎樣減的呢? 接下來介紹一個例項: #include intmain() { intarr[10]={1,2,3,4}; int*p=arr; *p=10; printf("%d\n",*p); p++; *p=20; printf("%d\n",*p); return0; } 執行結果為: 關於上述例項中的p++,可能會有以下三種情況:    1.加一個數組;    2.加一個位元組;    3.加一個單元格。

接下來我們一起來分析一下指標加一到底表示什麼 猜想1.加一個數組 這種情況是無意義的。

使用指標的目的就是訪問陣列內的元素,若為加一個數組,則直接到陣列的後一個地址,並沒有訪問陣列內元素,所以這種情況可以排除。

猜想2.加一個位元組 就上述例子,我們定義了一個整形陣列arr,p指向陣列首地址。

假設其首地址為1000,每一個單元格佔4個位元組則整個陣列對應的地址如下:                                                  圖1陣列arr對應的地址  *p=10,是將陣列首元素的值改為10:                                                      圖2將陣列首元素的值改為10 我們把前兩個單元格用位元組的形式畫出。

十進位制的10轉化為十六進位制為0xa,arr[0]佔用4個位元組,也就是8位,即0x0000000a,同理我們可知十進位制的2轉化為十六進位制為0x00000002。

又由於電腦使用的小端儲存,即低地址存放小資料,如下圖所示:                                                          圖3arr[0]、arr[1]位元組儲存 當p為加一個位元組時,將*p賦值為20,十六進位制為0x00000014,則如下圖4所示:                                                              圖4假設p加一個位元組,賦值為20 此時arr[0]的值為0x140a,轉化為十進位制為5130。

arr[1]=0,顯然與我們想要的結果不符,所以這種情況也可以排除。

猜想3.加一個單元格  當p向後加一個單元格,即指向arr[1],則將arr[1]修改為20,如圖5所示:                                                                    圖5p向後移動一個單元格後賦值 將arr[0]和arr[1]轉化為十進位制分別為10,20,此時結果才是正確的。

說明對於整型指標p++,應為加一個單元格,也就是四個位元組。

進而可推廣指標+整數的表示含義,地址需要調整,調整的權重為sizeof(指標去掉一個*) 接下來通過一些例項驗證一下這個推論: #include intmain() { int*p=(int*)1000; printf("%d\n",p+4);//1016 printf("%d\n",(short*)p+4);//1008 printf("%d\n",(unsignedlong*)p+4);//1016 printf("%d\n",(double*)p+4);//1032 printf("%d\n",(char***)p+4);//1016 printf("%d\n",(char*)p+4);//1004 printf("%d\n",(longlong)p+4);//1004 return0; } 執行結果:    指標-整數和指標+整數是同一個運算規則 指標-整數例項演示: #include intmain() { //指標減數字  int*p=(int*)0x1010;//定義一個整型指標變數p賦值為16進位制數0x1010  printf("%x\n",p-1);//100c 去掉一個*,屬於int型,sizeof()是4,1010-4=100c(注意是16進位制數)  printf("%x\n",p-2);//1008  printf("%x\n",(short*)p-2);//100c   printf("%x\n",(char*)p-2);//100e   printf("%x\n",(double*)p-2);//1000  printf("%x\n",(float*)p-2);//1008  printf("%x\n",(longlong)p-2);//100e 不是指標變數,所以不用求sizeof(),直接-2  printf("%x\n",(double**)p-2);//1008  printf("%x\n",(char**)p-2);//1008 去掉一個*,還屬於指標變數,sizeof()是4   } 執行結果:    二、指標+/-指標  1、指標+指標 由於指標加指標的值是一個相對於原陣列地址相差較大的數值,該數值很有可能超越了我們所定義的陣列的右邊界,這樣獲得的地址值將是一個“盲值”,雖然它確實存在,但我們不能對這個地址做任何處理,因為我們無法得知這個位置原先儲存的是什麼變數,所以我們認為這是個非法的。

2、指標-指標 只有當兩個指標都指向同一個陣列中的元素時,才允許從一個指標減去連一個指標。

兩個指標相減的結果型別是ptrdiff_t,它是一種有符號整數型別。

減法運算的值是兩個指標在記憶體中的距離(該距離以間隔的單元格數為單位,而不是以位元組為單位)。

演算法步驟:1、求出間隔的位元組數   2、將其除以調整的權重 例項演示: #include intmain() {  intarr[10]={0};//x  int*p=&arr[1];//x+4  int*q=&arr[9];//x+36  printf("%d\n",p-q);//-8  間隔的位元組數為(1 - 9)*4=-32,sizeof()是4,-32/4=-8  printf("%d\n",q-p);//8  printf("%d\n",(short*)q-(short*)p);//16 32/2=16  printf("%d\n",(char**)q-(char**)p);//8  32/4=8  printf("%d\n",(double*)q-(double*)p);//4  printf("%d\n",(long*)q-(long*)p);//8  printf("%d\n",(char*)q-(char*)p);//32  printf("%d\n",(longlong)q-(longlong)p);//32 非指標不需調整  //printf("%d\n",(int*)q-(short*)p);//error  return0; } 執行結果: 注意:不同型別的指標不允許相減 活著的言論 «上一篇 linux如何新增使用者(組)及下放許可權下一篇» 相關推薦 C語言關鍵字及運算符操作 oat分享限定改變tructbce基本blogcol1、數據類型與變量的本質 數據類型:數據類型可以理解... C語言基礎篇(二)運算子 導航:   2.1算數運算子   2.2邏輯運算子   2.3位運算   2.4賦值... c語言實現積分運算 用指標實現,最好先明白*p[4]和(*p)[4]的區別 int*p[4];//定義一個指標陣列,該陣列中每個元素是一個指標,每個指標指向哪裡就... 【C語言】使用異或運算子交換兩個數 異或交換兩個數: #include #include intmain() { i... C語言if、for、goto、位運算、位段、函式(2018.11.18) if語句 if(表示式) { 語句1; } else { 語句2; } 在使用if語句判斷條件的時候要注意符號的結合性eg:... C語言資料型別,運算子與表示式 1.C語言的關鍵字 32個關鍵字: auto:自動宣告   break:跳出當前迴圈 &nb... C語言知識點(3)-運算子與表示式 運算子與表示式 算數運算子 算術:+,-,*,/,%  考試一定要注意:“/”兩邊都是整型的話,結果就是一個整型。

3/2的結... 彙編:實現C語言的||與&&運算 ;C程式轉匯編(或運算連結) DATASSEGMENT aDw5 bdw6 ccdw7 ddw8 mdw2 ndw2 str... C語言中的自增運算 main(){inti=5,j=5,p,q;p=(i++)+(i++)+(i++);q=(++j)+(++j)+(++... C語言通過邏輯運算(與或非)實現加法 1.加法器:首先看看下面的內容,瞭解一下什麼是加法... 搜尋 基礎教學 Mysql入門 Sql入門 Android入門 Docker入門 Go語言入門 Ruby程式入門 Python入門 Python進階 Django入門 Python爬蟲入門 最近訪問 【C語言】指標的算術運算(指標+/-整數、指標+/-指標) 讓嵌入式工程師毛骨悚然的掉電丟資料事故可以這樣解決! centos+7+ssh免密碼登入 JAVA反射改動常量,以及其局限 Android+Studio:基本UI介面設計+(詳細) CE修改器使用教程+[提高篇] BZOJ+3585&&3339+靜態區間mex【主席樹】 SQL語句刪除具有外來鍵約束(foreign+key)的表。

錯誤提醒:無法刪除物件+'表名',因為該物件正由一個+FOREIGN+KEY+約束引用。

bzoj+4327:JSOI2012+玄武密碼 Android開發之實現最簡單最酷炫的3D圖片瀏覽效果(二)



請為這篇文章評分?