Aiuto programma

yoghi871
Salve a tutti sono nuovo e questa è la prima domanda che vi porgo, io devo creare un programma che acquisisca un polinomio di grado 2 e ne calcola la radice. vorrei qualche dritta sul calcolo delle radici di un polinomio di grado 2. Grazie per l'aiuto

Risposte
vict85
"luca260786":
Ciao Sergio finalmente sono riuscito a fare il programma per l'esame e funziona correttamente, anche grazie ai vostri aiuti!!!!!!!!!!!!!!!!!!!!!!!!!!
Ora volevo mettere un'aggiunta:

Se il valore acquisito è un numero tutto bene, passa all'acquisizione del secondo, e così il terzo, mentre se per caso uno dei tre valori è di tipo char il programma si deve fermare lì e richiedere nuovamente l'inserimento di un numero!!!!!!!!!!!!!! Come posso fare???????????? Ho qualche idea ma nn riesco a praticarla!!!!!!!!!!!!! Grazie 1000 in anticipo!!!!!!!!!!!!!!!


che metodo di caricamento usi?

Un metodo è questo...

#include <errno.h>

[...]

char lettura[21], *endnum;
long num;

[...]

do {

    puts("scrivi...");
    gets(lettura);
    num = strtol( lettura, &endnum, 10);

} while(endnum == lettura || errno == ERANGE);


Ho messo in un ciclo la lettura, converte in un int, se la conversione non è riuscita ritorna 0 e punta endnum a lettura (in caso contrario lo punta al primo valore non numerico) mentre se è troppo grande ritorna LONG_MAX o LONG_MIN e da ad errno valore ERANGE. Ho preferito strtol invece di atol perché di atol non si sa bene come si comporta quando il numero è troppo grosso.


P.S: se dovessi farlo accettare senza warning a quelli di microsoft dovresti scriverlo così:

#include <errno.h>

[...]

char lettura[21], *endnum;
long num;

[...]

do {

   puts("scrivi...");
   gets_s(lettura, 20);
   if (errno == EINVAL) return EXIT_FAILURE;
   num = strtol( lettura, &endnum, 10);

} while(endnum == lettura || errno == ERANGE);

Ma gets_s non è nello standard... è solo una funzione più "sicura"... EXIT_FAILURE è in stdlib.h e serve per essere sicuri che il programma dica che è uscito con un errore.

Quest'ultima parte è solo per ridere... non serve che tu scriva il programma in quel modo.

vict85
Credo sia chiaro ma devi mettere un ciclo per ogni numero. Ho usato il nome num ma tu ci metti al suo posto il nome della variabile.
Ho messo num come long per semplicità. Altrimenti avrei dovuto mettere un cast (che non è difficile ma in quel caso avrei avuto degli overflow non controllati).

luca260786
"vict85":
Credo sia chiaro ma devi mettere un ciclo per ogni numero. Ho usato il nome num ma tu ci metti al suo posto il nome della variabile.
Ho messo num come long per semplicità. Altrimenti avrei dovuto mettere un cast (che non è difficile ma in quel caso avrei avuto degli overflow non controllati).


Grazie Vict............ Ma è in linguaggio C o C++???????? A me servirebbe il C...... Cmq vedo di lavoraci sopra!!!!!!!!!!!!!!!!

vict85
"Sergio":
Lo spunto di vict85 è buono (sono abituato a tecniche... più raffinate che sarebbe un po' esagerato proporre a chi inizia), ma spero mi permetta alcune note.
1) Forse preferisci usare variabili di tipo double, quindi strtod() invece che strtol().
2) Esegui "man 3 strtod" ed anche "man 3 strtol" (a cui la man page di strtod rimanda per un esempio completo) per vedere come vanno usate le funzioni.
2) Evita come la peste gets()!!! Ti spiego più giù il motivo, ma anche vict85 suggerisce di evitarla usando get_s(), che però non è standard. Si può (si dovrebbe...) usare fgets().


I programmi di cui generalmente mi occupo generalmente non hanno a che fare con utenti e sicurezza, quindi ho messo la più semplice e veloce da scrivere.

Per luca. Sì è C.
Sono solo funzioni che generalmente non si vedono perché scanf e printf ti fanno già le conversioni.

furlani7
yoghi87 mi dai il tuo indirizzo email.

luca260786
Ciao a tutti ragazzi ho un enorme problema ho fatto il programma cn variabili locali ve lo quoto e lo devo consegnare oggi al prof, su Dev C ++ funziona prefettamente come sono andato su Ubuntu è partita la tragedia mi da degli errori che nn riesco a correggere è 2 ore che ci perdo tempo e anche altro da studiare!!!!!!!!!!!!!!!!!!! Vi prego mi potete dare una mano??????????? E' davvero urgentissimo!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Grazie 1000!!!!!!!!!!!!

Questo è il programma!!!!!!!!!!!!!!


/*********************************************************************/
/* Programma per il calcolo delle equazioni di primo e secondo grado */
/*********************************************************************/

/*****************************/
/* Inclusione delle librerie */
/*****************************/

#include <stdio.h>
#include <math.h>     /* La libreria matematica serve per la il calcolo della radice quadrata */                                                 

/* Dichiarazione delle funzioni */

void equazione_primo_grado(double , double, double);


void equazione_secondo_grado(double, double, double, double, double, double, double);


/* Definizione della funzione main */

int main(void)
{
    /* Dichiarazione delle variabili locali alla funzione */
    double a,       /* input: coefficiente di secondo grado */
           b,       /* input: coefficiente di primo grado */
           c;       /* input: termine noto */
    double x,       /* output: restituisce il risultato del calcolo dell'equazione di primo grado */
           x1,      /* output: restituisce il primo risultato nel calcolo dell'equazione di secondo grado */
           x2,      /* output: restituisce il secondo risultato nel calcolo dell'equazione di secondo grado */
           i1,      /* output: restituisce il primo risultato della parte complessa */
           i2;      /* output: restituisce il secondo risultato della parte complessa */       
    /* acquisizione del valore del coefficiente di secondo grado */ 
    printf("Inserire il valore per a: ");              
    scanf("%lf",                                          
            &a); 
                                                     
    /* acquisizione del valore del coefficiente di primo grado */                                                      
    printf("Inserire il valore per b: ");               
    scanf("%lf",
            &b);
            
    /* acquisizione del valore del termine noto */                      
    printf("Inserire il valore per c: ");              
    scanf("%lf",
            &c);
            
/* controllo del tipo di equazione tramite il valore del coefficiente di secondo grado */            
    
    if (a == 0)
    {
        equazione_primo_grado(b, c, x);                                       
    }  
    else
    {
        equazione_secondo_grado(a, b, c, x1, i1, x2, i2);
    }    
    return(0);
}        

/* Definizione della funzione equazione primo grado */
        
void equazione_primo_grado(double b, double c, double x)        
{
    
   /* controllare se il coefficiente di primo grado è uguale a zero e il termine noto è diverso da zero */
   if (b == 0 && c != 0)
   {
           
   /* comunicazione a video che l'equazione non ammette soluzioni */
   printf("L'equazione e' IMPOSSIBILE\n");
   }

   /* controllare se il coefficiente di primo grado e il termine noto sono uguali a zero */
   else if (b == 0 && c == 0)
   {
   printf("L'equazione e' INDETERMINATA\n");
   }
   else
   {      
     x = -c/b;
     printf("Il risultato dell'equazione di grado 1 %gx%+g = 0 e': \n x = %g \n", b, c, x);      
   }  
}

/* Definizione della funzione equazione secondo grado */

void equazione_secondo_grado(double a, double b, double c, double x1, double i1, double x2, double i2)
{
   /* Dichiarazione della variabile locale DELTA */
   double delta;   /* input: variabile che prende la formula del delta nell'equazione di secondo grado */
    
   /* Dichiarazione della variabile che prende la formula fondamentale per il calcolo dell'equazione di secondo grado */
   delta = b*b-4*a*c;

   /* controllare se il delta è maggiore di zero */
   if (delta > 0)
   { 

     x1 = (-b-sqrt(delta))/(2*a);
     x2 = (-b+sqrt(delta))/(2*a);
      
     /* stampa a video i due risultati dell'equazione */
     printf("Il risultato dell'equazione di grado 2 %gx^2%+gx%+g = 0 e':\n x1=%g e x2=%g.\n", a, b, c, x1, x2);
   }

   /* controllare se il delta è uguale a zero */
   else if (delta == 0)
   {
                    
     x1 = -b/(2*a);
          
     /* stampa a video il risultato coincidente */
     printf("Il risultato dell'equazione di grado 2 %gx^2%+gx%+g = 0 e':\n x1,2 = %+g.\n", a, b, c, x1);

   }
   else
   {
       
     x1 = -b/(2*a);
     x2 = -b/(2*a);
     i1 = (+sqrt(-delta))/(2*a);
     i2 = (-sqrt(-delta))/(2*a);
              
     /* stampa a video i due risultati con rispettivamente la parte reale e la parte complessa */
     printf("Il risultato dell'equazione di grado 2 %gx^2%+gx%+g = 0 e':\n x1 = %+g%+gi e x2 = %+g%+gi.\n", a, b, c, x1, i1, x2, i2);         
   }   
          
}



E questi sono gli errori!!!!!!!!!!!!!!!!!

gcc -ansi -Wall -lm -O equazioni.c -o equazioni
equazioni.c: In function ‘main’:
equazioni.c:61: warning: ‘x’ is used uninitialized in this function
equazioni.c:65: warning: ‘x1’ is used uninitialized in this function
equazioni.c:65: warning: ‘i1’ is used uninitialized in this function
equazioni.c:65: warning: ‘x2’ is used uninitialized in this function
equazioni.c:65: warning: ‘i2’ is used uninitialized in this function

Grazie 1000 sono veramente disperato!!!!!!!!!!!!!!!!! :cry:

Mi sono dimenticato di dirvi che cn Dev C++ in Windows mentre in Ubuntu nn funziona!!!!!!!!!!!!!!!!!!!!!!

luca260786
"Sergio":
Quelli non sono errori, sono solo warning.
Compaiono solo se usi insieme "-Wall" (attiva una lunga serie di warning) e "-O" (attiva un'ottimizzazione che richiede l'inizializzazione delle variabili locali [1]).
Se togli una delle due opzioni non compaiono più, e comunque...... anche se è buona norma (e costa poco) inizializzare sempre le variabili locali, puoi anche ignorarli.
E comunque, anche se non ho fatto grandi test, mi sembra funzionare correttamente.

Una sola nota.
Usare variabili locali... non vuol dire che devono essere tutte locali a main() ;-)
Lascerei a, b e c locali a main(), perché lì servono, ma main() non sa che farsi di x, x1, x2, i1 e 12.
Passerei poi a equazione_primo_grado() solo b e c, definendo dentro la funzione la variabile x.
Analogamente, passerei a equazione_secondo_grado() solo a, b e c, definendo dentro la funzione le variabili x1, x2, i1 e i2 come hai fatto con delta.

_______________________________
[1] La pagina "man gcc" è lunga, ma se cerchi "-Wuninitialized" troverai conferma di quanto ti ho detto.


Ciao Sergio, si si ho già risolto in facoltà per i warning infatti ho capito solo dopo di nn aver inizializzato le variabili!!!!!!!!!!!!!! Ok provo a fare quest'ultima modifica come hai detto tu!!!!!!!!!!!!!!! Grazie infinite sarai il primo a sapere quanto mi ha messo il prof anche se è molto pigno e s....... mi hai capito!!!!!!!!!!! Speriamo bene!!!!!!!!!!!!!!!!! :wink: :-D

Una domanda!!!!!!!!!! Quindi x, x1, x2, i1, i2 li dichiaro sempre locanlmente ma dentro le funzioni equazione_primo_grado ed equazione_secondo_grado nell'ordine in cui devono essere usate giusto???????

luca260786
"Sergio":
[quote="luca260786"]Quindi x, x1, x2, i1, i2 li dichiaro sempre locanlmente ma dentro le funzioni equazione_primo_grado ed equazione_secondo_grado nell'ordine in cui devono essere usate giusto???????

Direi che l'ordine è solo una questione di eleganza ;-)
In bocca al lupo![/quote]

Eh eh Crepi!!!!!!!!!!!!!!!!!!! Grazie!!!!!!!!!!!!!!!!!!!!!!!!! :-D

luca260786
Ciao Sergio buondì!!!!!!!!!!!!! Ho consegnato il progetto al prof!!!!!!!!! Ancora nn so il risultato sto aspettando una risposta!!!!!!!!!!!!!!
Ho una domanda stavo riguardando il programma e le dispense, vedi nella parte in cui si dichiarano e si definiscono le funzioni?????
Bene il tipo di risultato che restituisce la funzione nn è void ma dovrebbe essere un double giusto ti cuoto il codice ma solo la parte che dico

/* Dichiarazione delle funzioni */

void equazione_primo_grado(double , double, double);


void equazione_secondo_grado(double, double, double, double, double, double, double);

/* Definizione della funzione equazione primo grado */
        
void equazione_primo_grado(double b, double c, double x)

/* Definizione della funzione equazione secondo grado */

void equazione_secondo_grado(double a, double b, double c, double x1, double i1, double x2, double i2)


Ecco al posto di void nn ci andrebbe double?????? In teoria dalle dispense ho capito questo!!!!!!!!!!!!!!!

luca260786
"Sergio":
Sì e no. In casi come questo preferirei parametri di tipo puntatore a double.
In generale, una funzione che ritorna void si limita a "fare qualcosa" (ad esempio, stampare un prospetto), una funzione che ritorna double, o un valore di altro tipo, calcola quel valore e lo rende disponibile, come suo risultato, alla funzione chiamante.
In un linguaggio come il C anche le funzioni che "si limitano a fare qualcosa" ritornano un valore, per consentire alla funzione chiamante di verificare che quel "qualcosa" è stato effettivamente fatto; ad esempio, puts() ritorna un numero non negativo se è andato tutto bene, -1 se c'è stato qualche probema, ma si tratta in un valore "di controllo", non di un valore calcolato dalla funzione.
Pensa invece a sqrt(): ritorna un valore che è la radice quadrata del parametro.

Veniamo ora alle tue funzioni equazione_primo_grado() e equazione_secondo_grado().
equazione_primo_grado() potrebbe ritornare la soluzione dell'equzione, ma... cosa dovrebbe ritornare in caso di equazione impossibile o intederminata? Si potrebbe certo trovare un qualche espediente, tuttavia, per non complicare troppo, penserei a qualcosa del tipo:

int equazione_primo_grado(double b, double c, double* x)

Cioè:
- la soluzione arriverebbe alla funzione chiamante attraverso il parametro x;
- la funzione ritornerebbe valori convenzionali quali, ad esempio, 1 se x è stato effettivamente calcolato, 0 se l'equazione è impossibile, -1 se è indeterminata;
- in main() si dovrebbe esaminare il risultato della funzione per scegliere se mostrare la soluzione oppure i messaggi "equazione impossibie" e "equazione indeterminata".
Per equazione_secondo_grado() c'è un'ulteriore complicazione: deve ritornare infatti da uno a tre valori (uno se le radici sono reali e coincidenti, due se sono reali e distinte, tre se sono complesse coniugate).
Potrebbe magari ritornare un array di valori, ma anche qui preferirei qualcosa del tipo:

int equazione_secondo_grado(double a, double b, double c, double* x1, double* i1, double* x2, double* i2)

con un risultato intero che potrebbe valere:
- 1 se le soluziono sono reali coincidenti (in x1);
- 2 se le soluzioni sono reali e distinte (in x1 e in x2);
- 3 se se soluzioni sono complesse coniugate (parte reale in x1, parti immaginarie in i1 e in i2).


Capisco, Ti ringrazio!!!!!!!!!!!!!!!!!! Il prof mi ha dato la valutazione ho preso 25/30 Mancavano scelte progettuali e ingradramento, e nella relazione ho sbagliato cn le linee, e mi ha tolto 5 punti ma fa niente!!!!!!!!!!!!! Ti/Vi ringrazio (tutti quanti) per il vostro aiuto speriamo che gli altri progetti andranno meglio!!!!!!!!!! A presto a tutti!!!!!!!!!!!!!!!!!

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