Linguaggio C, array e puntatori

di il
19 risposte

Linguaggio C, array e puntatori

Testo esercizio:

Scrivere un programma in linguaggio C che realizzi:
A) la funzione: char* unione(char A[], int nA, char B[], int nB, int* sizeResult) che dati gli array di ingresso A e B alloca dinamicamente un nuovo array che rappresenta l'unione di A e B e lo restituisce. Verificare la funzione mediante un'opportuna funzione main di prova.


*sizeResult sarebbe la somma della dimensione dei due array? Perché lo passa come puntatore a intero?

19 Risposte

  • Re: Linguaggio C, array e puntatori

    Ciao,
    viene passato un puntatore a sizeResult in modo che la funzione sia in grado di modificarlo.
    Mi spiego meglio: nel main dichiari un intero, ad esempio
    int newSize;
    poi alla funzione non passi newSize ma IL SUO INDIRIZZO, in modo che questa possa modificare il valore della variabile, quindi
    ... = unione(..., &newSize)
    Alla fine dell'esecuzione della funzione, il main vedrà "magicamente" quello che la funzione ha scritto, proprio perché a quest'ultima era noto non il valore, ma proprio l'indirizzo della variabile newSize.

  • Re: Linguaggio C, array e puntatori

    Credo di aver capito.

    Dato che, per regola, una funzione può ritornare un solo valore, in questo caso l'array risultante dell'unione degli altri due, nel main avrei questo vettore ma non conoscerei la sua dimensione.

    Quindi non potrei farci nulla. Perciò gli passo l'indirizzo della variabile che contiene la somma delle dimensioni degli altri due vettori, in modo tale da ritrovarmelo direttamente modificato.

    Corretto?
  • Re: Linguaggio C, array e puntatori

    Esatto! Con questo "trucco" puoi "ritornare" tutto quello che vuoi. Tecnicamente il return rimane uno solo ma i valori modificati dalla funzione (e quindi visibili al main) possono essere molti di più.
  • Re: Linguaggio C, array e puntatori

    Ok, capito!
    Ti ringrazio, e buone feste!
  • Re: Linguaggio C, array e puntatori

    davide.fruci ha scritto:


    buone feste!
    Grazie, anche a te!

  • Re: Linguaggio C, array e puntatori

    Ho fatto il programma, eccoli qui, ma c'è un problema:

    main.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    #include "unione.h"
    #include "allocazione.h"
    int main()
    {
    	allocazione_dinamica();
    	
    	return 0;
    }
    allocazione.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    #include "allocazione.h"
    void allocazione_dinamica()
    {
    	int a, *A, b, *B, a_piu_b, i, j; 
    					
    	
    	printf("a: "); scanf("%d", &a);
    	printf("b: "); scanf("%d", &b);
    	
    	a_piu_b = a + b;
    	
    	//Allocazione dinamica della memoria
    	A = (int *) malloc (a * sizeof(int));
    	B = (int *) malloc (b * sizeof(int));
    	
    	//Caricamento dei vettori, modalità RANDOM
    	for(i = 0; i < a; i++)
    	{
    		printf("A[%d] = ", i);
    		scanf("%d", &A[i]);
    		printf("\n");
    	}
    		//A[i] = rand()%10;
    	for(j = 0; j < b;  j++)
    	{
    		printf("B[%d] = ", j);
    		scanf("%d", &B[j]);
    		printf("\n");
    	}
    		//B[i] = rand()%10;
    	
    	//Stampa dei vettori prima dell'unione
    	printf("Array prima di essere uniti: \n");
    	for(i = 0; i < a; i++)
    		printf("A[%d] = %d\n", i, A[i]);
    		
    	printf("\n");
    		
    	for(j = 0; j < b;  j++)
    		printf("B[%d] = %d\n", j, B[j]);
    	
    	//Invocazione della funzione unione
    	unione(A, a, B, b, &a_piu_b);
    	
    	
    }
    unione.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    #include "unione.h"
    
    char* unione(char A[], int nA, char B[], int nB, int* sizeResult)
    {
    	int i, *U; //Indice di scorrimento, *U array di unione 
    	
    	//Allocazione dinamica del vettore unione U
    	U = (int*) malloc (*sizeResult * sizeof(int));
    	
    	//Caricamento del vettore
    	for(i = 0; i < nA; i++)
    		U[i] = A[i];
    	for(i = nA; i < nB; i++)
    		U[i] = B[i];
    	printf("\n");
    	for(i = 0; i < *sizeResult; i++)
    		printf("U[%d] = %d\n", i, U[i]);
    	
    	
    }
    
    Funziona quasi tutto, quasi. Guarda l'output cosa mi da:

    a: 2
    b: 3
    A[0] = 1

    A[1] = 2

    B[0] = 3

    B[1] = 4

    B[2] = 5

    Array prima di essere uniti:
    A[0] = 1
    A[1] = 2

    B[0] = 3
    B[1] = 4
    B[2] = 5

    U[0] = 1
    U[1] = 0
    U[2] = 0
    U[3] = 0
    U[4] = 0


    Come mai? Grazie ancora.
  • Re: Linguaggio C, array e puntatori

    A occhio vedo che questo pezzo è sbagliato:
    
    //Caricamento del vettore
       for(i = 0; i < nA; i++)
          U[i] = A[i];
       for(i = nA; i < nB; i++)
          U[i] = B[i];
    
    Quando carichi i dati dal vettore B l'indice deve ripartire da zero!
  • Re: Linguaggio C, array e puntatori

    Ho provato, ma niente
  • Re: Linguaggio C, array e puntatori

    Forse non mi sono spiegato bene: un primo indice dovrà tenere traccia di quanti posti hai già riempito nell'array di destinazione; un secondo indice dovrà tenere traccia di dove sei nel vettore B.
    Quindi il primo partirà da nA, mentre il secondo da 0.

    In ogni caso ora dò un'occhiata al codice.
  • Re: Linguaggio C, array e puntatori

    Ecco qui: avevi fatto confusione tra int e char... E poi guarda bene la concatenzaione tra i due array e come ho usato la variabile "riempito". Inoltre nella tua funzione mancava il return: facevi direttamente la stampa... Invece la funzione unione deve restituire l'array-unione; della stampa si occuperà qualcun altro.
    In ogni caso ho sistemato la funzione di unione. Ora prova a rimettere la parte di riempimento dei vettori con input dell'utente.
    
    #include <stdio.h>
    #include <stdlib.h>
    
    char* unione(char A[], int nA, char B[], int nB, int* sizeResult)
    {
        int i, riempito=0;
        char * U;       /* lo avevi dichiarato come int* */
    
        //Allocazione dinamica del vettore unione U
        * sizeResult = nA+nB;
        U = (char*) malloc (*sizeResult * sizeof(char));
    
        //Caricamento del vettore
        for(i = 0; i < nA; i++)
        {
            U[i] = A[i];
            riempito++;
        }
        for(i = 0; i < nB; i++)
        {
            U[riempito] = B[i];
            riempito++;
        }
        return U;
    
    }
    
    int main()
    {
        char primo[5] = {'a', 'b', 'c', 'd', 'e'};
        char secondo[4] = {'f', 'g', 'h', 'i'};
        int totale;
        char * uniti = unione(primo, 5, secondo, 4, &totale);
    
        int i=0;
        for(i=0; i<totale; i++)
        {
            printf("%c\n", uniti[i]);
        }
    
    
        return 0;
    }
    
  • Re: Linguaggio C, array e puntatori

    Ok, grazie. Sìsì, lo so che devo ritornare il vettore e non stamparlo, volevo prima provare.

    Hai ragione, ho mischiato int con char per la fretta.
    Ho apportato le modifiche che mi hai detto, ma ora ho un altro problema!
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    #include "allocazione.h"
    void allocazione_dinamica()
    {
    	int a, b, a_piu_b, i, j; 
    	char *A, *B;				
    	
    	printf("a: "); scanf("%d", &a);
    	printf("b: "); scanf("%d", &b);
    	
    	a_piu_b = a + b;
    	
    	//Allocazione dinamica della memoria
    	A = (char *) malloc (a * sizeof(char));
    	B = (char *) malloc (b * sizeof(char));
    	
    	//Caricamento dei vettori, modalità RANDOM
    	for(i = 0; i < a; i++)
    	{
    		printf("A[%d] = ", i);
    		scanf("%c", &A[i]);
    		printf("\n");
    	}
    		//A[i] = rand()%10;
    	for(j = 0; j < b;  j++)
    	{
    		printf("B[%d] = ", j);
    		scanf("%c", &B[j]);
    		printf("\n");
    	}
    		//B[i] = rand()%10;
    	
    	//Stampa dei vettori prima dell'unione
    	printf("Array prima di essere uniti: \n");
    	for(i = 0; i < a; i++)
    		printf("A[%d] = %c\n", i, A[i]);
    		
    	printf("\n");
    		
    	for(j = 0; j < b;  j++)
    		printf("B[%d] = %c\n", j, B[j]);
    	
    	//Invocazione della funzione unione
    	unione(A, a, B, b, &a_piu_b);
    	
    	
    }
    Mi da errore nell'inserimento dei dati, guarda quando lo eseguo che accade:

    a: 2
    b: 3
    A[0] =
    A[1] =


    A[0] non me lo fa inserire, passa subito ad A[1]. Sarà la stanchezza ma io non riesco a trovare l'errore

    Grazie ancora!
  • Re: Linguaggio C, array e puntatori

    Mettendo tutto a int, compresi vettori e il prototipo della funzione, ora va alla grande!
  • Re: Linguaggio C, array e puntatori

    Così funziona tutto:
    
    #include <stdio.h>
    #include <stdlib.h>
    
    char* unione(char A[], int nA, char B[], int nB, int* sizeResult)
    {
        int i, riempito=0;
        char * U;       /* lo avevi dichiarato come int* */
    
        //Allocazione dinamica del vettore unione U
        * sizeResult = nA+nB;
        U = (char*) malloc (*sizeResult * sizeof(char));
    
        //Caricamento del vettore
        for(i = 0; i < nA; i++)
        {
            U[i] = A[i];
            riempito++;
        }
        for(i = 0; i < nB; i++)
        {
            U[riempito] = B[i];
            riempito++;
        }
        return U;
    
    }
    
    int main()
    {
        int dimA, dimB, i, totale;
        char * primo;
        char * secondo;
        printf("Inserire dimensione primo array: ");
        scanf("%d", &dimA);
        printf("Inserire dimensione secondo array: ");
        scanf("%d", &dimB);
    
        primo = (char *) malloc(dimA * sizeof(char));
        secondo = (char *) malloc(dimB * sizeof(char));
    
        for(i=0; i<dimA; i++)
        {
            printf("A[%d] = ", i);
            scanf(" %c", &(primo[i]));
        }
    
        for(i=0; i<dimB; i++)
        {
            printf("B[%d] = ", i);
            scanf(" %c", &(secondo[i]));
        }
    
        char * uniti = unione(primo, dimA, secondo, dimB, &totale);
    
        for(i=0; i<totale; i++)
        {
            printf("%c\n", uniti[i]);
        }
    
        return 0;
    }
    
    Probabilmente il problema erano i temutissimi "leading white spaces"...
  • Re: Linguaggio C, array e puntatori

    Ah.. non la sapevo questa cosa! Comunque ora ho cambiato tutto con int e non mi va di ricambiare tutto nuovamente. Comunque, grazie per l'informazione!

    Un'ultimissima cosa, premetto che il programma funziona:

    allocazione.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    #include "allocazione.h"
    void allocazione_dinamica()
    {
    	int a, b, a_piu_b, i, j, *A, *B, *U;				
    	
    	printf("a: "); scanf("%d", &a);
    	printf("b: "); scanf("%d", &b);
    	
    	a_piu_b = a + b;
    	
    	//Allocazione dinamica della memoria
    	A = (int *) malloc (a * sizeof(int));
    	B = (int *) malloc (b * sizeof(int));
    	
    	//Caricamento dei vettori, modalità RANDOM
    	for(i = 0; i < a; i++)
    		A[i] = rand()%10;
    	for(j = 0; j < b;  j++)
    		B[i] = rand()%10;
    	
    	//Stampa dei vettori prima dell'unione
    	printf("Array prima di essere uniti: \n");
    	for(i = 0; i < a; i++)
    		printf("A[%d] = %d\n", i, A[i]);
    		
    	printf("\n");
    		
    	for(j = 0; j < b;  j++)
    		printf("B[%d] = %d\n", j, B[j]);
    	
    	//Invocazione della funzione unione
    	U = unione(A, a, B, b, &a_piu_b);
    	
    	printf("Array unito: \n");
    	
    	for(i = 0; i < a_piu_b; i++)
    		printf("U[%d] = %d\n", i, U[i]);
    	
    }
    unione.c
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    #include "unione.h"
    
    int* unione(int A[], int nA, int B[], int nB, int* sizeResult)
    {
    	int i, j, riempito = 0, *U; //array di unione 
    	
    	//Allocazione dinamica del vettore unione U
    	U = (int*) malloc (*sizeResult * sizeof(int));
    	
    	//Caricamento del vettore
    	for(i = 0; i < nA; i++)
    	{
    		U[i] = A[i];
    		riempito++;
    	}
    	for(i = 0; i < nB; i++)
    	{
    		U[riempito] = B[i];
    		riempito++;
    	}
    	printf("\n");
    	
    	return U;
    }
    Nonostante funzioni tutto correttamente, mi da questo warning:

    allocazione.c:37:4: warning: assignment makes pointer from integer without a cast [enabled by default]
    U = unione(A, a, B, b, &a_piu_b);
Devi accedere o registrarti per scrivere nel forum
19 risposte