2012-12-22 114 views
-3

可能重複:
Pointer Arithmetic: ++*ptr or *ptr++?你能解釋* ptr ++和*(++ ptr)之間的區別嗎?

我不明白有什麼區別?這裏是一個實現的代碼的例子*的ptr ++

#include <stdio.h> 
int my_array[] = {1,23,17,4,-5,100}; 
int *ptr; 
int main(void) 
{ 
int i; 
ptr = &my_array[0]; /* point our pointer to the first 
element of the array */ 
printf("\n\n"); 
for (i = 0; i < 6; i++) 
{ 
printf("my_array[%d] = %d ",i,my_array[i]); 
printf("ptr + %d = %d\n",i, *ptr++); 

} 
return 0; 
} 

輸出是

my_array[0] = 1 ptr + 0 = 1 
my_array[1] = 23 ptr + 1 = 23 
my_array[2] = 17 ptr + 2 = 17 
my_array[3] = 4 ptr + 3 = 4 
my_array[4] = -5 ptr + 4 = -5 
my_array[5] = 100 ptr + 5 = 100 

當改變第二printf語句給printf( 「PTR +%d =%d \ n」 個,我,*(++ ptr)); 這成爲輸出繼電器:

my_array[0] = 1 ptr + 0 = 23 
my_array[1] = 23 ptr + 1 = 17 
my_array[2] = 17 ptr + 2 = 4 
my_array[3] = 4 ptr + 3 = -5 
my_array[4] = -5 ptr + 4 = 100 
my_array[5] = 100 ptr + 5 = -1881141248 

有人請詳細解釋的差異,所以我能理解。

+1

'* ++ ptr'增量,然後返回* current * eval,'* ptr ++'增量,然後返回* prior * eval。這是涵蓋了一些[問題](http://stackoverflow.com/questions/5209602/pointer-arithmetic-ptr-or-ptr)和[答案](http://stackoverflow.com/questions/13338730/ vs-precedence-in-c/13338801#13338801),僅舉幾例。 – WhozCraig

回答

3

一個遞增指針BEFORE提取它指向​​的內容,另一個增量從指針提取後。

在第二個例子,你已加強你過去的數組的最後一次迭代的結束,要打印(可能)的指針是在存儲位置陣列後立即(或一些隨機的垃圾)

1

一個是預增加運算符,另一個是後增加運算符。

printf("%d", i++);是一樣的:

printf("%d", i); 
i += 1; 

雖然printf("%d", ++i);是一樣的:

i += 1; 
printf("%d", i); 
3

這代表沒有一個給予好評的機會,因爲這個問題是關於無論如何都要關閉,但我無論如何,我不得不把它放在這裏。

當使用*ptr++會發生以下情況:

  1. 使由式寬度的字節ptr
  2. 現有的值遞增ptr的副本(在本例之一,因爲char是一個字節)
  3. 推測之前值來自(1)中製作的副本

當使用*++ptr會發生以下情況:

  1. 增量ptr通過型寬度字節(在此情況下,一個,由於char是一個字節)
  2. 解除引用ptr'的新值。

在C++對象上重寫上述操作符時,後遞增的基本複製然後遞增要求對於性能至關重要,因爲臨時複製可能非常昂貴。


後遞增

下面演示後增量行爲任何人懷疑這一點:

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

static char test[] = "AB"; 
static const char *ptr = test; 

void myprintf(const char *fmt, ...) 
{ 
    va_list args; 
    va_start(args, fmt); 
    printf("myprintf: %c\n", *ptr); 
    vprintf(fmt, args); 
} 

int main(int argc, char *argv[]) 
{ 
    myprintf("main: %c\n", *ptr++); 
    return EXIT_SUCCESS; 
} 

輸出

myprintf: B 
main: A 

無在調用myprintf()之前,ptr的值已經增加了main(),這與大多數人的想法相反,並且與大多數C/C++教師和書籍顯然教導相反。這方面的一個拆卸證明這是這種情況:

movq _ptr(%rip), %rsi  ; ptr value moved into rsi 
movq %rsi, %rcx   ; ptr value moved into rcx 
addq $1, %rcx    ; increment value by one 
movq %rcx, _ptr(%rip)  ; ** store incremented address back into ptr ** 
movsbl (%rsi), %esi   ; old pointer value still in rsi dereferenced here. 
movq %rax, %rdi   
movb $0, %al    
callq _myprintf 
movl $0, %eax 

預遞增

上述相同的代碼,但使用前遞增,這意味着變化main()此單個呼叫:

myprintf("main: %c\n", *++ptr); 

輸出

myprintf: B 
main: B 
相關問題