Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2001
    Messaggi
    338

    [c++] inizializzazione di aggregati

    Ho un problema, non riesco a capire come sfruttare il metodo di conteggio automatico per inizializzare un array. Vi riporto il codice di un esercizio che ho fatto:

    codice:
    //: C06:es_7.cpp
    // inizializzazione aggregati
    #include <iostream>
    using namespace std;
    
    int main() {
        double arr_d[3] = {1,2};
        
        int dim_arr = sizeof arr_d / sizeof *arr_d;
        cout << "arr_d ha " << dim_arr << " elementi" << endl;
        
        for (int i = 0; i < dim_arr; i++)
            cout << "arr_d[" << i << "] = " << arr_d[i] << endl;
            
        /* dalla stampa degli elementi di nota come arr_d[2] sia inizializzato
           automaticamente a 0 */
           
        double arr_d2[] = {2, 4.5};
    
        dim_arr = sizeof arr_d2 / sizeof *arr_d2;
        cout << "arr_d2 ha " << dim_arr << " elementi" << endl;
        
        for (int i = 0; i < dim_arr; i++)
            cout << "arr_d2[" << i << "] = " << arr_d2[i] << endl;
            
        /* dalla stampa degli elementi di nota come arr_d2 abbia 2 elementi, quelli
           creati tramite inizializzazione */
    
        arr_d2[2] = 5.7;
        cout << arr_d2[2] << endl;
        
        /* prima si e' creato un nuovo elemento arr_d2, ma questo non viene computato nella
           dimensione dell'array ! */
    
        dim_arr = sizeof arr_d2 / sizeof *arr_d2;
        cout << "arr_d2 ha " << dim_arr << " elementi" << endl;
        
        for (int i = 0; i < dim_arr; i++)
            cout << "arr_d2[" << i << "] = " << arr_d2[i] << endl;
    
    }///:~
    se notate i commenti e provate il codice vi accorgete che l'elemento arr_d2[2] sembra non essere gestito come gli altri.. come mai?

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Non capisco dove sia il problema: la dimensione dell'array arr_d2 viene calcolata utilizzando questo sistema:

    1) la funzione sizeof() restituisce la dimensione in byte dell'elemento passato come parametro (nel tuo caso essa viene utilizzata come un operatore, ma l'essenziale rimane);

    2) passando un array alla funzione, essa restituisce il numero di byte che l'array occupa in memoria

    3) il valore calcolato precedentemente viene diviso per la quantità di memoria occupata da un singolo elemento dell'array (vedi il puntatore: *arr_d2)

    4) questa operazione restituisce il numero di elementi di cui l'array è composto: totale spazio occupato da tutti diviso il totale spazio occupato da 1 = totale elementi nell'array.

    Nota: l'ultima operazione serve a far capire che non c'entra se ci sono state delle inizializzazioni degli elementi o meno: tanto ciascun elemento occupa sempre lo stesso spazio, indipendentemente dal valore (un intero occupa sempre 4 byte [o 2, a seconda del S.O., compilatore, ecc.] sia che esso valga 0, sia che valga 10.000).


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2001
    Messaggi
    338
    Forse nn mi sono spiegato bene:

    1 - sono d'accordo con tutti i tuoi punti, fin qui ci siamo
    2 - le note dell'esercizio le ho scritte io
    3 - il problema e' l'ultima parte...

    codice:
    arr_d2[2] = 5.7;
    - questa istruzione crea un nuovo elemento dell'array, array che inizialmente era previsto di 2 elementi -> è giusta la sintassi?

    il compilatore nn da errori, ma io mi aspettavo che quando con

    codice:
    dim_arr = sizeof arr_d2 / sizeof *arr_d2;
    rifaccio il calcolo, la dimensione risulti 3 e non 2 !!! perche' non e' così?

    grazie

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Hai perfettamente ragione, non mi sono accorto della cosa.
    Allora: Il compilatore non ti dà problemi perchè come quasi tutti i compilatori C ti lasciano molta libertà (anche di scrivere, come in questo caso, delle vere e proprie schifezze).
    Cosa succede: la variabile arr_d2 altro non è che un puntatore (all'elemento base dell'array). Dato che si tratta solo di un puntatore e che le parentesi quadre sono solo degli operatori (aggiungono un valore al puntatore [vedi l'aritmetica dei puntatori]), è possibile indirizzare delle celle di memoria che non sono state allocate per il tuo array. Questa operazione non è sempre possibile: sconfinare un array provoca, quasi sempre, un errore di Segmentation Fault. Nel tuo caso non accade questo errore (in genere non accade con i primi 2 o 3, oltre accade) e l'operazione sembra essere andata a buon fine. Ma l'array è stato inizializzato e dimensionato per contenere solamente 2 interi e, per questo, il tuo programma continuerà a vederlo come tale: il valore aggiunto dopo tale dimensione è come se non ci fosse perchè per il programma l'array è comunque di 2 interi.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2001
    Messaggi
    338
    quindi come si fa a ridimensionare un array? non e' possibile?

    io capisco quello che mi dici, il fatto e' che in "thinking in c++", al capitolo 6 si legge:

    Un’altra scorciatoia per gli array è il conteggio automatico, con cui si lascia che sia il compilatore a determinare la dimensione dell’array in base al numero di inizializzatori forniti:
    int c[] = { 1, 2, 3, 4 };
    Se ora si decide di aggiungere un altro elemento all’array, basta aggiungere un inizializzatore.

    che significa? (potrebbe anche essere stato tradotto in modo ambiguo)

  6. #6
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Che il tuo esercizio fosse preso dal TIC l'avevo capito dal commento sull'ultima riga di codice
    Non capisco quella frase, sinceramente. Potrebbe essere stata tradotta male, anche perchè l'unico modo che conosco per rendere "più dinamico" un array è attraverso l'uso di puntatori e la funzione malloc(). Ti faccio un esempio, ma non sapendo a che livello sei arrivato, non so quanto capirai (spero tutto!)
    codice:
    int main() {
       int *mioArray;
       int i;
    
       // Ora dimensiono l'array in modo che contenga 5 interi
       mioArray = (int*) malloc(5 * sizeof(int));
    
       // Ci lavoro: lo riempio
       for (i=0; i<5; i++) mioArray[i] = i;
       for (i=0; i<5; i++) printf("Ecco l'elemento %d: %d\n", i, mioArray[i]);
    
       // Ora lo ridimensiono, lo faccio raddoppiare di dimensione
       mioArray = (int*) malloc(10 * sizeof(int));
    
       // Ci lavoro di nuovo:
       for (i=0; i<10; i++) mioArray[i] = i;
       printf("\nNuovi valori:\n\n");
       for (i=0; i<10; i++) printf("Elemento %d: %d", i, mioArray[i]);
    
       return 0;
    }
    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  7. #7
    Utente di HTML.it
    Registrato dal
    Sep 2001
    Messaggi
    338
    mi sembra di arrivarci, tra l'altro se nn sbaglio nel momento in cui ridimensioni perdi il contenuto, vero?

    in pratica bisogna usare i vector..

    grazie cmq

  8. #8
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Già... nel momento in cui ridimensioni perdi tutto il contenuto anche perchè la locazione di memoria che viene riservata non è necessariamente la stessa di prima + le celle in più adiacenti...

    Per l'utilizzo dei Vector la cosa è un po' diversa: viene prima creata una copia dei dati, poi viene ridimensionato l'array, viene ripristinata la copia e di conseguenza non si perde nulla.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  9. #9
    Utente di HTML.it L'avatar di netarrow
    Registrato dal
    Apr 2004
    Messaggi
    1,425
    prova con realloc()
    Ecco un esempio che ho testato:

    codice:
    #include <malloc.h>
    #include <iostream.h>
    
    int main() {
    	int* s = (int*)malloc(10*sizeof(int));
    	int max = 10;
    	int now = 0;
    	for(register int i = 0; i < 20; i++) {
    		s[i] = i;
    		cout << s[i] << endl;
    		now++;
    		if(now == max-1) {
    			max *= 2;
    			s = (int*)realloc((void*)s, sizeof(int)*max);
    		}
    	}
    	cout << "Aggiunti altri 30\n";
    	max += 30;
    	s = (int*)realloc((void*)s, sizeof(int)*max);
        for(register int j = 0; j < 30; j++) {
    		s[j] = j;
    		cout << s[j] << endl;
    	}
    
    	return 0;
    }
    forse è + giusto così:

    codice:
    #include <malloc.h>
    #include <iostream.h>
    
    int main() {
    	int* s = (int*)malloc(10*sizeof(int));
    	int max = 10;
    	int now = 0;
    	for(register int i = 0; i < 20; i++) {
    		s[i] = i;
    		cout << s[i] << endl;
    		now++;
    		if(now == max-1) {
    			max *= 2;
    			s = (int*)realloc((void*)s, sizeof(int)*max);
    		}
    	}
    	cout << "Aggiunti altri 30\n";
    	max += 30;
    	s = (int*)realloc((void*)s, sizeof(int)*max);
        for(register int j = 19; j < 19+30; j++) {
    		s[j] = j;
    		cout << s[j] << endl;
    	}
    
    	return 0;
    }
    Imparare è un'esperienza, tutto il resto è solo informazione. (Albert Einstein)

  10. #10
    Utente di HTML.it
    Registrato dal
    Sep 2001
    Messaggi
    338
    ok, quello che volevo fare e'trovare la strada con le classi o la filosofia del c++, grazie cmq

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.