【问题标题】:how does the compiler treat the operator + when the operand is a pointer in C [duplicate]当操作数是C中的指针时,编译器如何处理运算符+ [重复]
【发布时间】:2013-07-21 04:39:05
【问题描述】:

例如。

int a[]={3,4};
int *p1=a;
int *p2=a+1;

最后一行,编译器怎么知道这行的+1不是普通的加法,而是地址加法。它如何与常见的添加区分开来,例如 int i=1+2

有人可以在寄存器级别解释一下吗?

【问题讨论】:

  • 嗯,事实上它不是在 int 上运行?
  • 向指针添加一个使其指向连续内存位置中同类的下一个元素。例如在将 1 添加到 int* 指针时,指向下一个 int。现在明白即使是一个 int 是 4(或 8)字节的指针值也是第一个单元地址值(但这个指针代表完整的int)。现在,在将1 添加到该指针值时,它将开始依次指向下一个int,因此大小指针地址值按int 的大小递增。因此,将1 添加到指针不是算术而是逻辑递增它。

标签: c pointers compiler-construction


【解决方案1】:

将标量添加到指针时,就像在做&pointer[scalar]。例如:

int * path = 0x1234;
path += 1;
printf("%p\n", path);

以上代码在 32 位系统上打印出0x1238

编辑:澄清一下,将n 添加到指针会使指针偏移n * sizeof(element) 字节。

【讨论】:

  • 我学到的是当使用指针[标量]时,编译器会将其视为*(指针+标量),而不是相反。
  • @henryyao 这是没有区别的区别。两者的待遇相同。哪个先来并不重要。
【解决方案2】:

它根据所添加对象的类型进行区分。如果它是一个指针,那么地址会增加你指定的数字乘以指针指定指向的对象的大小。

IOW,给定一些类型 T,并添加如下:

T *result = base + increment;

...基本上相当于这样:

char *raw_address = (char *)base_address;

raw_address += increment * sizeof(T);

result = (T *)raw_address;

但是请注意,在相当多的情况下,CPU 可能能够在单个指令(例如 Intel x86/x64 和兼容设备可以像这样结合缩放和添加)。

【讨论】:

  • 所以编译器足够聪明,可以区分 int i=1+3 和 int *p=0x1234+1,对吧?
  • 是和不是。正如您所展示的那样 (0x1234+1),它只是对几个整数进行数学运算,因此不会被缩放。但是,如果其中一个输入实际上是一个指针,那么它将对其进行数学运算与对整数进行数学运算(例如,int *p = (int *)0x1234; p += 4;)进行区分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-04
  • 1970-01-01
  • 2021-02-01
  • 2021-01-23
  • 1970-01-01
相关资源
最近更新 更多