#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。
答案 0 :(得分:8)
这是因为当你减去两个指针时,你会得到指针之间的距离,而不是字节数。
(char*)ptr2-(char*)ptr1 // distance is 3*sizeof(char), ie 3
(int*)ptr2-(int*)ptr1 // distance is 0.75*sizeof(int), rounded to 0
编辑:我说错误是说施法强制指针对齐
答案 1 :(得分:4)
如果要检查地址之间的距离,请不要使用(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所指出的,use "%td"
character for ptrdiff_t
。
答案 2 :(得分:1)
使用char
转换int*
指针会使其与4字节对齐(此处int为4字节)。虽然ptr1
和ptr2
距离是3个字节,但将它们转换为int*
,会产生相同的地址 - 因此产生结果。
答案 3 :(得分:0)
这是因为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
format不包含参数为int指针的信息。