int main(){
float arr[5] = {12.5, 10.0, 13.5, 90.5, 0.5};
float *ptr1 = &arr[0];
float *ptr2 = ptr1 + 3;
printf("%f ", *ptr2); // outputs 90.5
printf("%d", ptr2 - ptr1); // outputs 3
printf("%d",ptr2) ;
return 0;
}
为什么最后一行不打印3而不是一些随机值
答案 0 :(得分:4)
这是c基本原则的一部分。 ptr1
可以表示为ptr1 = &arr[0]
或ptr1 = arr
:两种形式都是等效的。此外,您的ptr2
作业可以表示为ptr2 = ptr1 +3
或ptr2 = &ptr1[3]
。
有问题的一行:
printf("%d", ptr2 - ptr1);
从另一个中减去一个指针值,并得到" gap"在两个指针之间,假设每个"间隙"是float
的大小。
以下示例应提供更多见解。使用intptr_t
类型只是为了让我可以像操作一个简单的数字一样操作指针。
#include <stdio.h>
#include <stdint.h>
#define OFFSET (3)
int main(void)
{
float arr[5] = {12.5, 10.0, 13.5, 90.5, 0.5};
float *ptr1 = &arr[0];
float *ptr2 = ptr1 + OFFSET;
printf("%p %p\n", ptr1, ptr2);
printf("sizeof(float):%ld\n", sizeof(float));
printf("Distance between pointers (bytes):%ld\n", (intptr_t)ptr2 - (intptr_t)ptr1);
printf("Distance between pointers (gaps):%ld\n", ptr2 - ptr1);
return 0;
}
0x7fffdc244800 0x7fffdc24480c
sizeof(float):4
Distance between pointers (bytes):12
Distance between pointers (gaps):3
如果您还没有,我强烈建议您购买/租借/借用一份&#34; C Primer Plus&#34;通过普拉塔,并在章节和最后的测验中进行所有练习。这本主题在本书的早期详细介绍,并且非常详细。
答案 1 :(得分:2)
以下是对每条印刷线上发生的事情的解释,并附有更正:
printf("%f ", *ptr2);
此行输出90.5
,这是*(ptr1 + 3)
指向的值,与ptr1[3]
相同。
printf("%td", ptr2 - ptr1);
此行应使用%td
,因为从ptr1
中减去ptr2
的结果会产生类型ptrdiff_t
的结果。结果是float
和ptr2
之间ptr1
数组中的位置数,即3
。
请注意,这是有效的,因为两个指针都指向同一个数组;你不能只减去任意两个任意指针并得到一个明确定义的答案。减去未指向同一数组的指针是未定义的行为。
printf("%p", (void*)ptr2) ;
此行打印指针的数值。您需要使用%p
代替%d
。使用%d
会产生未定义的行为,在您的情况下会导致打印3.使用%p
并将指针转换为void*
修复未定义的行为; the result printed on ideone is different
如何在算术运算后打印索引?为什么它会在最后一个中返回索引?有什么区别?
C具有适用于指针算术运算的特殊规则,称为指针算法。
指针本身不是索引。但是,您可以向指针添加整数,并且C会将其视为将指针移动到右侧或左侧的相应索引数,具体取决于整数的符号。此外,C根据索引的数量定义指针减法,因此通常的算术规则适用:
(p + i) - p = i