问题
I am a bit confused about array declaration in C. I know that it's possible to do this:
int a[20]; // Reserved space for 20 int array
int b[] = {32, 431, 10, 42}; // Length in square brackets is auto-calculated
int *c = calloc(15, sizeof(int)); // Created a pointer to the dynamic int array
But is it possible to do this?:
int my_array[sizeof(int) * 5];
Is it a valid code, or an array length should be a constant expression (in ANSI C)?
回答1:
sizeof(int) * 5
used in the example statement in your question: int my_array[sizeof(int) * 5];
, is a constant expression, so although it does not serve as a good illustration of your primary question, it is legal syntax for C array declaration.
With the exception of C99
, variable length arrays are optional in most recent C compiler implementations. (In C99
inclusion of VLA is mandated.)
So, if your compiler supports VLA, the following are an examples:
char string[100] = {0};
scanf("%99s", string);
int VLAarray1[strlen(string)+1];//per question in comments about functions to size array.
memset(VLA1array, 0, sizeof(VLAarray1));//see Note below for initialization
int arrayLen = 0;
scanf("%d", &arrayLen);
int VLAarray2[arrayLen];
memset(VLAarray2, 0, sizeof(VLAarray2));//see Note below for initialization
int nonVLAarray[100] = {0};//initialization during declaration of nonVLA
Note: that VLAs cannot be initialized in any form during its declaration. As with all variables though it is a good idea that it be initialized in subsequent statements by explicitly assigning values to its entire region of memory.
Passing VLAs as function arguments is not included within the scope of your question, but should it be of interest, there is a good discussion on that topic here.
回答2:
(This answer answers the question in the title, “Can array length in declaration be non-constant?” The example given in the body, int my_array[sizeof(int) * 5];
does not have a non-constant length.)
Variable length arrays are optional in the current C standard, 2018, meaning a C implementation may choose to support them or not. They were mandatory in the 1999 C standard and made optional in the 2011 standard.
Variable length arrays can be declared only inside functions or there parameters, not at file scope, and they cannot have static or thread storage duration.
回答3:
This declaration
int my_array[sizeof(int) * 5];
does not declare a variable length array because the expression sizeof(int) * 5
is a constant integer expression. So even your compiler does not support variable length arrays you may use such a declaration.
From the C Standard (6.6 Constant expressions)
6 An integer constant expression117) shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof operator.
and (6.7.6.2 Array declarators)
4 If the size is not present, the array type is an incomplete type. If the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations or type names with function prototype scope; such arrays are nonetheless complete types. If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type. (Variable length arrays are a conditional feature that implementations need not support; see 6.10.8.3.)
A declaration of a variable length array can look like
const int n = 5;
int my_array[sizeof(int) * n];
The support of variable length arrays is optional in C11 and higher.
来源:https://stackoverflow.com/questions/65218793/can-array-length-in-declaration-be-non-constant