将字符串存储在堆栈中还是在C中的代码段中?

问题描述 投票:1回答:2

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

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?

我感到非常困惑,任何见识将不胜感激。

谢谢

c arrays char c-strings string-literals
2个回答
3
投票

相当于

在功能上等同,它将存储在内存中[[somewhere,但是类型不同(一个是数组,另一个是指针))并且它们的结尾(通常)是不相同的地方。

但是如果我说c [0]怎么办?这是否存储在内存的代码部分中?

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

[当我们说存储代码部分中存储了字符串文学时,这意味着什么。

二进制文件(通常)由几个部分组成。其中之一就是包含代码(您的CPU将运行的指令)的代码。还有其他部分可用于存储字符串文字。所有这些工作原理取决于您的体系结构和操作系统。


0
投票
…类似

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

等效于

char* c = "ABCD";

没有第一个将c定义为5 char的数组,将使用所示的值对其进行初始化。如果此声明出现在函数外部,则c将具有静态存储持续时间。程序开始时它将被初始化一次,并且在整个程序执行中都将存在。在常见的C实现中,它将存储在Initialized-data节中。如果此声明出现在函数内部,则c将具有自动存储时间。每当执行到达声明时,它将被初始化。初始值的存储方式取决于C实现-它们可以内置在初始化数组的指令中,也可以存储在常量数据段中,以便程序可以将其从那里复制到c的新实例中。 ]只要创建一个。

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

编辑:跟进问题:

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

如果我现在说c + 1,这是指向字符'B'的指针吗?但是堆栈中的'B'是吗?还是在内存的代码部分?

c+1指向c[1]。如果c是在任何函数之外定义的,则在常见的C实现中,某些部分是编译器/程序用于静态数据的位置,因此c+1指向该部分。如果c是在函数内部定义的,则在常见的C实现中,它位于堆栈上,因此c+1指向堆栈。 (请注意,根据上下文的不同,优化可能完全没有必要存储所有c或将c+1保持为指针。)

但是当我们说存储的代码部分中存储了字符串>时,我总是感到困惑。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.