la dimensione della matrice può essere determinata in fase di esecuzione in c?

Come so, un array deve avere una dimensione specifica prima di compilare il tempo in c.

Mi chiedo perché questo codice funzioni ancora?

int s; printf("enter the array size: "); scanf("%d",&s); int a[s]; // Isn't s value determined at run time? 

Le dimensioni degli array devono essere note con ANSI 89 C. La versione 99 delle specifiche ha rimosso questa limitazione e consentito per array di dimensioni variabili.

Ecco la documentazione no della versione GNU di questa funzione

Se è necessario allocare un array con dimensioni dinamiche, è necessario recuperarlo dall’heap, con malloc ().

 int *a = (int*)malloc(sizeof(int) * s) 

Questo codice è supportato dalle specifiche del linguaggio C99. Questo codice è anche supportato dal compilatore GCC in modalità C89 / 90 come estensione.

Quindi, la risposta alla tua domanda (perché funziona “) dipende da come la stai compilando. In generale, questo non verrà nemmeno compilato da un compilatore C89 / 90.

Stai confondendo due cose qui.

1) Determinare la dimensione di una matrice già assegnata (che il titolo implica): divide sizeof() per il totale in base alla dimensione di un elemento (diciamo, il primo):

  sizeof(a)/sizeof(a[0]) 

2) Allocazione dynamic della memoria quando la tua domanda ti chiede:

  int *a = (int*)malloc( s * sizeof(int) ); 

È importante capire come la memoria è allocata alla variabile da un compilatore per dare una risposta adeguata alla tua domanda. Ci sono due modalità in cui la memoria è allocata alla variabile, può essere su un heap o può essere su una pila. La memoria su un heap è allocata dynamicmente. Quindi una variabile che alloca memoria su un heap può essere data la sua dimensione durante il tempo di esecuzione.

Gli array in caso di C vengono dati in memoria su una pila. Per fornire memoria su una pila, la dimensione della memoria dovrebbe essere nota al compilatore durante la compilazione. In modo che durante il runtime sia ansible dedicare molta memoria alla variabile in pila. Questo è il motivo per cui non è ansible decidere la dimensione dell’array in fase di esecuzione per quanto riguarda il linguaggio C.

Le matrici a lunghezza variabile hanno fatto parte del linguaggio C dal C99 . Ma sono stati fatti come una caratteristica in C11 – il che significa che un’implementazione conforms C11 non ha bisogno di fornirla (anche se praticamente tutte le implementazioni che supportano C99 forniscono certamente VLA in C11).

È ansible verificare se l’implementazione non fornisce VLA utilizzando la macro __STDC_NO_VLA__ (se è definita in modalità di compilazione C99 o C11, quindi l’implementazione non supporta VLA).

Quindi decidere la dimensione dell’array in fase di runtime è ansible nella moderna C (> = C99) e il codice come il seguente va bene:

 int s; printf("Enter the array size: "); scanf("%d", &s); int a[s]; 

Un ovvio inconveniente dei VLA è che se s è abbastanza grande e l’allocazione di a coud fallisce. Peggio ancora, non c’è modo di verificare se l’allocazione non è riuscita e si verificheranno errori di runtime (ad esempio, segfault). È un comportamento essenzialmente indefinito . Quindi vuoi evitare VLA se la dimensione dell’array è troppo grande . Fondamentalmente, quando sei nel dubbio, vai per l’allocazione dynamic della memoria (vedi sotto).

Un altro problema, molto meno grave rispetto ad altri, con gli VLA è che hanno una durata di archiviazione automatica (ovvero “stack allocato”). Quindi, se si desidera qualcosa che dura per una durata maggiore dell’ambito del blocco in cui viene dichiarato il VLA, i VLA non sono di aiuto.

In C89 , non c’è VLA. Quindi usare l’allocazione dynamic della memoria è l’unico modo. Sebbene ci fossero alcune estensioni non standard come alloca() che è simile a VLA e ha gli stessi svantaggi dei VLA).

 int s; printf("enter the array size: "); scanf("%d",&s); int *a = malloc(s * sizeof *a); ... free(a);