Domanda Risolto Ho un problema su questo esercizio sugli array come parametri delle funzioni in c++

alessina02

Utente Iron
2 Gennaio 2022
14
6
0
9
Ultima modifica da un moderatore:
Il compilatore non dà errore, ma la funzione selection sort non gira se l'array ha più di 6 elementi e non capisco come fare per rendere la mediana double o float per renderla più precisa.
grazie a chi risponderà





/*Programma che acquisisce un numero
minore di 10 e le componenti di un
vettore e le riordina in senso
decrescente e ne calcola la mediana*/
C++:
#include <stdio.h>
#include <math.h>
int lettura_dimensione (int []);
int controllo_dimensione (int);
void selection_sort (int [], int);
int mediana (int [], int);
int main ()
{int n, a[n];
n=lettura_dimensione (a);
if (controllo_dimensione (n)==0) return 0;
selection_sort (a, n);
int med=mediana (a, n);
printf ("\nMediana=%d", a[med]);
return 0;}

int lettura_dimensione (int v[])
{int a; printf ("Inserire un intero minore di 11="); scanf("%d", &a);
if (controllo_dimensione (a)==0) {printf ("Numero maggiore di 11"); return 0;}
for (int i=0; i<a; i++) {printf ("Inserire componente %d=", i+1); scanf ("%d", &v);} return a;}

int controllo_dimensione (int a)
{if (a>10) return 0;}

void selection_sort(int a[], int n)
{int i, j, min, temp;
for(i=0;i<n-1;i++) {min=i;
    for(j=i+1;j<n;j++) {if(a[min]<a[j])
    {min=j;}
    }
 temp=a[min];
 a[min]=a;
 a=temp;}
    printf("\nIl vettore ordinato=");
    for(int i=0;i<n;i++) {printf("%d ",a);}
}

int mediana (int a[], int x)
{double m;
if (x%2==1){m=(x+1)/2; return (m-1);}
else {if (x%2==0) {m=x/2; return ((m-1)+((m)/2));
}
}
}
 

St3ve

Utente Jade
12 Ottobre 2011
2,314
5
1,648
680
Questa roba qui è molto sbagliata:
C:
int n, a[n];
Definisci una variabile intera, che inizialmente conterrà un valore a indefinito, e la usi immediatamente per definire la dimensione di un VLA. I VLA non sono array normali e fondamentalmente, da principiante, non dovresti usarli mai. Dichiararli usando una variabile non inizializzata è decisamente un errore. La dimensione degli array dev'essere una costante a tempo di compilazione: o ci metti un numero (scritto a mano nel source code) oppure usi una define in questo modo:
C:
#define SIZE 1024
int main() {
    int n, int a[SIZE]; // oppure: int n, int a[1024];
}
Nel tuo caso un numero decente per SIZE potrebbe essere 10, visto che mi pare di aver capito che puoi inserire al più 10 elementi. In ogni caso, se sei incerta inserisci un valore sufficientemente grande: è meglio inserire 32 milioni e sprecare spazio piuttosto che usare una variabile e creare un VLA.

Qui manca un else:
C:
int controllo_dimensione(int a) {
  if (a > 10)
    return 0;
}

Alcune volte nel selection sort usi l'array a come se fosse una variabile, senza usare le parentesi quadre per accedere ai suoi elementi. Dovrebbe essere fatto in questo modo:
C:
void selection_sort(int a[], int n) {
  int i, j, min, temp;
  for (i = 0; i < n - 1; i++) {
    min = i;
    for (j = i + 1; j < n; j++) {
      if (a[min] < a[j]) {
        min = j;
      }
    }
    temp = a[min];
    a[min] = a[i];
    a[i] = temp;
  }
  printf("\nIl vettore ordinato=");
  for (int i = 0; i < n; i++) {
    printf("%d ", a[i]);
  }
}

Nel calcolo della mediana non fai nessun accesso all'array a e, per rispondere alla tua domanda, dovrebbe restituire un double invece di un int (anche nel prototipo di funzione). In questo modo:
C:
double mediana(int a[], int x) {
  if (x % 2 == 1) {
    return a[x/2];
  } else {
    return (a[x/2] + a[x/2 - 1]) / 2;
  }
}

Prova a sistemare e controlla che tutto funzioni correttamente, altrimenti riposta il codice e ne discutiamo ancora.

PS. Abituati ad indentare il codice correttamente oppure usa un IDE che te lo fa in automatico. Vedrai che ti aiuterà molto.
 

alessina02

Utente Iron
2 Gennaio 2022
14
6
0
9
Purtroppo non posso dare una dimensione numerica all'array perchè l'esercizio me lo impone. Ho corretto il selection sort, ma ancora non gira se la dimensione è maggiore di 6. Nell'if non serve l'else perchè se a<10 non ci entra proprio.
Codice:
/*Programma che acquisisce un numero
minore di 10 e le componenti di un
vettore e le riordina in senso
decrescente e ne calcola la mediana*/
#include <stdio.h>
#include <math.h>
int lettura_dimensione (int []);
int controllo_dimensione (int);
void selection_sort (int [], int);
double mediana (int [], int);
int main ()
{int n;
int a[n];
n=lettura_dimensione (a);
if (controllo_dimensione (n)==0) return 0;
selection_sort (a, n);
double med=mediana (a, n);
printf ("\nMediana=%lf", med);
return 0;}

int lettura_dimensione (int v[])
{int a; printf ("Inserire un intero minore di 11="); scanf("%d", &a);
if (controllo_dimensione (a)==0) {printf ("Numero maggiore di 11"); return 0;}
for (int i=0; i<a; i++) {printf ("Inserire componente %d=", i+1); scanf ("%d", &v[i]);} return a;}

int controllo_dimensione (int a)
{if (a>10) return 0;}

void selection_sort(int a[], int n)
{int i, j, min, temp;
for(i=0;i<n-1;i++) {min=i;
    for(j=i+1;j<n;j++) {if(a[min]<a[j])
    {min=j;}
    }
 temp=a[min];
 a[min]=a[i];
 a[i]=temp;}
    printf("\nIl vettore ordinato=");
    for(int i=0;i<n;i++) {printf("%d ",a[i]);}
}

double mediana (int a[], int x)
{
if (x%2==1){ return (a[x/2]);}
else {if (x%2==0) {return ((a[x/2]+a[x/2-1])/2);
}
}
}
 

St3ve

Utente Jade
12 Ottobre 2011
2,314
5
1,648
680
Purtroppo non posso dare una dimensione numerica all'array perchè l'esercizio me lo impone.
La dimensione che devi imporre non definisce il numero di elementi che saranno contenuti nell'array, è soltanto un limite superiore. Nel tuo caso puoi definire un array con 10 milioni di elementi e usare solo i primi n, ma è più sensato definire una array di solo 10 elementi visto che n <= 10 (sprechi meno spazio). È un procedimento standard che fanno tutti. L'alternativa accettabile consiste nell'usare malloc/free per creare un array dinamico, ma non so se li hai già studiati. I VLA non li usa quasi nessuno.

Non hai corretto controllo_dimensione. Dovevi aggiungere un else, in questo modo:
C:
int controllo_dimensione(int a) {
  if (a > 10)
    return 0;
  else
    return 1;
}

E ribadisco di usare una costante (un numero, non una variabile) al posto di n perché usare una variabile non inizializzata è proprio sbagliato... anche se vuoi un VLA.

Questo è il programma che gira sul mio computer. Ho sistemato controllo_dimensione e ho sistemato e ho esplicitamente scritto int a[10]; nel main.
Codice:
Inserire un intero minore di 11=10
Inserire componente 1=1
Inserire componente 2=7
Inserire componente 3=3
Inserire componente 4=9
Inserire componente 5=4
Inserire componente 6=5
Inserire componente 7=10
Inserire componente 8=2
Inserire componente 9=6
Inserire componente 10=8

Il vettore ordinato=10 9 8 7 6 5 4 3 2 1
Mediana=5.000000

Questo è quello che succede quando inserisco 8 al posto di 10 (a runtime, perché nel codice rimane scritto 10). Riporto l'output giusto per farti capire che per l'utente l'array appare come se fosse grande 8, anche se in realtà è grande 10.
Codice:
Inserire un intero minore di 11=8
Inserire componente 1=6
Inserire componente 2=3
Inserire componente 3=5
Inserire componente 4=1
Inserire componente 5=9
Inserire componente 6=23
Inserire componente 7=591
Inserire componente 8=2349

Il vettore ordinato=2349 591 23 9 6 5 3 1
Mediana=7.000000

Se da te non funziona, posta anche input e output, ma fidati... il main fallo così:
C:
int main() {
  int n;
  int a[10]; // oppure a[100000] basta che sia un numero e non una variabile
  // ...
}
 

alessina02

Utente Iron
2 Gennaio 2022
14
6
0
9
La dimensione che devi imporre non definisce il numero di elementi che saranno contenuti nell'array, è soltanto un limite superiore. Nel tuo caso puoi definire un array con 10 milioni di elementi e usare solo i primi n, ma è più sensato definire una array di solo 10 elementi visto che n <= 10 (sprechi meno spazio). È un procedimento standard che fanno tutti. L'alternativa accettabile consiste nell'usare malloc/free per creare un array dinamico, ma non so se li hai già studiati. I VLA non li usa quasi nessuno.

Non hai corretto controllo_dimensione. Dovevi aggiungere un else, in questo modo:
C:
int controllo_dimensione(int a) {
  if (a > 10)
    return 0;
  else
    return 1;
}

E ribadisco di usare una costante (un numero, non una variabile) al posto di n perché usare una variabile non inizializzata è proprio sbagliato... anche se vuoi un VLA.

Questo è il programma che gira sul mio computer. Ho sistemato controllo_dimensione e ho sistemato e ho esplicitamente scritto int a[10]; nel main.
Codice:
Inserire un intero minore di 11=10
Inserire componente 1=1
Inserire componente 2=7
Inserire componente 3=3
Inserire componente 4=9
Inserire componente 5=4
Inserire componente 6=5
Inserire componente 7=10
Inserire componente 8=2
Inserire componente 9=6
Inserire componente 10=8

Il vettore ordinato=10 9 8 7 6 5 4 3 2 1
Mediana=5.000000

Questo è quello che succede quando inserisco 8 al posto di 10 (a runtime, perché nel codice rimane scritto 10). Riporto l'output giusto per farti capire che per l'utente l'array appare come se fosse grande 8, anche se in realtà è grande 10.
Codice:
Inserire un intero minore di 11=8
Inserire componente 1=6
Inserire componente 2=3
Inserire componente 3=5
Inserire componente 4=1
Inserire componente 5=9
Inserire componente 6=23
Inserire componente 7=591
Inserire componente 8=2349

Il vettore ordinato=2349 591 23 9 6 5 3 1
Mediana=7.000000

Se da te non funziona, posta anche input e output, ma fidati... il main fallo così:
C:
int main() {
  int n;
  int a[10]; // oppure a[100000] basta che sia un numero e non una variabile
  // ...
}
ok, adesso mi trovo, ma entrambe le mediane dovrebbero venire 5.5 e 7.5 invece perdo i decimali perchè inizializzo un intero. Il problema è che inizializzando un float o un double il programma mi dà errore
 

St3ve

Utente Jade
12 Ottobre 2011
2,314
5
1,648
680
ok, adesso mi trovo, ma entrambe le mediane dovrebbero venire 5.5 e 7.5 invece perdo i decimali perchè inizializzo un intero. Il problema è che inizializzando un float o un double il programma mi dà errore
Dividi per 2.0 (2 in double) invece che per 2 (2 in int).

Il controllo_dimensione nel main è ripetitivo. Una volta che il tuo codice funziona se vuoi puoi preoccuparti di fare un cleanup generale.
 
  • Mi piace
Reazioni: alessina02