不能用这种方法计算一个数字的平方

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (9)

我找到了一个计算数字平方的函数:

int p(int n) {
    int a[n]; //works on C99 and above
    return (&a)[n] - a;
}

它返回N2的值。问题是,它是怎么做到的?经过一些测试,我发现(&a)[k](&a)[k+1]sizeof(a)/sizeof(int)。那是为什么?

提问于
用户回答回答于

要理解这个黑客,首先需要理解指针的差异,即当两个指针指向同列被减去了吗?

当一个指针从另一个指针中减去时,结果是指针之间的距离(以数组元素度量)。所以如果p指点a[i]q指点a[j],然后p - q等于i - j

C11:6.5.6加法算子(P9):

当两个指针被减去时,两者都应指向同一数组对象的元素,或者指向数组对象的最后一个元素;结果是两个数组元素下标的差异。 换句话说,如果PQ分别指向i-第四和j-数组对象的第四个元素,表达(P)-(Q)有价值i−j如果该值与类型的对象相匹配ptrdiff_t

现在我希望您知道数组名称转换为指针,a将指针转换为数组的第一个元素a,&a是整个内存块的地址,即它是数组的地址。

这将帮助你理解为什么a&a有相同的地址和方式(&a)[i]是ith数组的地址

所以,声明

return (&a)[n] - a; 

等于

return (&a)[n] - (&a)[0];  

这个差异将给出指针之间的元素数。(&a)[n](&a)[0],它们是n数组nint元素。因此,总数组元素是n*n=n2.

注:

C11:6.5.6加法算子(P9):

如果减去两个指针,两者都应指向同一个数组对象的元素,或者指向数组对象的最后一个元素。结果是两个数组元素下标的差异。结果的大小是实现定义的。,它的类型(有符号整数类型)是ptrdiff_t中定义的<stddef.h>头球。如果结果在该类型的对象中不可表示,则行为是未定义的。undefined

(&a)[n]既不指向同一个数组对象的元素,也不指向数组对象的最后一个元素,(&a)[n] - a会调用未定义行为

还请注意,最好更改函数的返回类型。pptrdiff_t.

用户回答回答于

显然是黑客,但是一种不用使用*操作员(这是编码竞赛的要求)。

(&a)[n] 
(a + sizeof(a[n])*n)

因此整个表达式是

  (&a)[n] -a 

= (a + sizeof(a[n])*n -a) /sizeof(int)

= sizeof(a[n])*n / sizeof(int)
= sizeof(int) * n * n / sizeof(int)
= n * n

扫码关注云+社区