在C中,您应该定义数组的长度。但是,以下代码是有效的:
int arr[] = {10, 20, 30, 40, 50};为什么这是可接受的语法?
发布于 2019-03-14 16:03:49
这是可以接受的,因为整数的大小(以字节为单位)是在编译期间已知的,因此编译器知道整个列表需要多少空间。
但是要理解这个答案,就必须深入挖掘,并询问为什么在编译过程中知道确切的大小是如此重要。泛指:为您的程序定义虚拟地址空间。其中一部分是存储局部变量的堆栈,不能将其与堆内存( malloc工作的地方)混淆。堆栈是一个LIFO列表,还包含所有函数调用及其参数。它用于函数的末尾,用于回跳,您来自哪里,并为此存储了一个内存地址。当您处于函数中时,堆栈上的所有内容都必须被释放,以便到达正确的回跳地址并避免潜在的分段错误。
幸运的是,C为我们自动进行这种类型的内存管理,并在所有自动变量被认为“超出作用域”时释放它们。要做到这一点,我们需要精确的大小,我们已经推到堆栈,这就是为什么编译器已经需要知道的大小。
要说明编译器如何翻译代码和硬代码,请参见此处:
$ echo "int int_size = sizeof(int); int main(void) { int arr[] = {10, 20, 30, 40, 50}; }" |\
gcc -c -xc -S -o- -masm=intel -
.file ""
.intel_syntax noprefix
.text
.globl main
.type main, @function
# [...] removed int_size here to keep it shorter. its "4" ;)
main:
.LFB0:
.cfi_startproc
push rbp # < backup rbp / stack base pointer
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
mov rbp, rsp # < rsp / stack shift pointer = top of the stack
.cfi_def_cfa_register 6
sub rsp, 32
mov rax, QWORD PTR fs:40
mov QWORD PTR -8[rbp], rax
xor eax, eax
mov DWORD PTR -32[rbp], 10 # < 10 is one element from the array
mov DWORD PTR -28[rbp], 20 # < -28 means relative to the top of the stack
mov DWORD PTR -24[rbp], 30
mov DWORD PTR -20[rbp], 40
mov DWORD PTR -16[rbp], 50
mov eax, 0
mov rdx, QWORD PTR -8[rbp]
xor rdx, QWORD PTR fs:40
je .L3
call __stack_chk_fail@PLT
.L3:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (GNU) 8.2.1 20181127"
.section .note.GNU-stack,"",@progbits发布于 2019-03-11 14:56:35
这是一个方便的功能。数组的大小是从初始化器中推导出来的,因此不必拼写它:
int arr[] = {10, 20, 30, 40, 50};相等于
int arr[5] = {10, 20, 30, 40, 50};这方面的另一个例子(感谢Eugene Sh.)是字符串初始化器:
char str[] = "asd";相等于
char str[4] = "asd";需要知道的一件重要的事情是,当用作函数参数的类型时,情况是不同的。以下所有表格:
void foo(int v[])
void foo(int v[1])
void foo(int v[5])
void foo(int v[1000])所有这些都是相互等效的,它们被转化为:
void foo(int* v)总是使用后者(void foo(int* v)),而不要使用其他的。因为第一种形式使它看起来像是有一个数组类型,但实际上您拥有的是一个指针。这是误导。
发布于 2019-03-11 15:16:38
补充现有答案,引用C11,第6.7.9节,P22
如果初始化了未知大小的数组,则其大小由具有显式初始化器的最大索引元素确定。数组类型在其初始化程序列表的末尾完成。
因此,数组的大小将由“最大索引元素”决定,或者简单地说,由初始化程序列表中的元素计数决定。
https://stackoverflow.com/questions/55104620
复制相似问题