2016-07-27 135 views
-3

我被這個問題困住了,需要逐步理解每一行的內容。前兩行我明白,但問題出現在第3行和第4行。另外,兩種不同的打印語句有什麼區別?簡單的C指針混淆

int a[] = {11, 22, 33}; 
int *p = a, *q = a + 1, *r = a + 2; 
*p++ = *r--; 
*++q = *r--; 
--*p; ++*q; --*r; 
printf("%d %d %d", a[0], a[1], a[2]); 
printf("%d %d %d", *p, *q, *r); 
+1

? –

+1

*「兩種不同的打印語句有什麼不同?」指針不再指向數組的基本元素。 –

+1

除了嚼口香糖和詢問它是否保留了味道之外,這種類型的代碼究竟是什麼? –

回答

3

一個簡單的方法來解釋每一行所做的是把它擴大成等價代碼更容易,當你不太熟悉的指針和預/後遞增解析:

// *p++ = *r--; 
*p = *r; // copies value in r over to p 
p = p+1; // then increments p, so it now points to a+1 
r = r-1; // and decrements r, so it points to a+1 too 

// *++q = *r--; 
q = q+1; // q now points to a+2 
*q = *r; // places value at a+1 in a+2 
r = r-1; // decrements r, so it points to a+0 

// --*p; ++*q; --*r; 
*p = *p-1; // decrements value at p, that is, a+1 
*q = *q+1; // increments value at q, that is, a+2 
*r = *r+1; // decrements value at r, that is, a+0 

// displays values at a+0, a+1, and a+2 
printf("%d %d %d", a[0], a[1], a[2]); 

// displays values at a+1, a+2, and a+0 
printf("%d %d %d", *p, *q, *r); 

如果預增/ decrement在*之前,那麼你正在修改指針指向的位置的值;如果它在*之後,那麼你正在改變指針指向的位置。在後增加/減少表達式的情況下,如果要修改值,則需要使用圓括號:*p++會更改p指向並計算爲該值的值,(*p)++將更改p指向的值。

作爲一個有趣的**運動,下面的代碼,從The C Programming Language,複製從位置t以零結尾的字符串s

void strcpy(char *s, char *t) { 
    while (*s++ = *t++); 
} 

**你的有趣的想法可以給K &的r不同。 strcpy的使用已被證明會導致緩衝區溢出和過早的禿頭 - 使用strncpy來代替。

+0

不錯的答案 - 但不贊同結尾的'strcpy()/ strncpy()'建議。沒有明確的解釋/例子,兩者都遭受誤用 – chux

+0

解釋正確使用動態內存將需要很多空間。但是,我認爲最低限度的警告是必要的 – tucuxi

1

好仔細聽:d 的問題是在pointer arithmetics(看到這些很好的例子)

*p++ = *r--; 

在這條線上,pr改變它們的值。 ++運算符將其分配給p+1,然後讀取它的值是22*此操作讀取指定的地址值。像「嘿給我什麼是空間內,其中該指針指向」)

*++q = *r--; 

這線在性質上是相同的

--*p; ++*q; --*r; 

這裏指針不會改變,但是它們的值做

所以最後prq沒有指向初始地址 並且打印結果將會不同

0

這可以通過操作符優先級來解釋。

第3行:

*p = *r    a={33(p),22(q),33(r)} 
p++,r--    a={33,22(p)(q)(r),33} 

4行:

q++     a={33,22(p)(r),33(q)} 
*q = *r    a={33,22(p)(r),22(q)} 
r--     a={33(r),22(p),22(q)} 

第5行:

--*p    a={33(r),21(p),22(q)} 
++*q    a={33(r),21(p),23(q)} 
--*r    a={32(r),21(p),23(q)} 
2

只需跟蹤指針。

int a[] = {11, 22, 33}; 
int *p = a, *q = a + 1, *r = a + 2; 

這指向pa[0]qa[1],和ra[2]

*p++ = *r--; 

此副本從*r*p(設定a[0]33),然後遞增p和遞減r(因此兩者pr最終指向a[1]

*++q = *r--; 

此遞增q(它從*r移動到a[2]),然後複製到*q(設定a[2]22),最後遞減r(在a[0]使它點)

--*p; ++*q; --*r; 

這遞減p(使a[1] 21)指向的值,然後遞增*q(使a[2] 23),最後遞減*r(使a[0] 32)

printf("%d %d %d", a[0], a[1], a[2]); 
printf("%d %d %d", *p, *q, *r); 

這些以不同的順序在陣列中打印3個值。

0

int a[] = {11, 22, 33}; //一個[0]←11,[1]←22,[2]←33
int *p = a, *q = a + 1, *r = a + 2; // p→&一個[0],Q→&一個[1],R→&一個[ 2]
*p++ = *r--; //一個[0]←33,p→&一個[1],R→&一個[1]
*++q = *r--; // q→&一個[2],A [2]←22,R→&一個[ 0]
--*p; ++*q; --*r; // a [1]←21,a [2]←23,a [0]←32
printf("%d %d %d\n", a[0], a[1], a[2]); //輸出爲32 21 23
printf("%d %d %d\n", *p, *q, *r); //輸出爲21 23 32

你唔明哪一部分的那些行的