不使用 符号的添加

Addition without using a + sign

本文关键字:添加 符号      更新时间:2023-10-16
int add(int a, int b)
{
  return (int)&(((char *)a)[b]);
}

为什么我应该将a施放到char *而不是int *

我试图完全理解此代码,但我不能,因此,如果您很容易,请提供一个简单的英语解释。

这个想法是数组只是带有索引的指针的添加。如果achar [](或char *),而b是整数,则a[b]是地址a+b处的值。此代码将a施放为指针,将其索引为B,并找到地址,该地址应等于a+b

但是在现实世界中,永远不要这样做。

为什么我应该将A施放给char *而不是int *?

为了澄清问题的读者,您根本不是假设的完全使用这样的代码。但是,让我们假设您正在参加IOCCC(本竞赛中有C 变体?),在这种情况下,这可能正是您应该做的。

因此,要回答这个问题,这是因为指针算术由尖头对象的大小缩放。如果使用int*,则b将通过sizeof(int)缩放。由于您不想扩展一个添加的操作数,因此您以1(乘法身份)进行缩放时,当尖端类型具有1个尺寸1时发生,从定义上讲,char具有。

P.S。该程序的形式不佳,可能无法在标准的编译器上编译。

要使其编译,您需要将其转换为有效的C 。指针与整数不兼容,但是两个指针之间的距离是整数类型:

#include <iterator>
int add(int a, int b)
{
    auto p = (char *)0;
    auto p2 = &(&p[a])[b];
    return static_cast<int>(std::distance(p, p2));
}

免责声明:我不认可此产品或服务。

让我们以A as 100和B为103

的例子
  1. (char *)a->这将a作为指针。因此,一个将被视为指针。
  2. ((char *)a)[b]->这是100 [103],即它在位置(100 103)
  3. 给出值
  4. &(((char *)a)[b]->这给出了上述值的地址,即给出203。
  5. (int)&(((char *)a)[b]-> int的最终类型将转换上面的地址按照函数的返回值要求的整数值。

这仅在步骤2中与char*打字一起使用。如果您在那里使用int* Typecast,则在步骤3中获得的总和将为100 + 4*103,即512