【问题标题】:Clarification over lvalue , rvalue behaviour of pointers in C澄清 C 中指针的左值、右值行为
【发布时间】:2011-05-26 12:10:30
【问题描述】:
#include<stdio.h>

int main()
{
    int i = 10;
    int *p = &i;

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

    return 0;
}

代码输出:-

初始化指针p的地址:3221221820

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

为什么“&(*p)”在赋值语句和 printf 语句中使用时表现不同?

更新 抱歉,只是 printf 中的格式说明符错误;)。感谢您的回复和指出。

【问题讨论】:

    标签: c pointers printf


    【解决方案1】:

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

    This 按预期工作。

    【讨论】:

    • %p 和 %u 有什么区别??
    • %u 用于打印无符号整数,%p 用于指针。
    • 感谢 Prasoon,还有一个疑问,当我使用 %p 时,我得到 0x7fbffff1bc,但是当我将 %u - 3221221820 打印的值转换为十六进制时,我只得到 bffff1bc。那么当我使用 %p 时,这个额外的 0x7f 是什么?
    • @Saran、指针和unsigned 的宽度可能不同。
    • @Prasoon,不只是“0x”作为前缀添加,而是“0x7f”作为前缀添加!!!这是什么 7f ?
    【解决方案2】:

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

    例如

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

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

    【讨论】:

    • 如果该值已经是一个指针,那么将其转换为void* 有什么区别?我可以看到将其保留在 C++ 中的问题(继承和运算符重载可能会导致问题),但是是什么使它在 C 中变得危险?
    • @cHao:虽然不常见,但指向不同类型的指针在 C 中可以有不同的表示形式。%p 格式说明符要求相应参数的类型为“指向void”的指针,所以如果变量你有一个指向其他东西的指针,那么严格来说你需要转换它以满足printf的要求。
    【解决方案3】:

    你有

    当您第二次尝试打印地址时,%d 而不是 %u

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

    printf("\n 修改后的地址 初始化指针 p:%u 值:%d valuez 地址:%u \n", p, *p, &(*p));

    最值得注意的是,您应该使用 %p 来打印指针值,而不是 another answer on this thread 中已经指出的 %u。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多