Domanda programma in c89

gius1805

Utente Bronze
13 Novembre 2020
42
22
0
38
Scrivere un sottoprogramma che riceve come parametri un array di
interi a e la sua dimensione dim. Il sottoprogramma copia in un
secondo array b i numeri pari contenuti in a; si noti che b deve
essere allocato dinamicamente delle dimensioni strettamente
necessarie per contenere i numeri pari. Infine il sottoprogramma
trasmette al chiamante b e la sua dimensione. Gestire opportunamente
gli eventuali errori di allocazione della memoria trasmettendo una
dimensione dell'array allocato pari a -1.
Scrivere un programma che chiede all'utente 10 valori interi da
salvare in un array. Il programma invoca il sottoprogramma sopra
definito e ne visualizza il risultato. Infine il programma libera la
memoria allocata. Gestire opportunamente gli eventuali errori di
allocazione della memoria.
C:
#include <stdio.h>
#include <stdlib.h>

#define MAX 3

int* numeri_pari(int array[], int dim, int *dim_pari);

int main(){
    int array[MAX], i, *a, dim_pari=0;

    printf("inserire valori:\n");
    for(i=0; i<MAX; i++){
        scanf("%d", &array[i]);
    }

    a=numeri_pari(array, MAX, &dim_pari);
    for(i=0; i<dim_pari; i++){
        printf("%d\n", *(a+i));
    }

    return 0;
}

int* numeri_pari(int array[], int dim, int *dim_pari){
    int i, j=0, *p;

    for(i=0; i<dim; i++){
        if(array[i]%2==0)
            (*dim_pari)++;
    }

    p=malloc(sizeof(int)*(*dim_pari));
    if(p){
        for(i=0; i<dim || j!=(*dim_pari); i++){
            if(array[i]%2==0){
                *(p+j)=array[i];
                j++;
            }

        }
        return p;
        free(p);
    }
    else{
        printf("Err. Malloc\n");
        *dim_pari = -1;
    }
}
Ho scritto questo programma e volevo se fosse giusto.
Grazie in anticipo.
 
E' (quasi) corretto e funziona, ma ci sarebbero aspetti da rivedere (e una precisazione che voglio fare).

MAX dovrebbe valere 10, ma credo che il valore scelto sia solo per comodità nei test (ricordati di cambiarlo).
Per comodità, puoi anche sfruttare il ciclo di input per contare già i numeri pari. Comunque non è errato ciò che hai fatto.

Il controllo che hai aggiunto nella condizione del for (il test su j) non serve, sai già che verrà rispettato (usi la stessa condizione anche sotto).
Quindi puoi trasformarlo solo in:
C:
 for(i=0; i<dim; i++){

La precisazione è su questa parte di codice:
C:
        return p;
        free(p);

quando viene eseguito il return, il controllo passa già al chiamante, quindi quel "free" non verrà mai eseguito.
Se avessi fatto il contrario sarebbe stato un errore grave conosciuto come dangling pointer. L'errore consiste in sostanza nel fare il free di un puntatore, e poi continuare a utilizzarlo per accedere alla locazione di memoria.
Ciò che hai fatto diciamo che è un errore in quanto non rispetti la traccia dell'esercizio: non avviene mai il free, quindi dovresti farlo nel main.

Il check sull'errore: il messaggio di errore dovresti lasciarlo al chiamante (al main) e non alla funzione chiamata, e dovresti anche restituire il puntatore all'array, anche se nullo.

Vedo che usi sempre questa sintassi *(p+j), puoi utilizzare anche le "parentesi quadrate", p[j].

Ricapitolando, il codice completo potrebbe essere (l'ho lasciato il più possibile simile al tuo):

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

#define MAX 3

int* numeri_pari(int array[], int dim, int *dim_pari);

int main(){
    int array[MAX], i, *a, dim_pari=0;

    printf("inserire valori:\n");
    for(i=0; i<MAX; i++){
        scanf("%d", &array[i]);
    }

    a=numeri_pari(array, MAX, &dim_pari);

    if(dim_pari == -1) {
        printf("Err. Malloc\n");
        return -1;
    }
    
    for(i=0; i<dim_pari; i++){
        printf("%d\n", *(a+i));
    }

    free(a);

    return 0;
}

int* numeri_pari(int array[], int dim, int *dim_pari){
    int i, j=0, *p;

    for(i=0; i<dim; i++){
        if(array[i]%2==0)
            (*dim_pari)++;
    }

    p=malloc(sizeof(int)*(*dim_pari));

    if(p){
        for(i=0; i<dim; i++){
            if(array[i]%2==0){
                *(p+j)=array[i];
                j++;
            }
        }
        return p;
    }

    *dim_pari = -1;
    return p;
}

Solo a titolo di esempio, l'if puoi anche riscriverlo in questo modo:
C:
            if(array[i]%2==0){
                p[j++] = array[i];
            }

E se hai già fatto gli operatori che operano sui bit, puoi anche mostrare al tuo prof di saperli usare, scrivendolo in questo modo if(!(array[i] & 1)){.
 
  • Mi piace
Reazioni: gius1805