0

下面是我的 C++ 代码。这里在函数“temp”中,首先声明“ch”的值然后打印(第一次“ch”没有初始化,所以“ch”有未定义的值)。然后“if”条件满足(在里面“如果”没有工作完成)。然后函数结束并返回到函数调用的下一行(增量'i')。然后下一次迭代也以与上一次调用相同的方式进行。相同的循环一直持续到按键被按下。当一个键被按下时(例如“a”被按下),“else”被执行并且被按下的键被 getch() 获取。然后函数结束并返回到函数调用的下一行(i++),然后在所有即将到来的下一次迭代中,当调用一个函数时,'ch'被分配与前一个键按下('a' )并打印该字符('a')。它继续打印'a',直到按下另一个键。为什么以及如何为“ch”分配上一个函数调用的值。上一次调用的变量值是否存储在堆栈中并将其分配给下一次调用的变量?

#include<iostream>
#include<conio.h>
#include<stdlib.h>
using namespace std;

int flag = 0,i = 1;

void temp()
{
    char ch;
    cout<<ch;
    if(!_kbhit())
    {

    }
    else{
        ch=_getch();
    }
}

int main()
{
    while(flag!=1)
    {
        temp();
        i++;
    }
   return 0;
}
4

3 回答 3

0

在您的代码中(以及在英特尔上),在调用temp()并返回之后,没有代码可以修改ch堆栈上的位置。因此,当您再次调用它时,它仍然具有先前的值。

例如,您是否会在调用printf()main()调用temp(),然后此调用将覆盖 的位置ch

于 2020-06-23T11:11:14.847 回答
0

要回答您的具体问题,您很幸运。

C++ 不会不必要地清除内存。当您调用temp()第二次或后续时间时,在这种情况下,它会以与前一次完全相同的方式分配内存,因此您会在ch.

但是,对您的程序结构或编译器设置的任何细微更改都可能意味着内存布局未对齐,您不会得到这种行为。

正如评论中所建议的,将声明更改为

static char ch;

将保证在调用之间保留该值,而对内存和性能的潜在成本非常低。

于 2020-06-23T11:15:43.197 回答
0

“为什么以及如何ch分配上一个函数调用的值?”

“上一次调用的变量的值是否ch存储在堆栈中并ch在下一次调用时分配给temp()?”

在 C++ 中,函数本地对象不需要在函数返回后被销毁,这似乎是你的情况。

尽管如此,行为是未定义的。您试图理解的内容是基于未定义的执行结果。

由于ch没有初始化,打印它的值可以输出任何值。

'a'在所有其他函数调用中打印字符temp()是未定义行为的标志。


ch您可以通过使用static存储类说明符限定变量来找到一个定义明确的解决方案,这意味着变量ch存储在BSS可执行文件 Fe 的段中:

static char ch;

然后ch在堆栈内存中保持活动状态,即使在函数调用之间使用它的值也是如此。

此外,这还具有有益的副作用,即ch自动0初始化。因此,不再有未定义的行为。

于 2020-06-23T11:20:57.037 回答