为什么*p0的值每次在编译中都有不同的值。这是用c语言解决这个问题的代码。? 要打印指针,请使用%p并将参数强制转换为(void*)
像为什么*p0的值每次在编译中都有不同的值。这是用c语言解决这个问题的代码。? 要打印指针,请使用%p并将参数强制转换为(void*),c,pointers,C,Pointers,像 阅读p+1,即执行*(p+1),是未定义的行为,因为p+1不指向int。所以不要那样做 在评论中,OP询问: p=6487564*p=500 p+1=6487568*(p+1)=0 p0=6487564*p0=-12 这就是我得到的输出,为什么*p0是-12pz解释 十进制值500与十六进制值0x000001F4相同。在little endian机器(32位int)上,其存储方式如下: printf("p=%p\n*p=%d", (void*)p, *p); 然后分配p
p+1
,即执行*(p+1)
,是未定义的行为,因为p+1
不指向int
。所以不要那样做李>
在评论中,OP询问:
p=6487564*p=500 p+1=6487568*(p+1)=0 p0=6487564*p0=-12 这就是我得到的输出,为什么*p0是-12pz解释 十进制值500与十六进制值0x000001F4相同。在little endian机器(32位
int
)上,其存储方式如下:
printf("p=%p\n*p=%d", (void*)p, *p);
然后分配p0
的p
值,因此
p -> F4 01 00 00
因此p0
指向0xF4(假设为8位字符)
在有符号字符的机器上,十六进制值0xF4是十进制值-12(即有符号8位2的补码表示)
结论在带有签名8位字符的little endian机器上,打印值将为-12
如果你改变
p -> F4 01 00 00
^
|
p0
到
然后它将打印244。这可能更容易理解,因为500是256+244(或十六进制:0x1F4=0x100+0xF4)
%p
并将参数强制转换为(void*)
p+1
,即执行*(p+1)
,是未定义的行为,因为p+1
不指向int
。所以不要那样做李>
在评论中,OP询问:
p=6487564*p=500 p+1=6487568*(p+1)=0 p0=6487564*p0=-12 这就是我得到的输出,为什么*p0是-12pz解释 十进制值500与十六进制值0x000001F4相同。在little endian机器(32位
int
)上,其存储方式如下:
printf("p=%p\n*p=%d", (void*)p, *p);
然后分配p0
的p
值,因此
p -> F4 01 00 00
因此p0
指向0xF4(假设为8位字符)
在有符号字符的机器上,十六进制值0xF4是十进制值-12(即有符号8位2的补码表示)
结论在带有签名8位字符的little endian机器上,打印值将为-12
如果你改变
p -> F4 01 00 00
^
|
p0
到
然后它将打印244。这可能更容易理解,因为500是256+244(或十六进制:0x1F4=0x100+0xF4)。在尝试访问
*(p+1)
时,您正在调用未定义的行为。好的,从技术上讲,在打印带有%d
的指针值时也会调用它%d
不是指针的正确格式字符串。可能您有64位指针和32位整数,因此您在第二个%d中得到了指针的剩余部分,但这都是未定义的行为。但是编译器没有对此发出警告吗?printf(“p=%d\n*p=%d”,p,*p)代码>->printf(“p=%p\n*p=%d”,(void*)p,*p)代码>否在这种情况下,我的编译器不会发出警告..p=6487564*p=500 p+1=6487568*(p+1)=0 p0=6487564*p0=-12尝试访问*(p+1)
时,您正在调用未定义的行为。好的,从技术上讲,在打印带有%d
的指针值时也会调用它%d
不是指针的正确格式字符串。可能您有64位指针和32位整数,因此您在第二个%d中得到了指针的剩余部分,但这都是未定义的行为。但是编译器没有对此发出警告吗?printf(“p=%d\n*p=%d”,p,*p)代码>->printf(“p=%p\n*p=%d”,(void*)p,*p)代码>否我的编译器在这种情况下不会给出警告..p=6487564*p=500 p+1=6487568*(p+1)=0 p0=6487564*p0=-12我认为在打印时将指针强制转换为void*
并不是真的必要。@GabrielStaples它在大多数没有强制转换的系统上工作,但要符合标准,强制转换是必需的。我明白了。forprintf()
表示预期的参数类型也是void*
。我以前从未注意到这一点,就像我通常看到的那样。@GabrielStaples比cplusplus好得多。不管怎么说,标准是最值得一看的地方。在%p
的标准描述中,您会发现:“……相应的参数应该是指向void的指针……”@Gabriel Staples如果您认为没有必要使用void*,那么请展示一个简单的代码示例。我不认为在打印时将指针投射到void*
。@Gabriel Staples它可以在大多数没有投射的系统上工作,但要符合标准,投射是必需的。我明白了。forprintf()
表示预期的参数类型也是void*
。我以前从未注意到这一点,就像我通常看到的那样。@GabrielStaples比cplusplus好得多。不管怎么说,标准是最值得一看的地方。在%p
的标准描述中,您会发现:“……相应的参数应该是指向void的指针……”@Gabriel Staples如果您认为void*是不必要的,那么展示一个简单的代码示例