我认为我理解指针算法的语义相当好,但我在处理数组时只看到了例子。是否有任何其他用途不能通过不透明的手段实现?我相信你可以找到一种巧妙的方法来使用它来访问结构的成员,但我不知道为什么你会打扰。我最感兴趣的是C,但我会用C ++标记,因为答案可能也适用于那里。
编辑,基于目前为止收到的答案:我知道指针可以在许多非数组上下文中使用。我特别想知道关于指针的算术,例如递增,带来差异等等。
答案 0 :(得分:10)
如果你遵循字母的语言标准,那么当指向数组时,指针算术仅 定义,而不是任何其他情况。
指针可以指向数组的任何元素,或者一步过去数组的结尾。
答案 1 :(得分:10)
C中的指针算法按照定义仅在数组上发生。但是,由于每个对象都有一个由重叠的unsigned char [sizeof object]
数组组成的表示,因此对该表示执行指针算法也是有效的。例如:
struct foo {
int a, b, c;
} bar;
/* Equivalent to: bar.c = 1; */
*(int *)((unsigned char *)&bar + offsetof(struct foo, c)) = 1;
实际上char *
也可以正常工作。
答案 2 :(得分:9)
从我的头脑中我知道它在XOR linked-lists中使用(非常漂亮)并且我已经在very hacky recursions中看到过它。
另一方面,很难找到用途,因为根据标准指针算术仅在数组的范围内定义。
答案 3 :(得分:5)
a[n]
是*(a + n)
的“正义”语法糖。对于lulz,请尝试以下
int a[2];
0[a] = 10;
1[a] = 20;
因此有人可能认为索引和指针算法只是可互换的语法。
答案 4 :(得分:1)
指针算法仅在数组上定义。将一个整数添加到不指向数组元素的指针会产生未定义的行为。
答案 5 :(得分:0)
在嵌入式系统中,指针用于表示地址或位置。可能没有定义数组。 (虽然可以说所有内存都是一个巨大的数组。)
例如,通过在堆栈指针中添加或减去值来操纵堆栈(保存变量和地址)。 (在这种情况下,堆栈可以说是基于数组的堆栈。)
答案 6 :(得分:0)
以下是(严格定义的)数组之外的指针运算的情况:
double d = 0.5;
unsigned char *bytes = (void *)&d;
for(size_t i = 0; i < sizeof d; i++)
printf("Byte %zu of d is %hhu\n", i, bytes[i]);
你为什么要这样做?我不知道。但是,如果您想查看对象的按位表示(对memcpy
和memcmp
等内容很有用),则需要将其地址转换为unsigned char *
s(或{{ 1}}如果您愿意)并逐字节地使用它们。 (如果你的任务不是太困难,你甚至可以编写代码来逐字工作,大多数signed char *s
实现都会这样做。但是,原则相同,只需用{memcpy
替换char
{1}}。)
请注意,在标准中,打印的确切值(或值的数量)是实现定义的,但这将始终作为访问对象的内部字节表示的方式。 (它不需要适用于更大的整数类型,但几乎总是如此 - 我知道的处理器在很长一段时间内都没有对整数进行陷阱表示。)