代码之家  ›  专栏  ›  技术社区  ›  Sadique

数组初始化之间的差异

c c++
  •  3
  • Sadique  · 技术社区  · 15 年前

    请参见以下声明:

    char a[5]="jgkl"; // let's call this Statement A
    char *b="jhdfjnfnsfnnkjdf"; // let's call this Statement B , and yes i know this is not an Array
    char c[5]={'j','g','k','l','\0'}; // let's call this Statement C
    

    现在,陈述式A和C有什么区别吗? 我的意思是两个都应该在堆栈上,不是吗?只有b在静态位置。


    那么,这不会使“jgkl”在程序的整个生命周期中都存在于静态位置吗?既然它应该是只读/常量? 请澄清。

    5 回复  |  直到 14 年前
        1
  •  2
  •   anon anon    15 年前

    如果a[]是静态的,那么c[]也是静态的-两者是等价的,而且都不是字符串。这两个可以同样好地声明,以便它们在堆栈上-这取决于它们在何处以及如何声明,而不是用于指定其内容的语法。

        2
  •  5
  •   Heath Hunnicutt    15 年前

    不,因为 人物 语句A中的“jgkl”用于初始化 a ). 此声明在读写内存中创建一个包含字节的字符数组 {'j','g','k','l','\0'}

    char *b "jhdfjnfnsfnnkjdf" . 这个字符串出现在可执行映像中的一个段,通常称为“.sdata”,意思是“静态数据”。这个字符串通常存储在只读内存中,这是C标准允许的。

    这是声明字符数组和字符串常量之间的一个关键区别:即使有指向字符串常量的指针,也不应该修改内容。

        3
  •  2
  •   AShelly    15 年前

    值“jgkl”可能永远不会加载到工作内存中。之前 main 一个函数(通常被调用 cinit )正在运行。这个函数做的事情之一就是初始化静态变量和文件范围变量。在我使用的DSP编译器上,初始值存储在一个表中,该表是程序映像的一部分。表的格式与正在初始化的变量的格式无关。初始值设定项表仍然是程序映像的一部分,从不复制到RAM。简单地说,内存中没有任何地方可以可靠地访问“jgkl”。

    a 可能根本就不会存储在那个表中。优化器可以将其简化为等价的(伪指令) store reg const(152<<24|167<<16|153<<8|154)

    我怀疑大多数编译器都是类似的。

        4
  •  1
  •   Gilles 'SO- stop being evil'    15 年前

    A和C完全相等。A中使用的语法是C中语法的缩写。

    每个名为 a c 是一个字节数组,长度为5,存储在内存中的某个位置,在执行期间固定。程序可以随时更改元素字节。编译器负责决定如何初始化对象。编译器可能会生成类似 a[0] = 'j'; a[1] = 'g'; ... ,或类似于 memcpy(a, static_read_only_initialization_data[1729], 5)

    名为 b 是指向字节的指针。它的初始值是一个指向字符串文字内存的指针,在许多具有只读内存(但不是所有)的实现中,字符串文字内存是只读的。价值 b NULL ). 程序不允许更改 jhdfjnfnsfnnkjdf"

        5
  •  0
  •   user411313    15 年前

    C字面值始终是只读的。

    • 文本中的内容,其中包含“\0”
    • b) 分配sizeof(size\t)字节 内存中存储文字地址
    • c) 分配5字节内存和 在其中存储5个字符的值