2016-03-02 55 views
-4

給定一個變量long *ptr_long;在這種情況下,C++中* pointer + 2的值是多少?

而且,以下內容:

Memory Content

會有什麼操作* ptr_long + 2的值?還有,怎麼樣?

我已經嘗試了以下內容:* ptr指向0x00現在持有內容'0x04'。現在,你接受並增加2(4字節,因爲它是一個長類型?)。我不確定該從哪裏出發。

+0

閱讀關於運營商的優先級和答案將是...... –

+0

'長'多久?注意:解引用具有比添加更高的優先級。 –

+0

@learnerX嚴格來說,會有未定義的行爲。:) –

回答

3

注意

*pointer + 2 

被解析爲

(*pointer) + 2 

而不是

*(pointer + 2), 

所以它的意思是「取消引用指針,然後再添加兩到你的數量結果「而不是」前進兩個對象,然後取消引用你得到的指針。「在這種情況下,你應該得到6(0x04 + 2)。

如果您添加括號得到*(pointer + 2),那你將獲得0x0c假設每個long是四個字節(我懷疑因爲你的記憶只給十六個字節),因爲pointer + 2指「2向前跳過* sizeof(long)字節。「

+0

我不認爲我們正在拒絕指針。這個問題之前的問題要求:*(ptr_long + 2),這是一個不同的情況。這個答案應該是0x0F。但我不知道如何。有任何想法嗎? – learnerX

+0

@learnerX templatetypedefs答案是絕對正確的。所以要麼你錯誤地輸入了這個問題,誤解了這個問題,或者你有錯誤的答案。實際上得到0xF的表達式將是'*(pointer + 1)+ 2' –

+0

@learnerX:如果你在指針前面有一個帶有*的表達式,你可以對它進行解引用。我沒有看到任何會給出'0x0F'的簡單表達式。你爲什麼認爲這是答案? (爲什麼你沒有在這個問題中提到這一點?)有可能是誰告訴你答案是'0x0F'是完全錯誤的。 –

0

答案取決於你的系統, 在大多數情況下,回答是:

*ptr + 2 = 0x6 
*(ptr + 2) = 0xc 

長型是在4個字節編碼爲32個系統,並在64位的系統的8個字節,

根據系統和CPU上,你的存儲器狀態可以是如下:

0x00 : 04 00 00 00 
0x04 : 0d 00 00 00 
0x08 : 0c 00 00 00 
0x0c : 0a 00 00 00 

or 

0x00 : 00 00 00 04 
0x04 : 00 00 00 0d 
0x08 : 00 00 00 0c 
0x0c : 00 00 00 0d 

或(64個比特系統):

0x00 : 04 00 00 00 00 00 00 00 
0x08 : 0d 00 00 00 00 00 00 00 
0x10 : 0c 00 00 00 00 00 00 00 
0x18 : 0a 00 00 00 00 00 00 00 

你的例子是在這種情況下更接近一個32位系統的情況下, :

# if ptr is a long pointer : 
*ptr + 2 = 0x6  // the (content of the long value at the adress 0x00) + 2 = 0x04 + 0x02 
*(ptr + 2) = 0xc // the content of adress 0x10 (0x00 + 2 as long size) = 0x00 + 0x10 (16 in decimal) 

這是好事,知道: *(PTR + 2)= *的ptr [2]

ptr -->0x00 : 04 00 00 00 
     0x04 : 0d 00 00 00 
ptr+2 -->0x08 : 0c 00 00 00 
     0x0C : 0a 00 00 00 

反之:

如果PTR是一個字符指針:

*ptr + 2 = 0x6  // the (content of the char/byte value at the adress 0x00) + 2 
*(ptr + 2) = 0x0 // the content of adress 0x02 (0x00 + 2 as char size) = 0x00 + 0x02 (2 in decimal) 

       ptr ptr+2=0x02 
        |  | 
     0x00 : (04)00(00)00 
     0x04 : 0d 00 00 00 
     0x08 : 0c 00 00 00 
     0x0C : 0a 00 00 00 

在這種情況下: 如果例如長(長×)類型的新指針PTR2由PTR + 2值初始化, 在32位,在住址內容指出通過PTR2將是: 00 00 0D 00

  0x00 : 04 00 (00 00 
     0x04 : 0d 00) 00 00 
     0x08 : 0c 00 00 00 
     0x0C : 0a 00 00 00 

在64位,由PTR2指向的住址的內容將是:00 00 00 00 00 00 0D 00

0x00 : 04 00 (00 00 00 00 00 00 
0x08 : 0d 00) 00 00 00 00 00 00 
0x10 : 0c 00 00 00 00 00 00 00 
0x18 : 0a 00 00 00 00 00 00 00 

在這兩種情況下的值是相同的:
* PTR2 + 2 = 0x0d02 //的(在ADRESS 0×02的值長的含量)+ 2

但在32位系統:
*(PTR2 + 2)= 0x0a00 // ADRESS 0X0A的內容(0×02 + 2只要(4個字節)大小)= 0×02 + 0×08 //值爲0x0a00 =(00 00 00 0A)

   adress 0x0a 
         | 
     0x08 : 0c 00(00 00 
     0x0C : 0a 00)00 00 

但在64位系統:
*(PTR2 + 2 )= 0x12 //地址0x12的內容(0x02 + 2長(8字節)大小)= 0x02 + 0x10 //值爲0x0a00

   adress 0x12 
         | 
     0x10 : 0c 00(00 00 00 00 00 00 
     0x18 : 0a 00)00 00 00 00 00 00   

我prurpose你編譯和運行後續的C程序:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

void long_hexa_print(long *p) 
{ 
char *ptr = (char *)p; 
int size=sizeof(*p); 
printf ("0x%x : ", p ); 
for (int i=0; i<size; i++){printf ("0x%x " , *(ptr + i));} 
printf ("\n"); 
} 

int main(void) 
{ 
    // char * string = "REVERSE"; 
    //reverse(string); 

    int j=4; 
    long *long_ptr = (long *)malloc((j*sizeof(long))+1); 
    char *ptr = (char *)long_ptr; 

    char * char_ptr2; 
    int * int_ptr2; 
    long * long_ptr2; 


    long_ptr[0]=0x4; // 4 
    long_ptr[1]=0xb; // 11 
    long_ptr[2]=0xc; // 12 
    long_ptr[3]=0xa; // 10 

    char_ptr2 = (char *)(ptr + 2); // or (char *) ptr[2] 
    int_ptr2 = (int *)(ptr + 2); 
    long_ptr2 = (long *)(ptr + 2); 

    printf ("\n=== Sizes of types ====\n\n"); 
    printf ("Size of char = %d\n", sizeof(char)); 
    printf ("Size of long = %d\n\n", sizeof(long)); 

    printf ("\n=== Memory status ====\n\n"); 
    long_hexa_print(long_ptr); 
    long_hexa_print(long_ptr + 1); 
    long_hexa_print(long_ptr + 2); 
    long_hexa_print(long_ptr + 3); 
    long_hexa_print(long_ptr + 4); 

    printf ("\n=== Values of pointers ====\n\n"); 
    printf ("long_ptr  = 0x%x\n", long_ptr); 
    printf ("long_ptr + 1 = 0x%x\n", long_ptr + 1); 
    printf ("long_ptr + 2 = 0x%x\n\n", long_ptr + 2); 

    printf ("* long_ptr + 2 = 0x%x\n", * long_ptr + 2); 
    printf ("*(long_ptr + 2) = 0x%x\n", *(long_ptr + 2)); 
    printf (" long_ptr[2] = 0x%x\n\n", long_ptr[2]); 


    printf ("&long_ptr[0] = 0x%x\n", & long_ptr[0]); 
    printf ("&long_ptr[1] = 0x%x\n", & long_ptr[1]); 
    printf ("&long_ptr[2] = 0x%x\n\n", & long_ptr[2]); 

    printf ("\n##### char *ptr = (char *)long_ptr; ##### \n"); 
    for (int i=0; i<=7; i++){printf ("ptr+%d  = 0x%x\n", i, *(ptr + i));} 


    printf ("\n=== Values of contents ====\n\n"); 
    printf ("*long_ptr = 0x%x\n", *long_ptr); 
    printf ("*(long_ptr) = 0x%x\n\n", *(long_ptr)); 
    printf ("long_ptr[0] = 0x%x\n", long_ptr[0]); 
    printf ("long_ptr[1] = 0x%x\n", long_ptr[1]); 
    printf ("long_ptr[2] = 0x%x\n\n", long_ptr[2]); 
    printf ("*(long_ptr+0) = 0x%x\n", *(long_ptr+0)); 
    printf ("*(long_ptr+1) = 0x%x\n", *(long_ptr+1)); 
    printf ("*(long_ptr+2) = 0x%x\n\n", *(long_ptr+2)); 

    printf ("char_ptr2 = 0x%x\n", *char_ptr2); 
    printf ("int_ptr2 = 0x%x\n", *int_ptr2); 
    printf ("long_ptr2 = 0x%x\n\n", *long_ptr2); 

    printf ("*(ptr) = 0x%x\n", *(ptr)); 
    printf ("*(ptr+1) = 0x%x\n", *(ptr + 1)); 
    printf ("*(ptr+2) = 0x%x\n", *(ptr + 2)); 
    printf ("*(ptr+3) = 0x%x\n", *(ptr + 3)); 
    printf ("*(ptr+4) = 0x%x\n", *(ptr + 4)); 
    printf ("*(ptr+5) = 0x%x\n", *(ptr + 5)); 
    printf ("*(ptr+6) = 0x%x\n", *(ptr + 6)); 
    printf ("*(ptr+7) = 0x%x\n", *(ptr + 7)); 
    printf ("*(ptr+8) = 0x%x\n", *(ptr + 8)); 
    printf ("*(ptr+9) = 0x%x\n\n", *(ptr + 9)); 

    printf ("(long *)(ptr + 4) = 0x%x\n", *(ptr + 4)); 
    printf ("(long *)(ptr + 4) = %d\n\n", *(ptr + 4)); 

    printf ("(long *)(ptr + 8) = 0x%x\n", (long *)(ptr + 8)); 
    printf ("(long *)(ptr + 8) = %d\n\n", (long *)(ptr + 8)); 

    return 0; 
} 

結果將如下所示:

=== Sizes of types ==== 

Size of char = 1 
Size of long = 8 


=== Memory status ==== 

0x10350 : 0x4 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x10358 : 0xb 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x10360 : 0xc 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x10368 : 0xa 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x10370 : 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 

=== Values of pointers ==== 

long_ptr  = 0x10350 
long_ptr + 1 = 0x10358 
long_ptr + 2 = 0x10360 

* long_ptr + 2 = 0x6 
*(long_ptr + 2) = 0xc 
    long_ptr[2] = 0xc 

&long_ptr[0] = 0x10350 
&long_ptr[1] = 0x10358 
&long_ptr[2] = 0x10360 


##### char *ptr = (char *)long_ptr; ##### 
ptr+0  = 0x4 
ptr+1  = 0x0 
ptr+2  = 0x0 
ptr+3  = 0x0 
ptr+4  = 0x0 
ptr+5  = 0x0 
ptr+6  = 0x0 
ptr+7  = 0x0 

=== Values of contents ==== 

*long_ptr = 0x4 
*(long_ptr) = 0x4 

long_ptr[0] = 0x4 
long_ptr[1] = 0xb 
long_ptr[2] = 0xc 

*(long_ptr+0) = 0x4 
*(long_ptr+1) = 0xb 
*(long_ptr+2) = 0xc 

char_ptr2 = 0x0 
int_ptr2 = 0x0 
long_ptr2 = 0x0 

*(ptr) = 0x4 
*(ptr+1) = 0x0 
*(ptr+2) = 0x0 
*(ptr+3) = 0x0 
*(ptr+4) = 0x0 
*(ptr+5) = 0x0 
*(ptr+6) = 0x0 
*(ptr+7) = 0x0 
*(ptr+8) = 0xb 
*(ptr+9) = 0x0 

(long *)(ptr + 4) = 0x0 
(long *)(ptr + 4) = 0 

(long *)(ptr + 8) = 0x10358 
(long *)(ptr + 8) = 66392 

我希望這將有助於你更好地理解指針

+1

sizeof(long int)和sizeof(uintptr_t)在我的ubuntu 15.10(64)機器上報告8字節(不是4字節)。 –

+0

'*(ptr + 2)'是長0x0 *** 8 ***的內容(假設長度爲4個字節) – immibis