指標賦值 int a[5]={…. …}, a 、&a[0]、 &a三者之間的區別 淺析 C/C++求職面試必備考點(五) .

來源:互聯網
上載者:User

首先,來看代碼:

[html]
view plaincopyprint?
  1. <SPAN style="FONT-SIZE: 18px">#include <stdio.h>  
  2. void main()  
  3. {  
  4. char a[] = "BruceLee!";  
  5. char *p = a;  
  6. printf("%c\n", *(p+4));  
  7. printf("%c\n", p[4]);  
  8. printf("%s\n", p);  
  9. printf("%c\n", a[4]);  
  10. printf("%c\n", *(a+4));  
  11. printf("%s\n", a);  
  12. }</SPAN>  
#include <stdio.h>void main(){char a[] = "BruceLee!";char *p = a;printf("%c\n", *(p+4));printf("%c\n", p[4]);printf("%s\n", p);printf("%c\n", a[4]);printf("%c\n", *(a+4));printf("%s\n", a);}


首先程式聲明了字元數組a,並且初始化,這個記得是預設後面加'\0'的。然後聲明了字元指標,指向數組a的首地址,也是a[0]的地址,這裡

[html]
view plaincopyprint?
  1. char *p = a; 等價於char *p = &a[0]  
char *p = a; 等價於char *p = &a[0]

。*(p+4) = p[4] = a[4] = *(a+4),這是最終的結果。這裡需要注意的是,字元指標p和數組的名字a每個都有兩種引用方法,一種是數組的引用方法如a[4],一種是*(a+4),指標的方法。

注意這裡的

[html]
view plaincopyprint?
  1. <SPAN style="FONT-SIZE: 18px">printf("%s\n", p);列印的內容仍然是<SPAN style="FONT-SIZE: 18px"></SPAN></SPAN><PRE class=html name="code">BruceLee!</PRE><PRE class=html name="code"></PRE>  
printf("%s\n", p);列印的內容仍然是[html] view plaincopyprint?
 
  1. BruceLee!  
BruceLee!
[html]
view plaincopyprint?
  1.   

也就是說我們僅僅是通過*(p+4),來查看裡面的內容,但並沒有改變p的指向。p仍然指的是首地址,所以列印出的字串也是從首字元開始的。

如果我們再代碼中,加上這兩句:

printf("%c\n", *p++);
printf("%s\n", p);

第一句執行結果是列印首字元‘B’,然後p往後移一位。所以下面一句列印字串,直接從第二個字元開始的,結果是ruceLee。

總結:(*p+4)這種方式並未改變指標p的指向。只有p++、p--或者p+=4類似這種方式,才改變指標p的指向!

下面再來看一個例子:

[cpp]
view plaincopyprint?
  1. <SPAN style="FONT-SIZE: 18px">#include <stdio.h>  
  2. void main()  
  3. {  
  4.     int a[5] = {1, 2 ,3 , 4, 5};  
  5.     int *p = a;  
  6.     printf("%d\n", a[0]);  
  7.    printf("%d\n", *p);  
  8.    printf("%d\n", p);  
  9.    int *q = (int *)a;  
  10.    printf("%d\n", q[0]);  
  11.      
  12. }</SPAN>  
#include <stdio.h>void main(){    int a[5] = {1, 2 ,3 , 4, 5};    int *p = a;    printf("%d\n", a[0]);   printf("%d\n", *p);   printf("%d\n", p);   int *q = (int *)a;   printf("%d\n", q[0]);   }

需要說的有兩點:

1,

[cpp]
view plaincopyprint?
  1. <SPAN style="FONT-SIZE: 18px">printf("%d\n", p);</SPAN>  
printf("%d\n", p);

這句話是不能正常執行的,列印出來和數組a毫無相關的數字。不要期望像printf(“%s”, p)p為首地址。這種方式企圖列印整個數組a的內容!

2,int *p = a; 和 int *q = (int *)a,這兩句話效果是一樣的,在這裡加不加前面的強制轉換都一樣。

再看這個迷惑性強的例子:

[cpp]
view plaincopyprint?
  1. #include <stdio.h>   
  2. void main()  
  3. {  
  4.     int a[5] = {1, 2 ,3 , 4, 5};  
  5.      int *m = (int *)&a[0];  
  6.      printf("%d\n", *(m + 1));  
  7.     int *p = (int *)&a;  
  8.     printf("%d\n", *(p + 1));  
  9.     int *q = (int *)(&a + 1);  
  10.     printf("%d\n", *(q-1));  
  11.     int *w = (int *)(&a[0] + 1);  
  12.      printf("%d\n", *(w-1));   
  13.   
  14.      
  15. }  
#include <stdio.h>void main(){    int a[5] = {1, 2 ,3 , 4, 5};     int *m = (int *)&a[0];     printf("%d\n", *(m + 1));    int *p = (int *)&a;    printf("%d\n", *(p + 1));    int *q = (int *)(&a + 1);    printf("%d\n", *(q-1));    int *w = (int *)(&a[0] + 1);     printf("%d\n", *(w-1));    }

有三個要點:

1,注意上面我們說那麼(int *)可有可無,但是當加了&後,在int *m = (int *)&a[0]這裡,如果不加強制轉換會警示,因為這裡取了地址,最好強制轉換一下!

2,(int*)(&a[0]) 和(int *)(&a),從列印m和p的值來看,貌似這兩種操作是沒有區別的,但其實並非如此!&a[0] = a,都是代表數組a的首地址,也就是a[0]的地址。但&a是整個對象,也就是a這個數組整體的首地址。緊跟其後的指標q的申明,&a + 1究竟是誰的地址呢?

       我們要切記,對指標進行加1操作,得到是下一個元素的地址,而不是原有地址的數值直接加1,這點大家肯定都知道。假設類型為x,則加1後,指標向後移動sizeof(x),移動是以sizeof(x)為單位的!

我怎麼越說越不明白了,其實就是a和&a[0]以及&a,三者的區別!

     前兩個是等價的。&a上面也說過了,把a看成一個整體,所以&a + 1是a下一個對象的地址,即&a + 1,以相對a或者&a[0]來說,移動了sizeof(a) = 5*4 = 20個位元組,即這裡指標q指向a[5]!所以*(q - 1)的值是5,也就是a[4] 的值。 為了對照區別,最後我取了(&a[0] +
1)來做對照,w在申明時指向a【1】,*(q-1)的值是1,也就是a[0]的值。

3,int *n = a 等價於 int *n = (int *)&a[0]  ,從指向上來看也等價於 int *n  = (int *)&a;

但 當有指標加減操作時,兩者的結果絕不相同!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

如:int *n = (int *)(&a[0]  + 1)絕不等於 int *n = (int *)(&a + 1)。  

 

http://blog.csdn.net/yanzi1225627/article/details/7858231

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.