指针行为将值设为 1

Posted

技术标签:

【中文标题】指针行为将值设为 1【英文标题】:Pointer behaviour gives value as 1 【发布时间】:2018-08-26 04:25:22 【问题描述】:

明确地说,我知道 C 中指向指针概念的指针以及取消对双、三指针的引用。我唯一的疑问是我编写的以下程序:

#include<stdio.h>
int main()
    int a;
    int* p;
    a=5;
    p=&a;
    int **q;
    printf("*p=%d\n",*p);
    printf("*q=%d\n",*q);

现在我知道,这个程序非常愚蠢而且毫无意义,但这不是问题所在。问题是为什么? 为什么输出是这样的:

*p=5
*q=1

为什么每次运行时 *q=1? 还要记住,如果我现在声明一个 ***r; 并添加以下行:

printf("*r=%d\n",*r);

现在的输出是:

*p=5
*q=-40821602 //garbage
*r=1

现在,*r=1。为什么? ****也一样。在这种情况下,*q,*r 是垃圾,*s=1。为什么?

【问题讨论】:

你有未定义的行为,这就是原因。 两件事:您需要使用"%p" 格式说明符打印void * 指针(需要转换);而且你永远不会初始化q,这意味着它取消引用它会导致undefined behavior 未定义行为(简称UB)通常意味着任何关于行为的讨论都是没有实际意义的。然而,这里发生的是您使用的是未初始化的变量,其值是 indeterminate 并且看似随机。你看到的就是这个“看似随机”的值。 未定义的行为随着时间的推移保持一致并不奇怪。几天来我有一些是一致的,然后发生了一些事情并且行为改变了。也许我进行了防病毒更新或修补程序,谁知道呢。 “为什么”的基本答案是“因为该指针占据了内存的一部分,恰好在其中相当一致地具有“1”。用不同的标志重新编译,看看它是否改变(例如,改变调试设置或优化设置。 如果你在汇编中打开一个调试器,你可以一步一步通过机器指令,这应该提供清晰。你所看到的一切都没有让我感到惊讶,我不知道你为什么觉得这很奇怪。 【参考方案1】:

对未初始化指针的求值是未定义的行为,这就是你所做的。 cppreference 对未定义的行为声明如下:

未定义行为

未定义的行为 - 对程序的行为没有限制。未定义行为的示例包括数组边界之外的内存访问、有符号整数溢出、空指针取消引用、在没有序列点的表达式中多次修改同一标量、通过不同类型的指针访问对象等。不需要诊断未定义的行为(尽管诊断了许多简单的情况),并且编译后的程序不需要做任何有意义的事情。

因此,您不能期望您的程序会产生任何有意义的东西。它可以打印 1,但它也可以做任何其他事情。例如,就我而言,它只是崩溃了。

所以问题“为什么?”根本不是一个有效的问题。

【讨论】:

以上是关于指针行为将值设为 1的主要内容,如果未能解决你的问题,请参考以下文章

HashMap浅入理解

将值传递给函数时,GCC前缀增量运算符行为不端[重复]

使用 jQuery 将复选框的值设为 1/0

下拉输入元素行为奇怪,而不是将值传递给“search.php”页面

阻止事件冒泡,取消浏览器默认行文

指针的意外行为(操作时)但使用双指针时定义的行为