C编译器对不同类型的声明做了什么?

时间:2011-06-04 21:10:10

标签: c declaration

我理解这一点:

int i = 3;  // declaration with definition

它告诉编译器:

  1. 在内存中保留空间以保存整数值。
  2. 将名称与内存位置关联。
  3. 将值3存储在此位置。
  4. 但是这个声明告诉编译器是什么:

    int i;  // declaration
    

6 个答案:

答案 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)

它与您之前的声明完全相同:

  1. 为整数
  2. 分配堆栈空间
  3. 编译器将名称与空格相关联(您正在运行的程序不会这样做,必然)
  4. 整数未初始化。

答案 4 :(得分:0)

其他人几乎已回答了这个问题,但我会提到两点(我认为)到目前为止尚未提及:

int i;

i定义为int,其中包含垃圾(除非i是“全局”)。这样的垃圾可能是trap representation,这意味着使用它可能是“坏”:

  

陷阱表示是一组位,当被解释为特定类型的值时,会导致未定义的行为。陷阱表示最常见于浮点和指针值,但理论上,几乎任何类型都可能有陷阱表示。未初始化的对象可能包含陷阱表示。这提供了与旧规则相同的行为:访问未初始化的对象会产生未定义的行为。

另外,int i;也可能是tentative definition,这意味着您告诉编译器:“iint,我稍后会定义它如果我不这样做,那就为我定义吧。“ 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.

}