简体   繁体   中英

Is this a valid way to declare an array in C?

I know you're not supposed to declare arrays with a variable as the size ex. int arr[n]; because the size of an array is supposed to be static if not using dynamic memory but what about if you have a function like this? Would this be valid or no? It seems to run just fine.. Does the fact that it is declared inside a function have anything to do with it?

int main() {
  int n;
  scanf("%d", &n);
  exampleFunc(n);

}

void exampleFunc(int const n) {
  int arr[n];
  for (int i = 0; i < num; i++) {
    arr[i] = i + 1;
  }
}

Thanks for your help in advance. I'm a noob with C and every resource I've found is for other languages.

From the GNU GCC documentation ,

Variable-length automatic arrays are allowed in ISO C99.

If you're using the std=c99 flag, then it's guaranteed to be a valid code. But, keep in your mind that the variable-length array (VLAs) is not a standard part of C++ programming. It was a mandatory feature introduced in C99 standard.

This feature did become optional until the implementation has not defined __STDC_NO_VLA__ flag in C11 support. Thanks to @trentcl for this effective detail.

For starters there is a typo in the for loop

for (int i = 0; i < num; i++) {

The variable num is undeclared. It seems you mean

for (int i = 0; i < n; i++) {

The function declaration shall be placed before its call.

There is no great sense to declare the parameter with the qualifier const.

void exampleFunc(int const n);

These two function declarations

void exampleFunc(int const n);

and

void exampleFunc(int n);

declare the same one function.

This declaration of an array within the function

int arr[n];

will be valid provided that your compiler supports variable length arrays. Otherwise the compiler will issue an error that the size of the array shall be an integer constant expression.

Variable length arrays shall have automatic storage duration. So even if your compiler supports variable length arrays you may not declare them outside any function like for example

const int n = 10;
int a[n];

int main( void )
{
    //...
}

Also you may not initialize variable length arrays in their declarations.

Here is a demonstrative program of using a variable length array.

#include <stdio.h>

void display_pattern( size_t n )
{
    for ( size_t i = 0; i < n; i++ )
    {
        int a[i+1];
        
        for ( size_t j = 0; j < i + 1; j++ ) a[j] = ( i + j ) % n;
        
        for ( size_t j = 0; j < i + 1; j++ ) printf( "%d ", a[j] );
        putchar( '\n' );
    }
}

int main(void) 
{
    display_pattern( 10 );
    
    return 0;
}

The program output is

0 
1 2 
2 3 4 
3 4 5 6 
4 5 6 7 8 
5 6 7 8 9 0 
6 7 8 9 0 1 2 
7 8 9 0 1 2 3 4 
8 9 0 1 2 3 4 5 6 
9 0 1 2 3 4 5 6 7 8 

The 1999 revision of the language introduced variable-length arrays , where the array dimension could be specified with a runtime variable rather than a compile-time constant 1 . They cover the exact use case in your exampleFunc , allowing you to declare a local array whose size isn't known until runtime without having to rely on malloc .

VLAs are limited in their use - they cannot be used as globals or be declared as static , you can't use an initializer in their declarations, and they cannot be arbitrarily large.

VLA support has been spotty among post-C99 implementations, and the 2011 revision made their support optional. To be completely safe, you should check against the language version and the __STDC_NO_VLA__ macro to determine whether your implementation supports them or not 2 :

void exampleFunc( const int n )
{
#if __STDC_VERSION__ >= 199901L && !defined(__STDC_NO_VLA__) 
  int arr[n];
#else
  int *arr = malloc( sizeof *arr * n );
#endif

// do stuff with arr

#if !(__STDC_VERSION__ >= 19901L && !defined(__STDC_NO_VLA__))
  free( arr );
#endif
}

  1. Despite the name, a variable-length array's size is fixed for any given definition; you can't resize it after it's been defined.
  2. Personally, I would reverse the sense of that feature macro, rename it __STDC_VLA__ and only define it if VLAs are supported, but I'm not on the standards committee.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM