指標加減運算和printf輸出與自加自減運算順序

2021-06-12 22:12:01 字數 2015 閱讀 4772

為了驗證指標加減運算時是移動乙個位元組還是移動指標所指向資料型別的位元組長度。我們用一下程式即可驗證。

1	int a = 0;

2 int* pa = &a;

34 printf("%d \n",(int)pa);

5 pa ++ ;

6 printf("%d \n",(int)pa);

7 printf("int %d %d \n",(int)pa,(int)(pa++));

由此可知 指標加減運算移動單位為指標所指向資料型別的位元組長度。

遇到的問題 :

以上程式的輸出為:

由第7行的輸出可知:printf入棧為自右往左, (int)(pa++) 先將引數入棧,再++,而後在對(int)pa入棧時,之前以++過一次,所以輸出結果如上。

若將第7行**改為  printf("int %d %d \n",(int)pa,(int)(++pa)); 則輸出為   x,x+4,x+8,x+8。原理同上。

更進一步的看乙個例子:

int arr=;

int *ptr=arr;

printf("%d,%d,%d",*ptr,*(++ptr),*(ptr--));

在win32 vs2010中輸出結果為:6,6,6

其原理為:先執行最右邊的引數入棧,及 *(ptr),然後執行ptr- -;再執行中間引數入棧,及 ptr + +,然後*(ptr);最後執行最左邊的引數入棧,及*(ptr)。所以結果為6,6,6.

但有人說這個執行順序與編譯器和環境相關。本人尚未測試,有興趣的可以自行測試。以上資料測試環境皆在 win32 vs2010中所得。如有疑問,可以共同**。

續0:

int arr=;

int *ptr=arr;

printf("%d,%d",*(++ptr),*(ptr));

同一環境下,輸出結果為:7,7。

若 用上面的原理解釋,答案應該為7,6。實際結果與之前解釋的相悖。求大神們指點。

續1:若將一指標進行,強制轉換,這指標的定址是按照原來的型別還是轉換後的型別:

char bbb[4]="0000";

int aaa = 0xf11ff22f;

int *abc = &aaa;

bbb[0] = ((char *)abc)[0];

bbb[1] = ((char *)abc)[1];

bbb[2] = ((char *)abc)[2];

bbb[3] = ((char *)abc)[3];

printf("%d %d %d %d\n",bbb[0],bbb[1],bbb[2],bbb[3]);

輸出結果:47 -14 31 -15;

以十六進製制表示下列數 0x2f 0xf2 0x1f 0xf1

若將輸出改為以十六進製制輸出:

printf("%x %x %x %x\n",bbb[0],bbb[1],bbb[2],bbb[3]);
則輸出結果為:2f fffffff2 1f fffffff1

由上結果可以知道,指標強制轉換後,定址按照轉換以後的型別進行定址。即 int * 變為 char * 後,指標加1時,只移動1個位元組。

對於 %x的輸出,因為其預設為整型數的輸出,所以負數高位全為1,所以 -14的輸出為 fffffff2。

在此基礎上,聯想到opencv 中iplimage的資料賦值問題。imagedata指標型別為char *;

1.對於ipl_depth_8u的影象資料來說,取值和賦值都很簡單,直接按位元組進行賦值或取值即可,注意自動填充的冗餘位元組數。

2.對於不是ipl_depth_8u的影象資料。例如ipl_depth_16u。

當賦值時,將原始 short 型別的資料指標強制轉換為char*,逐個位元組賦值即可。

當取值時,直接將char * imagedata 強制裝換為 short * ,逐點賦值即可。

指標加減運算

include include 字元陣列 指標是4位元組 指標 指標 錯誤 指標之間相加無限大,記憶體崩潰,所以指標 指標是不可能 指標 指標 得到之間間隔的單元個數。1 算出間隔的位元組數,2 除以調整的權重 int main x 可以設arr的起始位址是x int p arr 1 x 4 指標是...

指標加減運算 void 的加減

大家都知道對於一般的指標,比如int 等,其加減運算是以元素的大小為單位的。unsigned int s unsigned int 0x1234 cout s 1 endl cout s 1 endl 其結果分別是 0x1238,0x1230 分別加減了乙個unsigned int的大小,也就是4個...

printf和標準輸出

printf和標準輸出 printf和標準輸出 上次寫到main函式的引數傳遞.現在繼續往下進行.最近忙實驗室的事情,看了一周 的文章,也沒啥進展,週末寫點技術貼,放鬆一下 進入main函式後,就要呼叫printf hello world 了.順便將c語言引數傳遞提 一下.字串 hello worl...