calculate the square of a number

http://stackoverflow.com/questions/27828822/cant-understand-this-way-to-calculate-the-square-of-a-number?newsletter=1&nlcode=49042%7cdd5e

int p(int n)

{   

     int a[n];

    //works on C99 and above   

    return (&a)[n] - a;

}

 

It returns n^2. Question is, how does it do that? After a little testing, I have found that between(&a)[k] and (&a)[k+1] is sizeof(a)/sizeof(int). Why is that?

 

Obviously a hack... but a way of squaring a number without using the * operator.

(&a)[n]

is equivalent to a pointer to int at location

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

and thus the entire expression is

  (&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

 

 

To understand this hack, first you need to understand the pointer difference, i.e, what happens when two pointers pointing to elements ofsame array are subtracted? 

When one pointer is subtracted from another, the result is the distance (measured in array elements) between the pointers. So, ifp points to a[i] and q points to a[j], thenp - q is equal to i - j

Now I am expecting that you are aware of array name conversion to pointer, a converts to pointer to first element of array a. &a is address of the entire memory block, i.e it is an address of arraya. The figure below will help you to understand (readthis answer for detailed explanation):   

enter image description here

This will help you to understand that why a and &a has the same address and how(&a)[i] is the address of ith array (of same size as that ofa). 

So, the statement  

return (&a)[n] - a; 

is equivalent to 

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

and this difference will give the number of elements between the pointers (&a)[n] and (&a)[0], which are n arrays each of n int elements. Therefore, total array elements are n*n =n2.

NOTE:

C11: 6.5.6 Additive operators (p9):

When two pointers are subtracted, both shall point to elements of the same array object,  or one past the last element of the array object; the result is the difference of the  subscripts of the two array elements.The size of the result is implementation-defined,  and its type (a signed integer type) isptrdiff_t defined in the <stddef.h> header.  If the result is not representable in an object of that type, the behavior is undefined. 

Since (&a)[n] neither points to elements of the same array object nor one past the last element of the array object,(&a)[n] - a will invoke undefined behavior.

Also note that, better to change the return type of function p toptrdiff_t.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值