[ANSI C] Select case e stampa a video di un array

di il
17 risposte

[ANSI C] Select case e stampa a video di un array

Salve, sono alle prime armi con il C. Ho pensato di creare un piccolo menù, sfruttando lo "swtich/case"con il quale posso raggruppare più funzioni ( in un secondo momento, credo che esporterò tutte le funzioni dalla main ad una libreria, così da avere un main più ordinato e magari riutilizzare le funzioni; per il momento è tutto nel main .) Lascio qui sotto il codice

/* dichiarazione lib utilizzate */

#include <stdio.h>

/*#include "mylib.h"  --->  temporaneamente disabilitata per controllo main */

/* ================================================== */
int main ()
{

 char i; /* variabili locale utilizzata in fase di selezione (switch) */
 
/*qui inserirò un printf con tutte le funzioni possibili, attualmente chiamo le funzioni 1,2,3,4,5*/

 i = getchar (); /*prendiamo in input la selezione */ 

switch(i) /*inizializzazione switch, utilizziamo la variabile "i" come selezione dei vari case */
{
  /*===========================================================*/
  case'1':

/* dichiarazione var locali e strutture varie*/	
	int d /*dimensione dell'array */
	
	printf("Quanti numeri in input vuoi inserire?");
	
	scanf("%lf", &d); /*prendiamo in input la dimensione dell'array */
	
	int array[d]; /*eseguo la dichiarazione dell'array dopo aver preso in input d, così posso allocare "dinamicamente" in base alle esigenze la dimensione" */
     
      int i; /*variabile utilizzata per la for*/

/*fine dichiarazione var */
/*inizio caricamento array*/
    
    for (i=0; i<10; i++)
    {
        printf("Inserisci un numero :\n");
        scanf("%d", &array[i]);
    }

/* fine caricamento array */	
/*stampo a video i valori dell'array */
	
	printf("Questo e' il risultato: ");

	for (i=0; i<10; i++)
    {
        printf("%f\n", &array[i]);
       
    }
  break;
/*===========================================================*/
  case'2':
  printf("seconda funzione\n");
  break;
/*===========================================================*/
  case'3':
  printf("terza funzione\n");
  break;
/*===========================================================*/
  case'4':
  printf("quarta funzione\n");
  break;
/*===========================================================*/
  case'5':
  printf("quinta funzione\n");
  break;
 /*===========================================================*/
  default:
  printf("la scelta non e' valida, riavvia il programma\n");
} 
 
   return 0;
}

Come su detto, eseguo la dichiarazione dell'array dopo aver preso in input d, così posso allocare "dinamicamente" in base alle esigenze la dimensione dell'array. Eseguo il caricamento dell'array e successivamente lo stampo a video, ma qualcosa dev'essere andato storto, perchè il compilatore da errori. Qualcuno sa dove ho sbagliato? Di seguito inserisco il report del gcc (compilatore)

GCC REPORT [ANSI C]:


main.c: In function ‘main’:
main.c:24:2: error: a label can only be part of a statement and a declaration is not a statement
  int d
  ^~~
main.c:25:2: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘printf’
  printf("Quanti numeri in input vuoi inserire?");
  ^~~~~~
main.c:27:6: error: ‘d’ undeclared (first use in this function)
     &d);
      ^
main.c:27:6: note: each undeclared identifier is reported only once for each function it appears in
main.c:28:6: warning: unused variable ‘array’ [-Wunused-variable]
  int array[d];
      ^~~~~

17 Risposte

  • Re: [ANSI C] Select case e stampa a video di un array

    La riga

    int d

    non termina con ;

    P.S. cosa è una Select/case in c?
  • Re: [ANSI C] Select case e stampa a video di un array

    Sono uno studentello molto scarso e tutto quello che dico prima che venga confermato da qualcuno di più esperto non ha valore.
    Nonostante ciò sono quasi sicuro che in C l'allocazione in memoria delle variabili (statiche) deve essere dichiarato all'inizio del programma. In particolare la dimensione dell'ambiente (che comprende il codice, le variabili ecc) deve essere noto a tempo di compilazione (cioè prima che il programma venga effettivamente eseguito) e non dopo.
    Di conseguenza quello che chiederesti tu è di allocare una zona di memoria solo dopo che il programma è effettivamente in esecuzione, cosa volendo fattibile attraverso la funzione malloc() che lo alloca in una zona di memoria (lo heap) adibita a questo scopo.
  • Re: [ANSI C] Select case e stampa a video di un array

    enricoscarsissimo ha scritto:


    Sono uno studentello molto scarso e tutto quello che dico prima che venga confermato da qualcuno di più esperto non ha valore.
    Nonostante ciò sono quasi sicuro che in C l'allocazione in memoria delle variabili (statiche) deve essere dichiarato all'inizio del programma. In particolare la dimensione dell'ambiente (che comprende il codice, le variabili ecc) deve essere noto a tempo di compilazione (cioè prima che il programma venga effettivamente eseguito) e non dopo.
    Di conseguenza quello che chiederesti tu è di allocare una zona di memoria solo dopo che il programma è effettivamente in esecuzione, cosa volendo fattibile attraverso la funzione malloc() che lo alloca in una zona di memoria (lo heap) adibita a questo scopo.
    Se tu sei uno studentello allora credo che io non sono nulla a confronto. Non ho la più pallida idea di cosa sia una funzione malloc e che conseguenze abbia. Tuttavia, io non ho forse dichiarato tutte le variabili all'inizio? Non capisco a cosa tu ti riferisca! Se puoi essere più .... "basico" nella spiegazione te ne sarei grato! ( grazie comunque per la risposta!)
  • Re: [ANSI C] Select case e stampa a video di un array

    oregon ha scritto:


    La riga

    int d

    non termina con ;

    P.S. cosa è una Select/case in c?
    Intendevo un istruzione di switch (grazie mille, solito errore di distrazione!)
  • Re: [ANSI C] Select case e stampa a video di un array

    Figurati! Anzi è un piacere risponderti perchè mi accorgo anche io di quello che ho capito. Allora in generale è buona norma in C dichiarare tutte le variabili (int, char, vettori) a inizio funzione, proprio per evitare tentazioni di questo tipo. In particolare tu scrivi
    scanf("%lf", &d);
    int array[d];
    ovvero dichiari la dimensione dell'array solo dopo aver preso in input d dalla scanf. Questa operazione non si può fare perchè il compilatore vuole la dimensione dell'array prima che il programma venga eseguito.
    In generale a questo punto hai 2 strade:
    1) sovradimensioni l'array con un valore alto che sai non verrà mai sforato (tipo int array[1000])
    2)Allochi un vettore dinamicamente attraverso la funziona malloc(), cosa abbastanza macchinoso e che richiede la conoscenza dei puntatore. Se sai di cosa stia parlando ti posso aiutare a scriverla altrimenti andrei io per la prima strada
  • Re: [ANSI C] Select case e stampa a video di un array

    enricoscarsissimo ha scritto:


    Figurati! Anzi è un piacere risponderti perchè mi accorgo anche io di quello che ho capito. Allora in generale è buona norma in C dichiarare tutte le variabili (int, char, vettori) a inizio funzione, proprio per evitare tentazioni di questo tipo. In particolare tu scrivi
    scanf("%lf", &d);
    int array[d];
    ovvero dichiari la dimensione dell'array solo dopo aver preso in input d dalla scanf. Questa operazione non si può fare perchè il compilatore vuole la dimensione dell'array prima che il programma venga eseguito.
    In generale a questo punto hai 2 strade:
    1) sovradimensioni l'array con un valore alto che sai non verrà mai sforato (tipo int array[1000])
    2)Allochi un vettore dinamicamente attraverso la funziona malloc(), cosa abbastanza macchinoso e che richiede la conoscenza dei puntatore. Se sai di cosa stia parlando ti posso aiutare a scriverla altrimenti andrei io per la prima strada
    Ti ringrazio molto per il supporto enrico! Per i puntatori, si ho un assaggio. Li stiamo studiando ora in università, ma il concetto non mi è molto chiaro , a questo punto, avendo sfogliato un po' di dispense, credo di dover optare per la seconda strada.Non vorrei approfittarmi della tua gentilezza, ma se potessi darmi un incipit sarebbe fantastico!
  • Re: [ANSI C] Select case e stampa a video di un array

    Cerco di essere il più chiaro possibile, se hai dubbi chiedi pure .
    Come sai i puntatori sono variabili (statiche) che salvano l'indirizzo di una certa cella di memoria. Ora, la funzione malloc è una funzione del tipo:
    malloc( dimensione da allocare in memoria), che restituisce proprio l'indirizzo della prima cella della zona di memoria che gli stai chiedendo di allocare.
    Esempio:
    voglio 5 byte da allocare per metterci dentro 5 char, se scrivo malloc(sizeof(char)*5) ti restituisce un puntatore alla prima cella di questa zona di memoria appena allocata. La zona è un unico blocco, nel senso che puoi spostarti al suo interno con la garanzia che i byte siano uno di seguito all'altro.
    Ovviamente per avere una qualche utilità dovrai ricordarti di salvare l'indirizzo da qualche parte (ovvero un puntatore), quindi una cosa del tipo:
    char * punt;
    punt = malloc(sizeof(char)*5);

    Ci siamo quasi, per farlo funzionare devi sempre fare un cast esplicito sulla funzione del tipo di puntatore che hai intenzione di assegnare, nel nostro esempio:
    char * punt;
    punt = (char *) malloc(sizeof(char) * 5);

    A questo punto potrai lavorare con punt come un normalissimo puntatore, salvandogli dentro quello che vuoi e scorrendo dentro di esso con la stesso metodo dei vettori. Ad esempio se volessi salvare 'c' nel terzo byte scriverei:
    punt[2] = 'c';

    Ultime 2 cose:
    1)ricorda sempre a fine programma di scrivere free(punt) per deallocare la zona di memoria che altrimenti rimarrebbe inutilmente allocata
    2) ricordati di scrivere #include <stdlib> a inizio programma (dove è contenuta la funzione malloc() e free() ) per farlo funzionare
  • Re: [ANSI C] Select case e stampa a video di un array

    Tornando al tuo di esercizio, scriverei a inizio programma:
    int d;
    int * vettore;
    e quando vuoi fare la scanf:
    scanf("%d",&d);
    vettore = (int)malloc(sizeof(int) * d);
    
  • Re: [ANSI C] Select case e stampa a video di un array

    enricoscarsissimo ha scritto:


    Tornando al tuo di esercizio, scriverei a inizio programma:
    int d;
    int * vettore;
    e quando vuoi fare la scanf:
    scanf("%d",&d);
    vettore = (int)malloc(sizeof(int) * d);
    
    Grazie mille enrico! Sei stato molto utile, perdona la mia risposta tardiva, ho tentato con le mie solo forse di risolvere l'inghippo la non vi son riuscito , ecco come ho modificato il codice, con le fix da te suggerite. Molto probabilmente ho sbagliato qualcosa in quanto il gcc continua a riportare i seguenti errori:

    GCC REPORT [ANSI C]
    
    main.c: In function ‘main’:
    main.c:25:2: error: a label can only be part of a statement and a declaration is not a statement
      int d;
      ^~~
    main.c:26:2: error: expected expression before ‘int’
      int *vettore;
      ^~~
    main.c:37:2: error: ‘vettore’ undeclared (first use in this function)
      vettore = (int)malloc(sizeof(int) * d);
      ^~~~~~~
    main.c:37:2: note: each undeclared identifier is reported only once for each function it appears in
    main.c:37:12: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
      vettore = (int)malloc(sizeof(int) * d);
                ^
    main.c:46:25: error: ‘array’ undeclared (first use in this function)
             printf("%f\n", &array[i]);
                             ^~~~~
    
    Invece qui inserisco il brano di codice modificato, magari riusciamo assieme a trovare il mio solito errore! ( sempre se puoi darmi una mano!). Inoltre non ho capito con la funzione malloc, da dove dovrebbe prendere la dimensione il vettore
    
    /* dichiarazione lib utilizzate */
    
    #include <stdio.h>
    #include <stdlib.h>
    
    /*#include "mylib.h"  --->  temporaneamente disabilitata per controllo main */
    
    /* ================================================== */
    int main ()
    {
    
     char i; /* variabili locale utilizzata in fase di selezione (switch) */
     
    /* qui inseriro una printf con tutte le funzioni, per il momento le chiamo 1,2,3,4,5
    
     i = getchar (); /*prendiamo in input la selezione */
     
    
    switch(i) /*inizializzazione switch, utilizziamo la variabile "i" come selezione dei vari case */
    {
      /*===========================================================*/
      case'1':
    	int d;
    	int *vettore;	
    	int i;
    /*fine dichiarazione var */
        for (i=0; i<10; i++)
        {
            printf("Inserisci un numero :\n");
            scanf("%d",&d);
    	vettore = (int)malloc(sizeof(int) * d);    
    }
    /* fine primo caricamento array */	
    	
    	printf("Questo e' il risultato: ");
    
    	/* stampo array a video */	
    	for (i=0; i<10; i++)
        {
            printf("%f\n", &array[i]);
           
        }
      break;
    
    
  • Re: [ANSI C] Select case e stampa a video di un array

    enricoscarsissimo ha scritto:


    Tornando al tuo di esercizio, scriverei a inizio programma:
    int d;
    int * vettore;
    e quando vuoi fare la scanf:
    scanf("%d",&d);
    vettore = (int)malloc(sizeof(int) * d);
    
    con la funziona " vettore = (int)malloc(sizeof(int) * d); " prendiamo l'indirizzo della prima cella di "vettore" e lo inseriamo nella variabile int d?
  • Re: [ANSI C] Select case e stampa a video di un array

    Allora ci sono un bel po' errorini, più tardi ti riscrivo il tuo codice coi commenti su quello che fai e che secondo me non ha molto senso, comunque non devo averti fatto capire come funziona la malloc. Tu scrivi
    for (i=0; i<10; i++)
        {
            printf("Inserisci un numero :\n");
            scanf("%d",&d);
       vettore = (int*)malloc(sizeof(int) * d);  
    come se ad ogni scanf salvassi il valore di d e lo infilassi in coda al vettore. Non è così. Tu con una singola scanf dichiari la dimensione dell'array, da quel momento in poi per inserire i valori nel vettore dovrai trattarlo come un normalissimo vettore, ovvero (ammesso che tu voglia usare la scanf per salvarci dentro i valori:

    for(i=0; i<d; i++)
    scanf("%d",vettore);
  • Re: [ANSI C] Select case e stampa a video di un array

    enricoscarsissimo ha scritto:


    Allora ci sono un bel po' errorini, più tardi ti riscrivo il tuo codice coi commenti su quello che fai e che secondo me non ha molto senso, comunque non devo averti fatto capire come funziona la malloc. Tu scrivi
    for (i=0; i<10; i++)
        {
            printf("Inserisci un numero :\n");
            scanf("%d",&d);
       vettore = (int*)malloc(sizeof(int) * d);  
    come se ad ogni scanf salvassi il valore di d e lo infilassi in coda al vettore. Non è così. Tu con una singola scanf dichiari la dimensione dell'array, da quel momento in poi per inserire i valori nel vettore dovrai trattarlo come un normalissimo vettore, ovvero (ammesso che tu voglia usare la scanf per salvarci dentro i valori:

    for(i=0; i<d; i++)
    scanf("%d",vettore);

    Caspita, ti ringrazio e ti aspetto!
  • Re: [ANSI C] Select case e stampa a video di un array

    Te l'ho un po' sistemato e funziona, fammi sapere
    #include <stdio.h>
    #include <stdlib.h>
    
    int main ()
    {
     int i, d;							//dichiaro tutto a inizio main
     int * vettore = NULL;
     char c = '1';
    
     		
     
    
    switch(c) //ho gia posto c = '1', negli altri casi non fa nulla
    {
      case'1':								
        //int d;									//qui dichiaravi le variabili nel corpo della switch
       // int *vettore;   							
       // int i										// tra l'altro chiamavi due variabili con lo stesso nome all'interno della stessa funzione, 
      	printf("dammi la dimensione del vettore: ");			// cosa che non puoi fare
        	scanf("%d",&d);							
        	vettore = (int *)malloc(sizeof(int) * d);   //allochi spazio in memoria, in particolare ora hai un vettore di d elementi
        	
        	for(i=0; i<d; i++){
    			printf("dammi i valori da salvarci dentro\n");
    			scanf("%d",&vettore[i]);					//inializzi il vettore coi valori che vuoi
    		}
    		printf("i valori salvati nel vettore sono:\n");
       		for (i=0; i<d; i++)						 /* stampo array a video */   
            	printf("  %d\n",vettore[i]);
        break;
        
        default:
        	break;
    }     
    	free(vettore);
    }
    
  • Re: [ANSI C] Select case e stampa a video di un array

    Ho letto da qualche parte che in C non serve il cast al tipo del puntatore, perché il puntatore a void restituito da malloc() viene accettato per qualsiasi tipo. Invece, a "lamentarsi" per la mancanza del cast sono i compilatori per C++, per i quali tale cast è obbligatorio. Dunque...

    In C (23 e' un valore a caso):
    int *p = malloc( 23 );

    In C++:
    int *p = (int*)malloc( 23 );

    Lo stesso discorso vale anche per calloc() e per realloc().
Devi accedere o registrarti per scrivere nel forum
17 risposte