Help me...array

Sk_Anonymous
Ciao raga qualcuno sa dirmi come posso dichiarare un array dinamico...Cioè voglio creare un'applicazione e inserire io degli elementi (numeri)...che verranno poi elaborati da un afunzione, in questo caso insertsort...sxo di essere stato kiaro...grazie mille...ciao!

int main()
{
int a[50],
n = 5, i, conta_passi;



for(i = 0; i < n; i++)
{
insertsort(a, n);
printf("\nArray ordinato: %d\n",a);

}

printf("\nPassi: %d\n", conta_passi);

return 0;
}

Risposte
vict85
"giocala88":
Ciao raga qualcuno sa dirmi come posso dichiarare un array dinamico...Cioè voglio creare un'applicazione e inserire io degli elementi (numeri)...che verranno poi elaborati da un afunzione, in questo caso insertsort...sxo di essere stato kiaro...grazie mille...ciao!

int main()
{
int a[50],
n = 5, i, conta_passi;



for(i = 0; i < n; i++)
{
insertsort(a, n);
printf("\nArray ordinato: %d\n",a);

}

printf("\nPassi: %d\n", conta_passi);

return 0;
}


Un array dinamico consiste nel chiedere di allocare una porzione di memoria che vuoi gestire tu (modificare dimensione, eliminare...).
Mentre la creazione di un array normale alloca una quantità di memoria che fai gestire dal pc (cioé che viene distrutto alla fine del blocco o alla fine del programma e che non può essere ridimensionato). Inoltre un array statico deve essere dichiarato con una dimensione costante (deve essere conosciuta già dal compilatore).

Dopo di che lavori in C o C++? Perché non viene usata la stessa funzione nei due programmi.
Se usi C sappi che nell'ultimo standard C sono stati aggiunti i Variable-Lenght-Array e possono essere usati in alcuni casi in cui era prima previsto l'uso di array dinamici. L'unica differenza tra questi e i normali array è che la dimensione di questi è determinata in runtime. I VLA non sono compatibili con il C++.

Se usi il C++ sappi che c'é nelle STL la libreria vector.

In ogni caso se passi un puntatore all'array e la sua dimensione non hai bisogno di riallocare quella memoria (anzi lo sconsiglierei vivamente).

In ogni caso:
C

#include <stdlib.h>

/* creare un array di tipo type di dimensione intera n, p è un puntatore a type magari restricted.
    malloc non inizializza lo spazio di memoria */
p = (type*) malloc(n * sizeof (type));

/* calloc inizializza lo spazio di memoria a zero e crea un array di n elementi*/
p = (type*) calloc(n, sizeof(type));

/* realloc modifica la dimensione dello spazio allocato */
p = (type*) realloc(p, n * sizeof (type));

/* dealloca */
free(p);


C++

/* crea */
p = new type[n];

/* distrugge */
p = delete [] type;

Sk_Anonymous
Potresti essere specifico in riferimento alla mia implementazione in ANSI C?????.grazie...

#include
#include

int insertsort(int a[],
int n);

int main()
{
int a[] = {9, 7, 1, -32, 4, 0},
n = 5, i, conta_passi;




for(i = 0; i < n; i++)
{
insertsort(a, n);
printf("\nArray ordinato: %d\n",a);

}

printf("\nPassi: %d\n", conta_passi);

return 0;
}

int insertsort(int a[],
int n)
{
int valore_ins,
i,
j,
conta_passi = 0;

for (conta_passi = 1, i = 1;
conta_passi++, (i < n);
conta_passi++, i++)
{
for(conta_passi++, valore_ins = a, j = i - 1;
conta_passi++, ((j >= 0) && (a[j] > valore_ins));
conta_passi++, j--)
{
a[j + 1] = a[j];
conta_passi++;
}
if(j + 1 != i)
{
a[j + 1] = valore_ins;
conta_passi = +2;
}
conta_passi++;
}

return(conta_passi);
}

vict85
OK, cominciamo con una implementazione corretta...

Legato a conta_passi evidenzierei che a volte i cicli non funzionano come tali ma vengono "espansi" per permettere maggiori ottimizzazioni. Il tuo conta_passi non conta realmente quelli che farebbe il pc... In ogni caso generalmente si contano solamente confronti e scambi. Non ho cambiato quella parte.

#include <stdio.h>
#include <stdlib.h>

/* è buona norma informare il compilatore quando una variabile è costante. Possono essere usati vari modi, uno è questo, gli altri due sono variabili const ed enum. */
#define N 5

/* è solo che non mi piace che si vada a capo se non ce ne bisogno, C non è Ada... è importante in un codice vedere dove partono e finiscono le prentesi e non credo che con 2 parametri abbia senso metterli uno sull'altro (ritengo sua discutibile che aumenti la leggibilità). */
int insertsort(int a[], int n);

int main() 
{
    
    int  a[N] = {9, 7, 1, -32, 4, 0}, i, conta_passi;

    /* Non sempre gli algoritmi di ordinamento capiscono che un array è ordinato e anche in quel caso farlo partire su un array ordinato equivale a fare una lettura dell'array in più */
    /* conta_passi è una variabile locale al main, insertsort non la può vedere */
    conta_passi = insertsort(a, N);

    /* con una solo operazione le parentesi non sono necessarie */
    for(i = 0; i < N; ++i)
        printf("\nArray ordinato: %d\n",a[i]);

    free(a);

    printf("\nPassi: %d\n", conta_passi);

    return 0;
}

int insertsort(int a[], int n)
{
    /* Se le metti tutti su righe diverse perdi il contatto visivo con il tipo. Se proprio vuoi andare a capo metti il ; e riscrivi il tipo */
    int valore_ins, i, j, conta_passi = 0;

    /* già detto come ritengo inutile conta_passi ma se proprio lo vuoi usare... */
    for (conta_passi = 1, i = 1; ++conta_passi, (i < n); ++conta_passi, ++i) {

        for(++conta_passi, valore_ins = a[i], j = i - 1; ++conta_passi, ((j >= 0) && (a[j] > valore_ins)); ++conta_passi, --j) {
            a[j + 1] = a[j];
            conta_passi++;
        }

        if(j + 1 != i) {
            a[j + 1] = valore_ins;
            /* hai scritto il più e il meno al contrario */
            conta_passi += 2;
        }
        ++conta_passi;
    }
    
    /* Mai visto ne sentito quel tipo di return */
    return conta_passi;
}


Ora ci occupiamo di memoria...

#include <stdio.h>
#include <stdlib.h>

int insertsort(int a[], int n);

int main() 
{
    
    int  *a, i, conta_passi;
    const int N;

    printf("Inserisci la dimensione dell'array\n");
    scanf("%d", &N);
    a = (int *) malloc( N * sizeof(int));
    for (i=0; i<N; ++i) {
        printf("Inserisci l'elemento %d\n", i);
        scanf("%d" a+i);
    }

    conta_passi = insertsort(a, N);

    /* con una sola operazione le parentesi non sono necessarie */
    for(i = 0; i < N; ++i)
        printf("\nArray ordinato: %d\n", *(a+i));

    printf("\nPassi: %d\n", conta_passi);

    return 0;
}

int insertsort(int a[], int n)
{
    /* Se le metti tutti su righe diverse perdi il contatto visivo con il tipo. Se proprio vuoi andare a capo metti il ; e riscrivi il tipo */
    int valore_ins, i, j, conta_passi = 0;

    /* già detto come ritengo inutile conta_passi ma se proprio lo vuoi usare... */
    for (conta_passi = 1, i = 1; ++conta_passi, (i < n); ++conta_passi, ++i) {

        for(++conta_passi, valore_ins = a[i], j = i - 1; ++conta_passi, ((j >= 0) && (a[j] > valore_ins)); ++conta_passi, --j) {
            a[j + 1] = a[j];
            conta_passi++;
        }

        if(j + 1 != i) {
            a[j + 1] = valore_ins;
            /* hai scritto il più e il meno al contrario */
            conta_passi += 2;
        }
        ++conta_passi;
    }
    
    /* Mai visto ne sentito quel tipo di return */
    return conta_passi;
}


Non ho provato a farlo compilare... quindi potrebbero ancora esserci errori.

Sk_Anonymous
vict85...non so cm ringraziarti...grazie mille....ciao

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.