2011-11-21 150 views
57

讓我們假設,如何增加指針地址和指針的值?

int *p; 
int a = 100; 
p = &a; 

什麼將下面的代碼實際上和怎麼辦?我知道,這在編碼方面有點雜亂,但我想知道當我們這樣編碼時會發生什麼。

注意:讓我們假設地址爲a=5120300,它存儲在指針p中,地址爲3560200。現在,執行每條語句後的值是多少?

+3

爲什麼你不在調試器中運行它? –

+15

那麼..爲什麼不簡單*嘗試*看看? 'printf'將會打印一個指針,並且%p –

+0

如果你對行爲感興趣,只需要玩一下它。只需編寫一個簡單的c程序,通過所有這些用例,看看它是否對你有意義。 – Cyrus

回答

91

首先,*運算符優先於++運算符,並且()運算符優先於其他所有內容。編輯(事情比這更復雜,見底編輯)

二,++操作數是相同數量++運算符,如果你不將其分配給什麼。區別在於數字++返回數字,然後遞增數字,並且++數字首先遞增然後返回它。

三,通過增加一個指針的值,你用的sizeof增加它的內容,那就是你增加它,如果你是在一個數組迭代。

所以,總括起來:

ptr++; // Pointer moves to the next int position (as if it was an array) 
++ptr; // Pointer moves to the next int position (as if it was an array) 
++*ptr; // The value of ptr is incremented 
++(*ptr); // The value of ptr is incremented 
++*(ptr); // The value of ptr is incremented 
*ptr++; // Pointer moves to the next int position (as if it was an array). But returns the old content 
(*ptr)++; // The value of ptr is incremented 
*(ptr)++; // Pointer moves to the next int position (as if it was an array). But returns the old content 
*++ptr; // Pointer moves to the next int position, and then get's accessed, with your code, segfault 
*(++ptr); // Pointer moves to the next int position, and then get's accessed, with your code, segfault 

由於有在這裏很多情況下,我可能已經取得了一些錯誤,請糾正我,如果我錯了。

編輯:

所以,我錯了,優先級是一個小比我寫的更復雜,查看這裏: http://en.cppreference.com/w/cpp/language/operator_precedence

+3

* ptr ++,該值不遞增,指針爲。這些一元運算符具有相同的優先級,但從右到左進行評估。代碼的意思是「從ptr指向的地方取內容,然後增加ptr」。這是非常常見的C代碼(是的,很混亂)。請糾正這一點,我會刪除downvote。 *(ptr)++相同,括號不做任何事情。 – Lundin

+0

非常感謝Lundin,我錯過了其他什麼? – felipemaia

+0

@Lundin嗨,上面的答案是現在糾正嗎?謝謝。 – Unheilig

3

至於「如何增加一個指針地址和指針的值?」我認爲++(*p++);實際上是明確界定,並做了你要問什麼,例如:

#include <stdio.h> 

int main() { 
    int a = 100; 
    int *p = &a; 
    printf("%p\n",(void*)p); 
    ++(*p++); 
    printf("%p\n",(void*)p); 
    printf("%d\n",a); 
    return 0; 
} 

它不是一個序列點之前修改同樣的事情兩次。儘管對於大多數用途,我不認爲這是很好的風格 - 這對我的喜好來說有點太神祕。

8

檢查程序和結果都一樣,

p++; // use it then move to next int position 
++p; // move to next int and then use it 
++*p; // increments the value by 1 then use it 
++(*p); // increments the value by 1 then use it 
++*(p); // increments the value by 1 then use it 
*p++; // use the value of p then moves to next position 
(*p)++; // use the value of p then increment the value 
*(p)++; // use the value of p then moves to next position 
*++p; // moves to the next int location then use that value 
*(++p); // moves to next location then use that value 
+1

'使用它'。怎麼樣 ? – alex

+1

@alex使用它的意思,例如,考慮語句,'int * a = p ++;'這裏首先使用指針'p'的值,之後p將移動到下一個位置。因此,在執行上述語句後,'a'將具有由'p'指向的先前位置的地址,並且'p'將指向下一個位置。首先使用'p'的值作爲上面的賦值表達式,然後增加'p'的值以指向下一個位置 –

0

以下是各種的實例化「只是打印」的建議。我發現它很有啓發性。

#include "stdio.h" 

int main() { 
    static int x = 5; 
    static int *p = &x; 
    printf("(int) p => %d\n",(int) p); 
    printf("(int) p++ => %d\n",(int) p++); 
    x = 5; p = &x; 
    printf("(int) ++p => %d\n",(int) ++p); 
    x = 5; p = &x; 
    printf("++*p  => %d\n",++*p); 
    x = 5; p = &x; 
    printf("++(*p) => %d\n",++(*p)); 
    x = 5; p = &x; 
    printf("++*(p) => %d\n",++*(p)); 
    x = 5; p = &x; 
    printf("*p++  => %d\n",*p++); 
    x = 5; p = &x; 
    printf("(*p)++ => %d\n",(*p)++); 
    x = 5; p = &x; 
    printf("*(p)++ => %d\n",*(p)++); 
    x = 5; p = &x; 
    printf("*++p  => %d\n",*++p); 
    x = 5; p = &x; 
    printf("*(++p) => %d\n",*(++p)); 
    return 0; 
} 

它返回

(int) p => 256688152 
(int) p++ => 256688152 
(int) ++p => 256688156 
++*p  => 6 
++(*p) => 6 
++*(p) => 6 
*p++  => 5 
(*p)++ => 5 
*(p)++ => 5 
*++p  => 0 
*(++p) => 0 

我投的指針地址int S左右,他們可以很容易地進行比較。

我使用GCC編譯它。