C語言學習筆記之指標的運算

Insight2發表於2019-01-24

C語言中指標的運算

/*
  以下實驗是探究當指標不是指向一片連續的空間 
  而是指向陣列時的情況 
  編譯器為TDM-GCC 4.9.2 64-bit Release 
*/
	int a1[]={0,1,5,9,4,}; 為避免偶然 我不按順序排數
	int *p = a1;
	printf("p = %p\n",p);
	printf("p+1 = %p\n",p+1);
	printf("sizeof(int) = %d\n",sizeof(int));//執行之後可以發現p與p+1的差值就是一個 sizeof(int)
	
	double a2[]={0,1,2,3,4,}; 
	double *q = a2;
	printf("q = %p\n",q);
	printf("q+1 = %p\n",q+1);
	printf("sizeof(double) = %d\n",sizeof(double));//同理執行之後可以發現是一個 sizeof(double)
/*
  那為什麼指標加一相當於加一個資料型別長度?
  因為在一個陣列裡,一個元素分為對於資料型別的位元組,
  如果int 一個陣列 一個元素被劃分為4個位元組 指標代表一個地址 
  如果加一不是加一個資料型別長度,而是地址加一,
  那麼加了一之後還是這個元素,就顯得毫無意義,
  所以就設定為加一個資料型別長度,本質上就是移動一個元素下標,移動一個位置
*/ 
	printf("*p = %d\n",*p);  
	printf("a1[0] = %d\n",a1[0]);		// *p = a1 --> *p = a1[0] 那麼*(p+n)等於多少?
	printf("*(p+2) = %d\n",*(p+2));
	printf("a1[2] = %d\n",a1[2]);		//可以看到  *(p+2)==a1[2] 
	printf("*(p+3) = %d\n",*(p+3));
	printf("a1[3] = %d\n",a1[3]);		//可以看到  *(p+3)==a1[3] 
	
	//剛才之所以加括號是因為*是一個單目運算子 優先順序高於()
	//那麼*p+1等於多少??
	printf("*p+1 = %d\n",*p+1);// *p+1=1
	printf("*p+2 = %d\n",*p+2);// *p+2=2
/*
  有無括號是有區別的 
  *(p+n)有括號 此時為地址加n個資料型別長度 因為p是地址 相當於a1[0]移動n個下標
  *p+n   無括號 此時為數值加一 因為*p就是值 相當於就是*p= a1=&a1[0] =0 再加上數值n 而已
  指標可用運算子有
   -,-=,+=,++,--
*/ 
	//那麼指標與指標之間的運算呢?
	int *p1 = &a1[3] ;
	printf("p = %p\n",p);//	p = 000000000062FE20
	printf("p1 = %p\n",p1);//p1 = 000000000062FE2C 
	printf("p1 - p = %d\n",p1-p);//	p1 - p = 3
/*
   兩個十六進位制的地址相減為C C即為十進位制12
   此時p1=9,p=0,顯然p1-p不是兩者差值,那3是什麼?
   3是由地址差值除以資料型別長度得來的 即12/4=3
   那麼這就說明,指標與指標的運算又與指標本身加減是有所不同的
   指標之間的運算是地址之間的運算,這就很有意思了 
*/   	
	//說點題外話
	int array[]={0,1,2,3,4,5,6,-1};
	int *arr = array; 
	while(*arr != -1)
	{
		printf("%d ",*arr++);//結果輸出0,1,2,3,4,5,6 
	}
/*
  指標也可以用作陣列空間的連續操作,這其中還是有歷史故事的。
  C語言初期,電腦執行速度並沒有那麼快,
  當時的*p++,表示可以把c語言程式碼翻譯成機器執行指令, 
  因此程式碼跑起來就更快,這也是指標的來源。 
*/ 

/*
   補充:
   指標是不可以繼續乘除的;
   指標之間也可以比較,實質是地址的比較;
   常用比較運算子,指標也可以使用;
*/ 

相關文章