繁体   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