Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么C标准没有定义不确定变量的使用?_C - Fatal编程技术网

为什么C标准没有定义不确定变量的使用?

为什么C标准没有定义不确定变量的使用?,c,C,垃圾值存储在哪里,用于什么目的?C出于效率原因选择不将变量初始化为某些自动值。为了初始化此数据,必须添加指令。下面是一个例子: int main(int argc, const char *argv[]) { int x; return x; } 生成: pushl %ebp movl %esp, %ebp subl $16, %esp movl -4(%ebp), %eax leave ret pushl %ebp movl %esp, %ebp subl $16

垃圾值存储在哪里,用于什么目的?

C出于效率原因选择不将变量初始化为某些自动值。为了初始化此数据,必须添加指令。下面是一个例子:

int main(int argc, const char *argv[])
{
    int x;
    return x;
}
生成:

pushl %ebp
movl  %esp, %ebp
subl  $16, %esp
movl  -4(%ebp), %eax
leave
ret
pushl %ebp
movl  %esp, %ebp
subl  $16, %esp
movl  $1, -4(%ebp)
movl  -4(%ebp), %eax
leave
ret
而此代码:

int main(int argc, const char *argv[])
{
   int x=1;
   return x;
}
生成:

pushl %ebp
movl  %esp, %ebp
subl  $16, %esp
movl  -4(%ebp), %eax
leave
ret
pushl %ebp
movl  %esp, %ebp
subl  $16, %esp
movl  $1, -4(%ebp)
movl  -4(%ebp), %eax
leave
ret

正如您所看到的,一个完整的额外指令用于将1移动到x中。这一点过去很重要,现在在嵌入式系统上也很重要。

IIRC、Thompson或Richie几年前接受了一次采访,他们说,语言定义故意在某些地方留下模糊的东西,因此特定平台上的实现者可以在该平台上做有意义的事情(周期、内存等)。很抱歉,我没有链接到的参考。

C被设计成一种相对低级的语言,因此它可以用来编写低级的东西,比如操作系统。(事实上,它的设计目的是让UNIX可以用C编写)您可以简单地将其视为具有可读语法和更高级构造的汇编代码。因此,C(负优化)完全按照您的要求执行,不多不少

当你写
intx,编译器只为整数分配内存。您从未要求它在那里存储任何东西,所以当您的程序启动时,该位置中的任何东西都会保持不变。最常见的情况是,预先存在的值是“垃圾”


有时,外部程序(例如设备驱动程序)可能会写入某些变量,因此无需添加另一条指令来初始化这些变量。

垃圾值实际上并不存储在任何地方。事实上,就抽象语言而言,垃圾值实际上并不存在

您可以看到,为了生成最高效的代码,编译器仅根据对象(变量)的生命周期进行操作是不够的。为了生成最有效的代码,编译器必须在更精细的级别上运行:它必须“思考”值的生命周期。例如,为了高效地调度CPU寄存器,这是绝对必要的

抽象语言没有“价值的生命周期”这样的概念。然而,语言作者认识到这个概念对优化编译器的重要性。为了给编译器足够的自由来执行有效的优化,特意指定了该语言,以便它不会干扰重要的优化。这就是“垃圾值”出现的地方。该语言没有声明垃圾值存储在任何地方,该语言也不能保证垃圾值是稳定的(即,重复尝试读取相同的未初始化变量可能很容易导致不同的“垃圾值”)。这样做是为了使优化编译器能够实现“值的生命周期”这一重要概念,从而执行比“对象生命周期”这一语言概念所规定的更有效的变量操作

为什么C标准没有定义不确定变量的使用

它没有:-):

  • 对于局部变量,它表示未定义的行为,这意味着任何事情(如SEGFULT、擦除硬盘)都是合法的:

  • 对于全局变量,它将其归零:


垃圾值不是“存储”的,也没有“用途”。它们只是被未初始化变量占用的内存空间中的任何东西。太快太快。这是个问题。它可以(可以/必须)解释得更好。但这是一个问题。也许是复制品,但这是个问题。我一直在回答:>>垃圾值不是故意存储的。简单地说,内存和寄存器保存值。如果noone将它们设置为对任何感兴趣的人都有意义的值(如函数的调用者),则“调用者”会得到一个“垃圾”值,即访问noone已设置为有意义值的内存区域或寄存器,因此它可以是根据之前谁拥有该内存或上次执行的计算而定的任何值,或任何其他“不可预测”的事实。如果你的意思不一样,请指定更好的问题。对于重新打开我的帖子,我真的很想得到一些答案,以便我能在课堂上做一个简短的解释…(悲伤的是一些ppl关闭了它)你的问题在这里发布的评论中得到了很好的回答。如果不初始化变量,它将包含该特定内存位置中的任意随机位。为什么C(或者更具体地说,C编译器)允许这样做?可能是出于简单性和性能原因。你,程序员,负责初始化你的变量,使你的代码是安全的。我不确定什么是“这过去很重要,现在在嵌入式系统上仍然如此”。@Michael Burr:我把它解释为“除非你在嵌入式系统上工作,否则你不应该担心额外指令对性能的影响。”如果您的自动变量是一个大数组,而您的函数恰好在该调用中没有做很多事情,这仍然很重要。@Cogwheel:这就是它的初衷。你知道规则:让它工作,让它正确,让它快速。。。按这个顺序。@Rannick:或者你可以每秒调用该函数数千次。它发生在我参与的一个项目中。某些日志记录函数正在初始化缓冲区,然后决定对优先级低于错误和返回的任何内容禁用日志记录。这在语言中随处可见,例如,算术类型的未定义大小等。交换函数是一个很好的示例,其中初始化temp变量完全没有意义(并且相对于整个函数运行时来说成本较高)。大多数函数会更长,因此自动初始化的运行时成本相对较小,但正如@ninjalj所指出的,在某些情况下,大数据量