我理解这一点:
int i = 3; // declaration with definition
它告诉编译器:
3
存储在此位置。但是这个声明告诉编译器是什么:
int i; // declaration
答案 0 :(得分:4)
声明告诉编译器为变量i
保留空间,并将名称i
与该空间(您的点1和2)相关联。
如果i
是全局变量,则会将其初始化为0
。
如果它是本地的,i
的值是未定义的(可能是垃圾,即一些随机值),你应该在阅读它之前给它分配。
答案 1 :(得分:3)
有两种情况:在文件范围(即全局声明)和函数中。
在函数中,声明int i;
执行两项操作:它声明了一个名为i
的变量,其类型为int
,并保留了一些存储空间将值设置为int
的内存。它没有做的是给变量一个值。 i
使用的存储仍将包含之前的垃圾。在从中读取值之前,需要初始化变量,即为其赋值。如果不初始化变量,好的编译器会发出警告。
在文件范围,int i
也声明了一个名为i
的变量。其余的取决于其他事项:这被称为暂定定义。您可以在文件中包含多个此类声明。至多其中一个允许使用初始化程序,使其成为一个完整的定义。如果文件范围内i
的任何声明都没有初始值设定项,则声明也是一个定义,并且0
存在隐式初始化。因此:
int i;
/* ... more code ...*/
int i;
有效,i
将初始化为0(假设这些是文件范围内i
的唯一声明)。鉴于:
int i;
int i = 3;
也有效,程序启动时i
将初始化为3。
实际上,在文件范围内,将初始化隐式和显式初始化为0之间通常存在差异。许多编译器将在二进制文件中存储显式0,但让程序加载时操作系统自动初始化隐式零。除非你有一个大的全局数组(不应该经常发生)或者你在微小的嵌入式系统上工作,所以不要担心这个。
答案 2 :(得分:1)
它表示为一个名为i的整数保留空间。至于编译器中的内容并未定义。
答案 3 :(得分:0)
它与您之前的声明完全相同:
答案 4 :(得分:0)
其他人几乎已回答了这个问题,但我会提到两点(我认为)到目前为止尚未提及:
int i;
将i
定义为int
,其中包含垃圾(除非i
是“全局”)。这样的垃圾可能是trap representation,这意味着使用它可能是“坏”:
陷阱表示是一组位,当被解释为特定类型的值时,会导致未定义的行为。陷阱表示最常见于浮点和指针值,但理论上,几乎任何类型都可能有陷阱表示。未初始化的对象可能包含陷阱表示。这提供了与旧规则相同的行为:访问未初始化的对象会产生未定义的行为。
另外,int i;
也可能是tentative definition,这意味着您告诉编译器:“i
是int
,我稍后会定义它如果我不这样做,那就为我定义吧。“ Here is a very good explanation of why C has tentative definitions
答案 5 :(得分:0)
对象有三种内存:
1)外部(通常称为“全局”,但实际上是指范围)。这里的对象是在运行程序之前创建的; 2)堆栈(在运行时创建); 3)堆(例如malloced)。
“int i;”要么在外部存储器中创建对象,要么在堆栈中创建对象。如果它在一个函数中,它就是在堆栈上创建的(如果还没有使用“static”。
如果没有显式初始化在外部存储器中创建的对象,则初始化为零(例如,“int i = 3”;
您可以使用“static”关键字在函数中创建外部对象。
int a; // external memory with "global" scope. Initialized to 0 implicitly.
static int b; // external memory with file (module) scope. Initialized to 0 implicitly.
int c = 3; // external memory initialized to 3.
f()
{
int d; // created on the stack. Goes away when the block exits. Filled with random trash because there is no initialization.
int e = 4; // stack object initialized to 3.
static int f; // "f" is external but not global. Like all externals, it's implicitly initialized to zero.
static int g = 3; // An external like f but initialized to 3.
}