热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

澄清C中指针的左值、右值行为

Clarificationoverlvalue,rvaluebehaviourofpointersinC


Clarification over lvalue , rvalue behaviour of pointers in C












1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17



#include

int main()
{

    int i = 10;

    int *p = &i;

    printf("
address of initialized pointer p: %u
"
, p);

    p = &(*p);

    printf("
modified address of initialized pointer p:%u value:%d valuez address: %d
"
, p, *p, &(*p));

    return 0;
}



代码输出:-

初始化指针p的地址:3221221820

初始化指针p的修改地址:3221221820 value:10 valuez地址:-1073745476

为什么是"


您在 printf 中使用了不正确的格式说明符。使用 %d 打印地址将不起作用。而是使用 %p 。 [打印地址的%u也不正确。]

这符合预期。



相关讨论




  • %p 和 %u 之间有什么区别?


  • %u 用于打印无符号整数,%p 用于指针。


  • 谢谢 Prasoon,还有一个疑问,当我使用 %p 时,我得到 0x7fbffff1bc,但是当我将 %u - 3221221820 打印的值转换为十六进制时,我只得到 bffff1bc。那么当我使用 %p 时附加的这个额外的 0x7f 是什么?


  • @Saran:在这种情况下,该值以十六进制格式表示。因此,0x。


  • @Saran,指针和 unsigned 的宽度可能不同。


  • @Prasoon,不仅 "0x" 被添加为前缀,而且 "0x7f" 被添加为前缀!这是什么7f?


  • @Jens,好的,所以未签名的宽度可能较小,因此缺少 7f 是吗?所以 %p 打印的值是正确的,对吗?


  • @Saran:地址的一部分(以十六进制格式表示)






你有

当您第二次尝试打印地址时,使用

%d 而不是 %u。

请注意以下修改后的源代码中的粗体更改:

printf("

modified address of

initialized pointer p:%u value:%d

valuez address: %u

", p, *p,

&(*p));

最值得注意的是,您应该使用 %p 来打印指针值,而不是 %u,正如在此线程的另一个答案中已经指出的那样。


指针的标准格式说明符是%p。为了安全起见,您应该始终在对 printf 的调用中明确地将指向 (void*) 的指针强制转换。不保证任何其他格式说明符都可以使用指针值。

例如










1
2



printf("p: %p; *p: %d; &(*p): %p
"
, (void*)p, *p, (void*)&(*p));


您看到的区别只是第一个格式说明符是 %u ,它将指针值打印为无符号整数,而第二次使用 %d 将其打印为有符号整数。



相关讨论





  • 如果该值已经是一个指针,那么将其转换为 void* 有什么区别?我可以看到将其保留在 C 中的问题(继承和运算符重载可能会导致问题),但是是什么使它在 C 中变得危险?


  • @cHao:虽然不常见,但指向不同类型的指针在 C 中可以有不同的表示形式。 %p 格式说明符要求相应参数的类型为 "pointer to void" 因此,如果您拥有的变量是指向别的东西那么严格你需要转换它以满足 printf 的要求。










推荐阅读
author-avatar
__-霖
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有