程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++ 指針 -算術運算

C++ 指針 -算術運算

編輯:C++入門知識

指針可以加上或減去一個整數。指針的這種運算的意義和通常的數值的加減運算的意義是不一樣的,以字節為單位。

 

[cpp]
char a[20]; 
int *ptr=(int *)a;//強制類型轉換並不會改變a的類型  
ptr++; 

char a[20];
int *ptr=(int *)a;//強制類型轉換並不會改變a的類型
ptr++;
  在上例中,指針ptr的類型是int*,它指向的類型是int,它被初始化為指向整型變量a。接下來的第3句中,指針ptr被加了1,編譯器是這樣處理的:它把指針ptr的值加上了sizeof(int),在32位程序中,是被加上了4,因為在32位程序中,int占4個字節。由於地址是用字節做單位的,故ptr所指向的地址由原來的變量a的地址向高地址方向增加了4個字節。

        由於char類型的長度是一個字節,所以,原來ptr是指向數組a的第0號單元開始的四個字節,此時指向了數組a中從第4號單元開始的四個字節。


  我們可以用一個指針和一個循環來遍歷一個數組,看例子:


[cpp] 
int array[20]={0}; 
int *ptr=array; 
for(i=0;i<20;i++) 

 (*ptr)++;//單元的值+1  
 ptr++;//指向下一個單元  

int array[20]={0};
int *ptr=array;
for(i=0;i<20;i++)
{
 (*ptr)++;//單元的值+1
 ptr++;//指向下一個單元
}

 

  這個例子將整型數組中各個單元的值加1。由於每次循環都將指針ptr加1個單元,所以每次循環都能訪問數組的下一個單元。

  再看例子:


[cpp] 
   char a[20]="You_are_a_girl"; 
   int *ptr=(int *)a;  
  ptr+=5; 

   char a[20]="You_are_a_girl";
   int *ptr=(int *)a;
  ptr+=5;

 

  在這個例子中,ptr被加上了5,編譯器是這樣處理的:將指針ptr的值加上5乘sizeof(int),在32位程序中就是加上了5乘4=20。由於地址的單位是字節,故現在的ptr所指向的地址比起加5後的ptr所指向的地址來說,向高地址方向移動了20個字節。在這個例子中,沒加5前的ptr指向數組a的第0號單元開始的四個字節,加5後,ptr已經指向了數組a的合法范圍之外了。雖然這種情況在應用上會出問題,但在語法上卻是可以的。這也體現出了指針的靈活性。

  如果上例中,ptr是被減去5,那麼處理過程大同小異,只不過ptr的值是被減去5乘sizeof(int),新的ptr指向的地址將比原來的ptr所指向的地址向低地址方向移動了20個字節。

       下面請允許我再舉一個例子:(一個誤區)


[cpp] 
#include<stdio.h>  
int main() 

char a[20]=" You_are_a_girl"; 
char *p=a; 
char **ptr=&p; 
  
//printf("p=%d\n",p);                                                                                           
//printf("ptr=%d\n",ptr);         
//printf("*ptr=%d\n",*ptr);  
printf("**ptr=%c\n",**ptr); 
  
ptr++; 
  
//printf("ptr=%d\n",ptr);  
//printf("*ptr=%d\n",*ptr);  
printf("**ptr=%c\n",**ptr); 

#include<stdio.h>
int main()
{
char a[20]=" You_are_a_girl";
char *p=a;
char **ptr=&p;
 
//printf("p=%d\n",p);                                                                                        
//printf("ptr=%d\n",ptr);      
//printf("*ptr=%d\n",*ptr);
printf("**ptr=%c\n",**ptr);
 
ptr++;
 
//printf("ptr=%d\n",ptr);
//printf("*ptr=%d\n",*ptr);
printf("**ptr=%c\n",**ptr);
}

 

 

誤區一、輸出答案為Y和o

誤解:ptr是一個char的二級指針,當執行ptr++;時,會使指針加一個sizeof(char),所以輸出如上結果,這個可能只是少部分人的結果.

誤區二、輸出答案為Y和a

誤解:ptr指向的是一個char *類型,當執行ptr++;時,會使指針加一個sizeof(char *)(有可能會有人認為這個值為1,那就會得到誤區一的答案,這個值應該是4,參考前面內容), 即&p+4;那進行一次取值運算不就指向數組中的第五個元素了嗎?那輸出的結果不就是數組中第五個元素了嗎?答案是否定的.

正解: ptr的類型是char**,指向的類型是一個char *類型,該指向的地址就是p的地址(&p),當執行ptr++;時,會使指針加一個sizeof(char*),即&p+4;那*(&p+4)指向哪呢,這個你去問上帝吧,或者他會告訴你在哪?所以最後的輸出會是一個隨機的值,或許是一個非法操作.

 

總結一下:

一個指針ptrold加(減)一個整數n後,結果是一個新的指針ptrnew,ptrnew的類型和ptrold的類型相同,ptrnew所指向的類型和ptrold所指向的類型也相同。ptrnew的值將比ptrold的值增加(減少)了n乘sizeof(ptrold所指向的類型)個字節。就是說,ptrnew所指向的內存區將比ptrold所指向的內存區向高(低)地址方向移動了n乘sizeof(ptrold所指向的類型)個字節。

 

指針和指針進行加減:

兩個指針不能進行加法運算,這是非法操作,因為進行加法後,得到的結果指向一個不知所向的地方,而且毫無意義。兩個指針可以進行減法操作,但必須類型相同,一般用在數組方面,不多說了。


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved