簡體   English   中英

這兩種說法有什么區別?

[英]What is the difference between these two statements?

我有這兩個聲明:

printf("%u",a+1);

printf("%u",(int *)a+1);

實際上,當我遇到這種困惑時,我正在處理這段代碼。

#include<stdio.h>

int main()
{
  int a[2][2]={1,2,3,4};
  int i,j;
  int *p[] = { (int*)a, (int*)a+1, (int*)a+2 };
  for(i=0; i<2; i++){
    for(j=0; j<2; j++){
      printf("%d %d %d %d",* (*(p+i)+j), *(*(j+p)+i), *(*(i+p)+j), *(*(p+j)+i));
    }
  }
  return 0; 
}

Output:

1 1 1 1
2 2 2 2
2 2 2 2
3 3 3 3

為了理解上面程序的 output,我知道如果我知道上面兩個語句之間的區別,就可以解決造成這個 output 的區別。

我目前的理解: (a+1)會給我數組第二個元素的地址。 在這種情況下,二維數組可以可視化為 2 1-d arrays,每個數組有 2 個元素。 所以(a+1)會給我a[1][0]的地址,但為什么(int *)a+1會給我a[0][1]的地址?

請說明區別和程序的output。

謝謝。

成語(int*)a+1被解釋為((int*)a) + 1) 也就是說,轉換優先於添加。 所以它的計算結果為(int*) a) ,它是作為 ptr-to-int 的數組地址,偏移 1,返回數組中的第二個元素 ( 2 )。

編程的兩個關鍵規則:

規則 1:編寫代碼時,使布局反映功能。
規則 2:閱讀代碼時,閱讀功能,而不是布局。 (推論:調試代碼,而不是注釋。)

從概念上講,當你聲明

int a[2][2]={1,2,3,4};

你設想一個像這樣的二維數組:

  1 2
  3 4

但 C 實際上將數據存儲在 memory 的一個連續塊中,如下所示:

  1 2 3 4

它在計算索引時“記住”數據表示一個 2×2 數組。 但是,當您將a從其原始類型轉換為int *時,您是在告訴編譯器忘記其原始聲明,從而有效地失去其二維性並成為int的簡單向量。

以下是如何理解p的聲明:

int *p[] = { (int*) a,  (int*) a+1,     (int*) a+2 };     // As written
int *p[] = { (int*) a,  ((int*) a) + 1, ((int*) a) + 2 }; // As interpreted
int *p[] = { &a[0][0],  &a[0][1],       &a[1][0] };       // Resulting values

由此可見, p是一個一維向量數組:

p[0] = { 1, 2, 3 }
p[1] = { 2, 3 }
p[2] = { 3 }

如果您認識到(p+i) == (i+p) ,那么最后兩項與該行中的前兩項相同

printf("%d %d %d %d\n",* (*(p+i)+j), *(*(j+p)+i), *(*(i+p)+j), *(*(p+j)+i));

這相當於:

printf("%d %d %d %d\n", p[i+j], p[j+i], p[i+j], p[j+i]);

有趣的是,因為以下都是等價的:

a[i]
*(a+i)
*(i+a)

那么寫i[a]來表示相同的值是完全合法的。 換句話說,編譯器允許你寫

printf("%d %d %d %d\n", p[i], i[p], p[1], 1[p]);

當然,你的 tech lead 最好不要讓你這么寫。 如果你在我的小組里這樣寫,你就會被解雇。 ;-)

無,兩者都會產生未定義的行為。 打印指針值的正確格式是%p 將指針發送到printf時將指針指向void*

多維 C arrays 表現得像單維 arrays 並排放置。 因此,如果您將a (通常(int **) ) 轉換為(int *) ,您會得到與a[0]相同的結果。 因此(int *) a + 1&a[0][1] 否則你的理解是正確的,這就是為什么a + 1得到你&a[1][0]

(此行為由標准指定;但這並不是好的編程習慣。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM