c++指针总结(易混淆)
生活随笔
收集整理的這篇文章主要介紹了
c++指针总结(易混淆)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一:指針的概念指針是一個特殊的變量,里面存儲的數值是內存里的一個地址。學好指針,重要的是搞清楚指針的四個方面的內容:指針的類型、指針所指向的類型、指針所指向的內存區、指針本身占據的內存區。1、 如何判斷指針的類型呢:12345int *p;char *p;int **p;int (*p)[3];int *(*p)[4];上面的五個聲明,指針的類型分別是:int *、char *、int ** 、 int (*)[3]、int *(*)[4];是不是非常簡單,就是把變量名去掉,剩下的就是指針的類型。2、指針所指向的類型12345int *p;char *p;int **p;int (*p)[3];int *(*p)[4];上面五個聲明,指針所指向的類型分別是:int\char \int *\int()[3]\int *()[4],找出規律了嗎?就是把變量名和一個*去掉,剩下的就是指針所指向的類型。特別強調:指針的類型和指針所指向的類型是不同的概念。3、指針所指向的內存區或者指針的值指針的值是指針本身所存儲的數值,這個值被編譯器當作一個地址,而不是而不是一個一般的數值。在32位程序里,所有的類型的指針的值都是一個32位數,因為32位程序中內存地址全部都是32位字長。指針所指向的內存區就是從指針的值所代表的內存區開始,長度為sizeof(指針所指向的類型)的一篇內存區。以后,我們說一個指針的值是XX,就代表了該指針指向了以XX為首地址的一片內存區域;我們說一個指針指向了某個內存區域,相當于指針的值就是該內存區域的首地址。指針指向誰,就把誰的地址賦給指針。4、指針本身所占據的內存區指針本身占據了多大的內存。用sizeof(指針的類型)測試一個就知道了。在32位平臺里,指針本身占據了四個字節的長度。二、指針的算術運算123char a[20];int *p=a;p++;指針p的類型是 int * ,指針所指向的類型是int ,它被初始化位指向整形變量a,接下來指針p被加了1,編譯器是這樣處理的:它把指針p的值加上了sizeof(int),在32位程序里,是加上了4.由于地址是用字節做單位的,故p的地址由原來的a的地址指向了加四個字節后的高地址。由于char類型的長度是一個字節,所以原來p是指向數組從0開始的四個字節,現在指向了從第四個字節開始的四個字節我們可以用一個指針和一個循環來遍歷一個數組:12345678int arr[20];int *p=arr;.......//此處略去整數型賦值的代碼for(i = 0; i<20 ; i++){(*p)++;P++; ? ? ? ?}這個例子將整數型數組各個單元的值加1,由于每次循環都將指針p,所以每次循環都能訪問數組的下一個單元。12345char a[20];int *p=a;......p+=5;在這個例子中,p被加上了5,從編譯器的角度看:將指針p的值加上sizeof(int),在32位恒旭中就是加上了5*4=20.由于地址的單位十字街,故現在p指向剛開始高字節方向的20個字節。在這個例子中,沒加5之前的p指向數組第0個單元開始的四個字節,加5后,p已經指向數組的合法范圍之外了。雖然這種情況在應用上會出現問題,但在語法上是可以。這體現了指針的靈活性。總結一下:一個指針,加上一個整數n后,結果是一個新的指針pnew,pnew的類型和pnew所指向的類型與pold的類型都是一樣的。pnew的值比起pold的值增加了n*sizeof(p指向的類型)個字節。加是往高字節移動,減是往低字節移動。三運算符&和*&是取地址運算符,*在書上叫做間接運算符。&a的運算結果是一個指針,指針的類型是a的類型加一個*。指針所指向的類型是a的類型,指針所指向的地址就是a的地址。*p的結果是p所指向的結果,類型是p的類型,占用的地址就是p所指向的地址123456789101112int a =12;int b;int *p;int *ptr;p=&a//&a的結果是一個指針,指針的類型是一個int *,指針所指向的數據類型是int ,指向的地址是a的地址。*p=24;//*p的結果,它的類型是int,它所占用的地址是p所指向的地址,顯然*p就是變量a*ptr=&P;//p本身就是一個指針了,對p在取地址,那么 該指針的類型是int **,指針所知下個的類型是 int * 。指針所指向的地址就是p的地址**ptr=34;// *ptr的結果就是ptr所指向的東西。在這里是一個指針,對這個指針在做一次*運算,。結果就是一個int 類型的變量四指針表達式一個表達式的最后結果如果是一個指針,這個表達式就叫做指針表達式1234567891011121314151617int a ,b ;int array[10];int *pa;pa=&a;//指針表達式int **ptr = &pa;//表達式*ptr=&b;//表達式pa=array;pa++;//表達式char arr[20];char **parr =arr//如果把arr看作指針的話,arr也是指針表達式char *str;str=*parr;//指針表達式str=*(parr+1);//指針表達式由于指針表達式的結果是一個指針,所以指針表達式也需要具有指針的四個要素:指針的類型,指針所指向的類型、指針指向的內存區、指針自身占據的內存區。指針在左邊表示賦值,指針在右邊表示取值。五、數組和指針的關系12345678int array[10] = {0,1,2,3,4,5,6,7,8,9},value;......value = array[0];//也可以寫成 value = *array;value = array[3];//也可以寫成 value = *(array+3);value = array[4];//也可以寫成 value = *(array+4);上例中,一般而言,數組名array代表數組本身,類型是int[10];如果把array看作指針的話,它指向數組的第0個單元,類型是int *,所指向的類型是數組單元的類型 int ,因此*array = 0 就一點也不奇怪了。同理,(array+3)指向數組單元的第三個指針,所以*(array+3) = 3 ;123456789char *str[3] = {"Hellp,this is a sample","Hi ,good morning ","Hello world"};char s[80];strcpy(s,str[0]);//也可以寫成 strcpy(s,*str);strcpy(s,str[1]);//也可以寫成strcpy(s,*(str+1));上例中,str是一個三單元的數組,該數組的每個單元都是一個指針,這些指針每個都指向一個字符串,如果把數組名看作指針的話,它指向數組的第0號元素,類型是char** ,指向的類型是 char *;*str 也是一個指針,它的類型是char*,指向的類型是char ,它指向的地址是字符串 “Hello,this is a sample”的第一個字符H的地址。*(str+1)也是一個指針,他的類型是char*,指向的類型是char,指向“Hi,good morning”的第一個字符H的地址。在不同的表達式中,數組名array可以扮演不同的角色 。在表達式sizeof(array)數組名array 代表數組本身,故測出的是整個數組的大小。在表達式*array中,array扮演的是一個指針,所以該表達式就是數組第0號單元的值。sizeof(*array)測出的是數組單元的大小。表達式array+n,array扮演的是指針,故array+n也是指針,他的類型是type*,指向的類型是type,指向數組第n號單元,故sizeof(array+n)測出的是指針類型的大小。六、指針和結構類型的關系1234567891011struct mystruct{int a ;int b;int c; ? ? ? ? ?}mystruct ss = {20,30,40};mystruct *ptr = &ss;//聲明了一個指向結構對象ss的指針,它的類型是myStruct * ,指向的類型是mystructint *pstr = (int *)&ss//聲明了一個指向結構對象ss的指針。但是他的類型和它指向的類型和ptr是不同的,請問如何通過指針ptr來訪問ss的三個成員變量答案:12345678910ptr ->a;ptr ->b;ptr ->c;請問如何通過指針pstr來訪問ss的三個成員變量答案*pstr;*(pstr+1);*(pstr+2);這樣使用pstr來訪問結構成員是不正規的。那么該怎么樣來通過指針訪問數組的各個單元呢?123456int array[3]={35,56,37};int *pa = array;//通過指針pa訪問數組array的三個單元的方法是:*pa;*(pa+1);*(pa+2);從格式上看倒是與通過指針訪問結構成員的不正規方法的格式一樣.所有的C/C++編譯器在排列數組的單元時,總是把各個數組單元存放在連續的存儲區里,單元和單元之間沒有空隙。但在存放結構對象的各個成員時,在某種編譯環境下,可能會需要字對齊或雙字對齊或者是別的什么對齊,需要在相鄰兩個成員之間加若干個“填充字節”,這就導致各個成員之間可能會有若干個字節的空隙。所以,在例十二中,即使*pstr訪問到了結構對象ss的第一個成員變量a,也不能保證*(pstr+1)就一定能訪問到結構成員b。因為成員a和成員b之間可能會有若干填充字節,說不定*(pstr+1)就正好訪問到了這些填充字節呢。這也證明了指針的靈活性。要是你的目的就是想看看各個結構成員之間到底有沒有填充字節,嘿,這倒是個不錯的方法。
總結
以上是生活随笔為你收集整理的c++指针总结(易混淆)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 尖刀剧情介绍
- 下一篇: 成都大熊猫繁育研究基地电子票怎么退