在堆栈中存储字符串与 C 中的代码部分?

Storing strings in stack vs code section in C?

我目前在 C class 中,对于字符串文字的存储位置感到非常困惑。我知道一个字符串只是一个字符数组,所以像

char c[5] = {'A','B','C','D', 0};

等同于

char* c = "ABCD";

编辑:跟进问题:

char c[5] = {'A','B','C','D', 0};

如果我现在说c+1,这是对字符'B'的足尖?但是 'B' 在堆栈中吗?还是在内存的代码段?

但是当我们说字符串文字存储在内存的代码段中时,我总是对它的含义感到困惑。

我明白了栈和堆的区别,但是我抓不住内存的代码段的思路

例如,我知道,在上面的示例中,c 只是一个堆栈变量。美好的。但是如果我说 c[0] 呢?这是存储在内存的代码部分吗?或者,我给出的第二个例子中,char * c = "ABCD",c本身是一个栈变量,但是它指向内存代码段的chars?

我很困惑,如果有任何见解,将不胜感激。

谢谢

is equivalent to

在功能上等同于将存储在内存中某处,但类型不同(一个是数组,另一个是指针)以及它们最终的位置与(通常)不是同一个地方。

But what if I said c[0]? Is this stored in the code section of memory?

c[0] 只是一个表达式,它引用数组中的第一个字符(或者对于指针,它指向的第一个字符)。表达式本身没有存储在任何地方,但它表示的字符是数组的第一个(同上)。例如,如果字符串在堆栈中结束,则 c[0] 表示第一个字符将在堆栈中。

what it means when we say that STRING LITERALS ARE STORED IN THE CODE SECTION OF MEMORY.

二进制文件(通常)由几个部分组成。其中之一是包含代码的代码(您的 CPU 将 运行 的说明)。还有其他部分可用于存储字符串文字。这一切如何运作取决于您的架构和操作系统。

… something like

char c[5] = {'A','B','C','D', 0};

is equivalent to

char* c = "ABCD";

没有。第一个将 c 定义为 5 char 的数组,它将使用显示的值进行初始化。如果此声明出现在函数外部,则 c 将具有静态存储持续时间。它会在程序开始时初始化一次,并在程序的整个执行过程中一直存在。在常见的 C 实现中,它将存储在初始化数据部分中。如果此声明出现在函数内部,c 将具有自动存储期限。每次执行到达声明时都会对其进行初始化。初始值如何存储取决于 C 实现——它们可能内置于初始化数组的指令中,或者它们可能存储在常量数据部分中,以便程序可以将它们从那里复制到 [= 的新实例13=] 每当创建一个时。

第二个将 c 定义为指向 char 的指针。字符串文字名义上定义了一个静态存储持续时间的数组。在常见的 C 实现中,如果实际需要该数组(优化可能使其变得不必要),则该数组将存储在常量数据部分中。 c 被初始化为指向该数组的第一个字符。如果这个声明出现在函数外,c有静态存储期,所以在程序启动的时候就初始化一次。如果它出现在函数内部,c 具有自动存储持续时间,并且在每次执行到声明时创建并初始化它。在任何一种情况下,它都被初始化为指向由字符串文字定义的数组的第一个字符。

EDIT: Follow up question:

char c[5] = {'A','B','C','D', 0};

if I now say c+1, this is a pointe to the character 'B'? But is 'B' in > the stack? or in the code section of memory?

c+1 指向 c[1]。如果 c 是在任何函数之外定义的,那么在常见的 C 实现中,在某些部分中 compiler/program 用于静态数据,因此 c+1 指向该部分。如果 c 是在函数内部定义的,在常见的 C 实现中,它是在堆栈上,因此 c+1 指向堆栈。 (请注意,根据上下文,优化可能会使 c 全部存储或根本不需要将 c+1 保留为指针。)

But I always get confused as to what it means when we say that STRING > LITERALS ARE STORED IN THE CODE SECTION OF MEMORY.

一个字符串文字定义了一个静态存储持续时间的数组。在常见的 C 实现中,它们将存储在常量数据部分中。这与代码部分不同。它们都是只读的,但代码部分是可执行的。有些计算机体系结构没有区分它们的方法,当然可以将只读数据存储在代码段中,但通常最好有单独的段。

与 C 中的所有内容一样,源代码的名义含义就是它在 C 标准定义的抽象机器中必须如何表现。只要生成的程序在可观察到的效果(包括可见的输入和输出)方面具有相同的行为,就允许编译器进行优化。优化可能会导致在抽象机中具有静态存储持续时间的字符串在实际程序中有很大不同。