C 编译器如何处理不同类型的声明?

发布于 2024-11-14 07:02:41 字数 262 浏览 4 评论 0原文

我的理解是:

int i = 3;  // declaration with definition

它告诉编译器:

  1. 在内存中保留空间来保存整数值。
  2. 将名称与存储位置关联起来。
  3. 在此位置存储值3

但是这个声明告诉编译器什么:

int i;  // declaration

I understand this:

int i = 3;  // declaration with definition

It tells the compiler to:

  1. Reserve space in memory to hold integer value.
  2. Associate name with memory location.
  3. Store the value 3 at this location.

But what does this declaration tell the compiler:

int i;  // declaration

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

塔塔猫 2024-11-21 07:02:41

该声明告诉编译器为变量 i 保留空间,并将名称 i 与该空间相关联(您的点 1. 和 2.)。

如果i是全局变量,则它被初始化为0

如果它是本地的,则 i 的值未定义(可能是垃圾,即某个随机值),您应该在读取它之前对其进行赋值。

The declaration tells the compiler to reserve space for the variable i and associate the name i with that space (your points 1. and 2.).

If i is a global variable it is initialized to 0.

If it is local the value of i is undefined (probably garbage, ie. some random value) and you should assign to it before reading it.

悸初 2024-11-21 07:02:41

有两种情况:在文件范围(即全局声明)和在函数中。

在函数中,声明 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,但让操作系统在加载程序时自动初始化隐式零。除非您有一个大型全局数组(这不应该经常发生)或者您在小型嵌入式系统上工作,否则不必担心这一点。

There are two cases: at file scope (i.e. for a global declaration), and in a function.

In a function, the declaration int i; does two things: it declares a variable called i whose type is int, and it reserves some storage in memory to put a value of type int. What it does not do is give the variable a value. The storage used by i will still contain whatever garbage was there before. You need to initialize the variable, i.e. assign a value to it, before you can read a value from it. Good compilers will warn you if you don't initialize the variable.

At file scope, int i also declares a variable called i. The rest depends on other things: this is known as a tentative definition. You can have multiple such declarations in your file. At most one of these is allowed to have an initializer, making it a full-fleged definition. If none of the declarations of i at file scope have an initializer, the declaration is also a definition, and there is an implicit initialization to 0. Thus:

int i;
/* ... more code ...*/
int i;

is valid, and i will be initialized to 0 (assuming these are the only declarations of i at file scope). Whereas:

int i;
int i = 3;

is also valid, and i will be initialized to 3 when the program starts.

In practice, at file scope, there's often a difference between leaving the initialization implicit and explicitly initializing to 0. Many compilers will store an explicit 0 in the binary, but let the operating system initialize implicit zeroes automatically when the program is loaded. Don't worry about this unless you have a large global array (which shouldn't happen often) or you work on tiny embedded systems.

终难遇 2024-11-21 07:02:41

它表示为一个名为 i 的整数保留空间。至于其中的内容取决于编译器并且是未定义的。

It says to reserve space for an integer called i. As far as what is in there is up to the compiler and is undefined.

莫相离 2024-11-21 07:02:41

它与您之前的声明执行相同的操作:

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

It does the same thing as your previous declaration:

  1. allocates space on the stack for the integer
  2. the compiler associates a name with the space (your running program won't do this, necessarily)
  3. the integer is not initialized.
久随 2024-11-21 07:02:41

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

int i;

i 定义为 int,带有垃圾在其中(除非 i 是“全局”)。此类垃圾可能是陷阱表示,这意味着使用它可能会“不好”:

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

此外,int i;也可以是暂定定义,这意味着你告诉编译器:“i是一个int,我稍后会定义它。如果我不这样做,那么将它定义为我。”。 这里有一个很好的解释为什么 C 有暂定定义

Others have pretty much answered the question, but I will mention two points that (I think ) haven't been mentioned so far:

int i;

defines i to be an int, with garbage in it (unless i is "global"). Such garbage might be a trap representation, which means that using it could be "bad":

A trap representation is a set of bits which, when interpreted as a value of a specific type, causes undefined behavior. Trap representations are most commonly seen on floating point and pointer values, but in theory, almost any type could have trap representations. An uninitialized object might hold a trap representation. This gives the same behavior as the old rule: access to uninitialized objects produces undefined behavior.

Also, int i; could also be a tentative definition, which means that you're telling the compiler: "i is an int, and I will define it later. If I don't, then define it for me.". Here is a very good explanation of why C has tentative definitions.

来日方长 2024-11-21 07:02:41

对象有三种类型的内存:

1)外部(通常称为“全局”,但实际上指的是范围)。这里的对象是在程序运行之前创建的; 2)堆栈(在运行时创建); 3) 堆(例如malloced)。

“int我;”在外部存储器或堆栈上创建对象。如果它在函数中,则在堆栈上创建(如果未使用“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.

}

There are three kinds of memory for objects:

1) external (often called "global" but that really refers to scope). Objects here are created before running the program; 2) stack (created during run time); 3) heap (eg malloced).

"int i;" either creates the object in the external memory or on the stack. If it's in a function, it's created on the stack (if "static" isn't also used.

Objects created in external memory are initialized to zero if they are not explicitly initialized (e.g, "int i = 3";

You can create an external object in a function by using the "static" keyword.

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.

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文