Programma in C

scientifico92
Salve ragazzi sto preparando l'esame di informatica ma non riesco a trovare l'errore in questo programma.
Devo trovare massimo e minimo di un vettore tramite le funzioni ecco come l'ho scritto ma non mi fa compilare:

#include
#include
#Define N 5


float fu(float v[],int N,float *p);

int main()

{ float v[N]={1,2,3,4,5},max,min;

max=fu(v[],N,&min);
printf("Il max e' %d",max);
}


float fu (float v[],int N,float *p){
float m1,m2;
int i;
m2=v[0];

for (i=0;i if (v m2=v
}
}
*p=m2;
for (i=0;i if (v>m1){
m1=max;
}
}
return m1;
}



Sapreste dirmi dove sbaglio?

Risposte
onlyReferee
Ciao scientifico :!:
Nel corpo della tua funzione "fu" la variabile "max" ha scope (visibilità) limitata al main e pertanto non è possibile richiamarla all'interno di "fu".
Volendo, ma questo è solo un passo successivo, può ottimizzare anche il codice all'interno della tua funzione scandendo il vettore una volta sola per raggiungere il tuo scopo.

scientifico92
Ti ringrazio ho provato a migliorarlo adesso si compila però mi da sempre come risultato max=0 e min=0 e non capisco il perchè.

#include
#include
#define N 5


float fu(float v[],int M,float *p);

int main()

{ float v[N]={1,2,3,4,5},max,min;

max=fu(v,N,&min);
printf("Il max e' %d\n",max);
max=fu(v,N,&max);
printf("Il min e' %d",min);
}


float fu (float v[],int M,float *p){
float m1,m2;
int i;
m2=v[0];


for (i=0;i if (v m2=v;
}
else{
m1=v;

}
}
*p=m2;
return m1;
}

minomic
Ecco il codice funzionante:

#include <stdio.h>
#include <stdlib.h>
#define N 5


float fu(float v[],int M,float *p);

int main()

{
     float v[N]= {1,2,3,4,5},max,min;

     max = fu(v,N,&min);
     printf("Il max e' %g\n", max);
     printf("Il min e' %g\n", min);

     return 0;
}


float fu (float v[],int M,float *p)
{
     float min, max;
     int i;
     min = v[0];
     max = v[0];


     for (i=0; i<M; i++) {
          if (v[i] < min) {
               min = v[i];
          } else if (v[i] > max){
               max = v[i];
          }
     }
     *p = min;
     return max;
}

Cercavi di stampare un float ma utilizzavi %d: abituati a leggere i warning del compilatore!

Inoltre è inutile chiamare la funzione 'fu' due volte: con una sola chiamata ottieni sia 'min' sia 'max'.

C'era poi un errore di logica nella funzione 'fu' e le cose funzionavano solo perché l'array aveva elementi crescenti... In poche parole devi fare il controllo sia sul minimo che sul massimo: se è minore del minimo allora è il nuovo minimo, altrimenti se è maggiore del massimo allora è il nuovo massimo.

Infine potresti valutare l'idea di trasformare la tua funzione 'fu' in una void e restituire 'min' e 'max' scrivendo sui puntatori corrispondenti. Questo non perché sia sbagliato quello che fai, ma forse appare un po' strano.

Consiglio finale: cerca di dare nomi espliciti alle tue variabili! 'm1' e 'm2' non vogliono dire niente, e tra due giorni ti sarai già dimenticato che cosa sono. Invece 'min' e 'max' hanno significati precisi, che ti saranno sempre chiari a prima vista.

onlyReferee
"minomic":

[...]
Consiglio finale: cerca di dare nomi espliciti alle tue variabili! 'm1' e 'm2' non vogliono dire niente, e tra due giorni ti sarai già
dimenticato che cosa sono. Invece 'min' e 'max' hanno significati precisi, che ti saranno sempre chiari a prima vista.

Oltre a condividere quanto scritto da mimomic, aggiungo che il fatto di dare nomi espliciti alle variabili aiuta molto a compiere un numero minore di errori in fase di stesura del codice.
Aggiungo altri due consigli. Primo: prima di scrivere il codice bisogna pensarlo e strutturarlo per bene, nella fattispecie pensare a come è fatta la funzione che vogliamo realizzare. Secondo: per facilitare la comprensione del mancato funzionamento del codice di un programma posta anche l'errore che ti viene restituito in fase di compilazione/esecuzione.

scientifico92
Vi ringrazio entrambi per i consigli li terrò presente anche nella stesura dei prossimi programmi.
Solo due cose non mi sono ancora chiarissime:

1) Perchè nel main ho bisogno di chiamare solo una volta la funzione e no invece due trovando sia minimo che massimo scrivendo:
max = fu(v,N,&min);
min = fu(v,N,& max);

2) Ho provato a dare anche alla funzione invece di variabile M ho scritto N così:
float fu(float v[],int N,float *p);

e mi da come errori

error: expected ';', ',' or ')' before numeric constant|
|6|note: in expansion of macro 'N'|
|21|error: conflicting types for 'fu'|
13|note: previous implicit declaration of 'fu' was here|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

minomic
"scientifico":
Vi ringrazio entrambi per i consigli li terrò presente anche nella stesura dei prossimi programmi.
Solo due cose non mi sono ancora chiarissime:

1) Perchè nel main ho bisogno di chiamare solo una volta la funzione e no invece due trovando sia minimo che massimo scrivendo:
max = fu(v,N,&min);
min = fu(v,N,& max);



Quella è una funzione che fa due cose insieme: restituisce un valore (con un classico return) e scrive su una variabile passata per riferimento. Quindi è sufficiente che esegua una sola volta per "riempire" entrambe le variabili min e max. Per evitare questa confusione ti suggerivo appunto di utilizzare una funzione void e passare 'min' e 'max' per riferimento.


2) Ho provato a dare anche alla funzione invece di variabile M ho scritto N così:
float fu(float v[],int N,float *p);

e mi da come errori

error: expected ';', ',' or ')' before numeric constant|
|6|note: in expansion of macro 'N'|
|21|error: conflicting types for 'fu'|
13|note: previous implicit declaration of 'fu' was here|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|


Non ho capito cosa hai fatto, quindi non ho idea di come risolvere... Dovresti postare il codice completo.

scientifico92
Ti ringrazio per il chiarimento sulla funzione..
Per quanto riguarda il secondo punto ho risolto grazie lo stesso :smt023 ..

Non voglio rompervi ho fatto altri esercizi ma su uno mi sono bloccato.
Devo creare un programma che sia capace di codificare un messaggio.La codifica si basa su una chiave=2 che non fa altro che spostare di due posizioni una lettera.Ad esempio
A----->C
B------>D

Quando arriva a V----> A mentre Z---->B Quindi inserendo una frase del tipo: marco mi deve restituire: octeq

Io ho provato a scriverlo così:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10
#define M 10


int main()
{char frase[N+1],cifrato[M+1];
int i,k,distanza,lung_stringa;
int const chiave=2;

printf("Frase:\n");
gets(frase);

lung_stringa = strlen(frase) ;

for (i=0;i<lung_stringa;i++){
        distanza='z'-frase[i];
        for (k=0;k<lung_stringa;k++)
    if (distanza>=chiave)
    cifrato[k]=frase[i]+chiave;
    else
    cifrato[k]='a'+(chiave-distanza);
    }

puts(cifrato);


    return 0;
}



Si compila ma non mi restituisce il risultato desiderato,sapete dirmi dove sbaglio?

minomic
Ciao,

la versione corretta del tuo programma è questa:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10
#define M 10


int main()
{
     char frase[N+1],cifrato[M+1];
     int i, distanza, lung_stringa;
     const int chiave = 2;

     printf("Frase:\n");
     gets(frase);

     lung_stringa = strlen(frase);

     for (i=0; i<lung_stringa; i++) {
          distanza = 'z' - frase[i];
          if (distanza >= chiave)
               cifrato[i] = frase[i] + chiave;
          else
               cifrato[i] = 'a' + (chiave - distanza - 1);
     }

     puts(cifrato);


     return 0;
}

Ti invito ovviamente a osservare le differenze, e in particolare il fatto che il secondo ciclo for fosse sbagliato: ci deve essere una corrispondenza uno-a-uno tra le lettere, quindi ci vuole un solo ciclo for che scandisca tutta la stringa.

Inoltre ti posto un'altra versione del programma, dove tutta l'operazione di cifratura viene fatta su una sola riga sfruttando l'aritmetica modulare. Ti ricordo che l'operatore % restituisce il resto della divisione.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10
#define M 10


int main()
{
     char frase[N+1],cifrato[M+1];
     int i, lung_stringa;
     const int chiave = 2;

     printf("Frase:\n");
     gets(frase);

     lung_stringa = strlen(frase);

     for (i=0; i<lung_stringa; i++) {
          cifrato[i] = ((frase[i] - 'a' + chiave) % ('z' - 'a' + 1)) + 'a';
     }

     puts(cifrato);


     return 0;
}

Se hai dubbi, siamo qui.

scientifico92
Ho visto le differenze tra i due codici mi trovo sul fatto che dovevo aggiungere -1 per calcolare cifrato,solo che per quanto riguarda il for se ne metto due come ho fatto io non dovrebbe essere la stessa cosa solo con passaggi in più?
Visto che sia i che k si spostano insieme no?

Inoltre quando vado a compilarlo mi da il mio risultato giusto però poi mi riscrivere anche la frase che ho inserito non cifrata e non capisco il perchè sinceramente.

Per quanto riguarda il secondo codice sinceramente non ci avevo proprio pensato sono ancora troppo un principiante :-D

minomic
Il primo codice che avevi postato (quello con i due cicli for annidati) era sbagliato per un semplice motivo: ad ogni lettera della parola non cifrata andavi a scandire (e modificare!) tutta la stringa cifrata. Invece la corrispondenza è uno a uno: la i-esima lettera cifrata è funzione della sola i-esima lettera non cifrata.
Infatti il risultato che si otteneva era qqqqq, perché riportava 5 volte la lettera 'q', corrispondente cifrata della 'o', cioè l'ultima lettera della parola 'marco'.

Nota: 'i' e 'k' non si spostavano insieme, perché i due cicli for erano annidati. Quindi ad ogni 'scatto' di 'i' corrispondevano N scatti di 'k'.

apatriarca
Dal testo originale sembrerebbe si debba prendere in considerazione l'alfabeto italiano e non quello inglese. Se supponiamo di voler effettivamente inserire questa restrizione, il codice dovrà essere modificato (e complicato) di conseguenza. Un metodo molto semplice sarebbe ovviamente quello di usare un array per questa conversione. In effetti il metodo basato su un "dizionario" permetterebbe codifiche anche molto più complicate. Ma immagino che il professore pensasse a qualcosa tipo quello postato da minomic.

scientifico92
Grazie per l'aiuto ho capito dove sbagliavo...
Comunque l'esercizio intendeva lettere dell'alfabeto inglese.

scientifico92
Salve ragazzi mi sono bloccato su questo esercizio.
Devo creare un programma in c che legga da tastiera due numeri interi corrispondenti a base ed esponente ed esegua il calcolo della potenza.
Ho provato a svolgerlo ma non mi da il risultato che mi aspetto.


#include <stdio.h>
#include <stdlib.h>
int power(int base,int esponente);

int main()

{ int a,b,risultato;

printf("Inserire due numeri\n");
    scanf("%d", &a);
    scanf("%d", &b);
    risultato=power(a,b);
        printf("Il risultato e' %d",risultato);
        return 0;
}

int power(int base,int esponente)

{
    int risultato,i;

    for(i=0;i<esponente;i++)
        risultato*=base;

    return risultato;
}

apatriarca
Non hai inizializzato risultato..

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.