为什么只有算术运算打印出值而不是正常值

时间:2017-09-19 15:14:23

标签: c arrays pointers

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而不是一些随机值

2 个答案:

答案 0 :(得分:4)

这是基本原则的一部分。 ptr1可以表示为ptr1 = &arr[0]ptr1 = arr:两种形式都是等效的。此外,您的ptr2作业可以表示为ptr2 = ptr1 +3ptr2 = &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的结果。结果是floatptr2之间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