【问题标题】:Why does this pointer appear to point to itself?为什么这个指针似乎指向自己?
【发布时间】:2014-05-04 11:19:31
【问题描述】:

我正在尝试掌握 C 中的指针,并且正在努力理解为什么我会得到一个奇怪的输出。

我的代码是:

int main(){

int a[3][6];
int i,j,k = 0;

for(i = 0; i < 3; i++){
    for (j = 0; j < 6; j++) {
        a[i][j] = k++;
    }
}

int c = 5;
int *p = &c;
printf("address of p = %p\n",&p);
printf("p = %p\n",p);
printf("address of c = %p\n",&c);

printf("address of a[2] = %p\n", &a[2]);
printf("address of a[2][0] = %p\n", &a[2][0]);
printf("a[2] = %p\n", a[2]);
printf("a[2][0] = %d\n",a[2][0]);

return 0;

}

我得到的输出是:

address of p = 0x7fff6cbabf88
p = 0x7fff6cbabf90
address of c = 0x7fff6cbabf90
address of a[2] = 0x7fff6cbabf70
address of a[2][0] = 0x7fff6cbabf70
a[2] = 0x7fff6cbabf70
a[2][0] = 12

这似乎表明a[2] == &amp;a[2],但这肯定不正确吗?

【问题讨论】:

  • a[2] 的类型为int[6]&amp;a[2] 的类型为 int (*)[6]。如果你有一个指向人的指针和一个指向火车的指针;把人放在火车里……两个指针都指向同一个东西吗????
  • 头脑 == 炸了!好困惑
  • 如果您要求上面的指针指向下一件事,它们将指向完全不同的方向(下一个人与下一趟火车)。我的意思是,指针由它们指向的地址和类型来标识。
  • 我认为我的问题是我正在尝试使用不是指针的数组名称进行指针运算。
  • @lurker: a[n]&amp;a[n] 不是同义词!第一个是数组(检查sizeof a[n]),第二个是指针(检查sizeof &amp;a[n])。数组有时会转换为指向其第一个元素的指针。 转换发生时 a[n]&amp;a[n][0] 的同义词。

标签: c pointers multidimensional-array


【解决方案1】:

从更简单的开始,像这样

int main( void )
{
    int b[5];

    printf( "b      = %p\n", b      );
    printf( "&b     = %p\n", &b     );

    printf( "b+1    = %p\n", b+1    );
    printf( "(&b)+1 = %p\n", (&b)+1 );
}

编译器将b 视为pointer to an int,而&amp;bpointer to an array of 5 ints。因此,b 加 1 会将地址更改为 4(假设为 32 位 int),而将&amp;b 加 1 会将地址更改为十进制的 20。


一旦你理解了这一点,你就可以用a[3][6] 数组把自己搞砸了。

a        is a pointer to     int [6]
a[i]     is a pointer to     int
a[i][j]  is an int

&a       is a pointer to     int [3][6]
&a[i]    is a pointer to     int [6]
&a[i][j] is a pointer to     int

【讨论】:

  • 这会将内容转换成英文,让我更容易理解指针。我一直感到困惑,因为我印象中数组几乎只是指针,而 a[5] 在编译时会转换为 a+5。但是编译器看到a as:int (*)[6],这让我很困惑。
  • 是的,C 语言中的pointers to arrays 语法令人费解。您是正确的,a[5] 始终转换为 a+5。要记住的是,指针运算总是涉及到所指向对象的大小,因此在进行数学运算之前,您需要知道该大小是多少。
【解决方案2】:

数组名等价于指向数组第一项的指针:arr == &amp;arr[0]
你的a 是二维数组,所以a[0]a[2] 是一维数组,
因此a[2] == &amp;a[2][0]

【讨论】:

    【解决方案3】:

    如果使用数组的标识符,在大多数情况下它会衰减为指向第一个元素的指针。

    所以有

    int a[3][6];
    
    • &amp;aint (*)[3][6],所以 sizeof(*&amp;a) 将是 18 * sizeof(int)
    • a&amp;a[0] 都是 int (*)[6],所以 sizeof(*a)sizeof(*&amp;a[0]) 将是 6 * sizeof(int)
    • a[0] 和 &a[0][0] 都是 int *,所以 sizeof(*a[0])sizeof(*&amp;a[0][0]) 将是 6 * sizeof(int)

    (请注意,sizeof 表达式中出现的所有 *&amp; 都可以优化掉;我将它们留在这里以便更好地理解。)

    但是所有提到的指针都指向同一个位置。

    始终注意指针由地址和类型(长度)组成,两者都是相关的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-01
      • 2021-01-16
      • 2013-01-30
      • 1970-01-01
      • 2012-10-07
      相关资源
      最近更新 更多