繁体   English   中英

为什么第二个printf打印0

[英]Why does second printf print 0

#include<stdio.h>
int main()
{
    char arr[] = "somestring";
    char *ptr1 = arr;
    char *ptr2 = ptr1 + 3;
    printf("ptr2 - ptr1 = %ld\n", ptr2 - ptr1);
    printf("(int*)ptr2 - (int*) ptr1 = %ld",  (int*)ptr2 - (int*)ptr1);
    return 0;
}

我明白

 ptr2 - ptr1

给出3,但无法弄清楚为什么第二个printf打印0。

这是因为当你减去两个指针时,你得到的指针之间的距离是元素的数量,而不是字节。

(char*)ptr2-(char*)ptr1  // distance is 3*sizeof(char), ie 3
(int*)ptr2-(int*)ptr1  // distance is 0.75*sizeof(int), rounded to 0 

编辑:我错误地说,演员强制指针对齐

如果要检查地址之间的距离不要使用(int *)(void *)ptrdiff_t是一种能够表示任何有效指针减法操作的结果的类型。

#include <stdio.h>
#include <stddef.h>

int main(void)
{
    char arr[] = "somestring";
    char *ptr1 = arr;
    char *ptr2 = ptr1 + 3;
    ptrdiff_t diff = ptr2 - ptr1;

    printf ("ptr2 - ptr1 = %td\n", diff);
    return 0;
}

编辑:正如@chux所指出的那样, ptrdiff_t使用"%td"字符

使用int*转换char指针会使其与4bytes对齐(在此处int为4个字节)。 虽然ptr1ptr2距离是3个字节,但是将它们转换为int*产生相同的地址 - 因此产生结果。

这是因为sizeof(int) == 4

每个char占用1个字节。 你的字符数组在内存中看起来像这样:

[s][o][m][e][s][t][r][i][n][g][0]

当你有一个int数组时,每个int占用四个字节。 存储'1'和'2'在概念上看起来更像是这样的:

[0][0][0][1][0][0][0][2]

因此,Int必须与4字节边界对齐。 您的编译器将地址别名化为最低整数边界。 你会注意到,如果你使用4而不是3,这可以按预期工作。

您必须执行减法以使其执行此操作(仅将传递的指针传递给printf不会这样做)的原因是因为printf不是严格类型的,即%ld格式不包含参数的信息一个int指针。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM