DOMANDA Cosa si deve sapere del linguaggio C

TheJudge

Utente Attivo
335
84
CPU
i5-8600k
Dissipatore
Cooler Master TX3 EVO
Scheda Madre
MSI Z370 SLI PLUS
HDD
SAMSUNG 840 Pro 250GB + SSD Sandisk 250GB
RAM
Hiperx 2x8GB DDR4 @2666Hz
GPU
Asus Strix 1070TI
Monitor
1 Asus 24" fullHD + BENQ 27" fullHD
PSU
EVGA SuperNova 850W 80+ gold
Case
NZXT S340
OS
Windows 10 Pro
mmmh
c'è da lavorare parecchio sul risolvere problemi e possibilmente farlo con efficienza, ragionare sui tipi ecc. ecc.;
per esempio, in questo caso particolare
- per calcolare un quadrato non si chiama una funzione, si fa una semplice moltiplicazione
- i coefficienti delle eq. normalmente sono numeri "con virgola" (double)
- una conseguenza è che i test di uguaglianza sui double sono pericolosi e portano ad errori (in questo caso il test delta==0)
- per il calcolo della radice r c'è una divisione tra interi, il compilatore potrebbe eseguirla come e troncare il risultato, in barba al fatto che r è un float, producendo un risultato errato
- con delta<0 l'equazione non è impossibile
- quando un calcolo si ripete uguale nel codice, si memorizza il risultato in una variabile e si usa quella, non si chiama inutilmente più volte una funzione per ripetere il calcolo (è il caso della chiamato di pow per calcolare una radice quadrata)

Anche da un esercizio in teoria semplicissimo si imaprano concetti utili in generale

Non sono del tutto d'accordo, ovviamente è una mia opinione personale.
Risponderò in ordine:
- Per calcolare un quadrato va benissimo chiamare una funzione, il codice risulta più compatto e ordinato. ovviamente il risultato finale non cambia
- Sono d'accordo con te
- Qui non ho capito a cosa ti riferisci. Il calcolatore può calcolare fino alla sua massima precisione oltre non può andare, precisione che verifichi con il comando DBL_DIG se ricordo bene. Se vuoi più precisione esistono del LONG DOUBLE. Nel 99.9% dei casi i double bastano e avanzano.
- Anche qui non sono d'accordo. Si risolve semplicemente seguendo il tuo punto 2, ovvero dichiarando i coefficienti double
- Vero, ma lui non può ancora saperlo. Non lo avrà ancora studiato. Inutile confondergli le idee
- d'accordo con te. Il ritorno delle due soluzioni, così scritto, è uno scempio. :D :D

Tutto sommato il programma fa quello che deve fare. E' solo scritto male. Si può ancora migliorare, magari mettendo a punto un sistema che riconosca le frazioni. Renderlo un pò più user-friendly e magari facendo un controllo sui dati in arrivo. Adesso non ricordo se C controlla in automatico le variabili in ingresso ma per assurdo, se io inserissi come coefficiente una lettera, Cosa succede?
 

BAT

Moderatore
Staff Forum
Utente Èlite
22,948
11,581
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
davvero scrivere b*b per calcolare un quadrato non è sufficientemente chiaro compatto? sorvoliamo

per i test di uguaglianza sui numeri in virgola mobile c'è un un procedimento standard soprattutto in caso di calcoli matematici:
immagina di avere un numero in virgola mobile, per brevità facciamo che sia lo 0;
se questo "zero" è il risultato di calcoli su altri double invece di essere proprio 0 potrebbe essere 0.000000000001 (eventualmente col segno meno);
se fai un test di uguaglianza a 0.0 esso fallisce; di norma quando si fa un test di uguaglianza si definisce una quantità molto piccola, in genere 10^(-12) è sufficiente (10 elevato a -12). Invece di fare il test di uguaglianza devi fare un test "compreso tra" cioè, post eps=10^(-12) il test corretto
devi testare (nel caso dello 0) -eps<=delta<=eps
è una pignoleria matematica ma la procedura corretta è questa ed inoltre è valida in generale;

per la faccenda della divisone, ti sei risposto da solo: i coefficienti devi dichiararli double PRIMA;
altrimenti il compilatore potrebbe eseguire una divisione intera e solo dopo fare la conversione a double

Il resto delle cose (come controllo sull'input dell'utente) sono "zucchero";

Comunque il mio intervento mirava più a spronare Pij87 a fare molti esercizi e risolvere problemi più che a conoscere ogni dettaglio del C (cosa che probabilmente neanche serve); tutto quello che impara se lo "spende" su tutti i linguaggi.
Prima si impara a risolvere i problemi nel modo più generale
poi si impara a codificarli in un linguaggio di programmazione (qualsiasi)
poi si cerca di affinare il codice in base a quanto si sa del linguaggio prescelto
 

TheJudge

Utente Attivo
335
84
CPU
i5-8600k
Dissipatore
Cooler Master TX3 EVO
Scheda Madre
MSI Z370 SLI PLUS
HDD
SAMSUNG 840 Pro 250GB + SSD Sandisk 250GB
RAM
Hiperx 2x8GB DDR4 @2666Hz
GPU
Asus Strix 1070TI
Monitor
1 Asus 24" fullHD + BENQ 27" fullHD
PSU
EVGA SuperNova 850W 80+ gold
Case
NZXT S340
OS
Windows 10 Pro
davvero scrivere b*b per calcolare un quadrato non è sufficientemente chiaro compatto? sorvoliamo

per i test di uguaglianza sui numeri in virgola mobile c'è un un procedimento standard soprattutto in caso di calcoli matematici:
immagina di avere un numero in virgola mobile, per brevità facciamo che sia lo 0;
se questo "zero" è il risultato di calcoli su altri double invece di essere proprio 0 potrebbe essere 0.000000000001 (eventualmente col segno meno);
se fai un test di uguaglianza a 0.0 esso fallisce; di norma quando si fa un test di uguaglianza si definisce una quantità molto piccola, in genere 10^(-12) è sufficiente (10 elevato a -12). Invece di fare il test di uguaglianza devi fare un test "compreso tra" cioè, post eps=10^(-12) il test corretto
devi testare (nel caso dello 0) -eps<=delta<=eps
è una pignoleria matematica ma la procedura corretta è questa ed inoltre è valida in generale;

per la faccenda della divisone, ti sei risposto da solo: i coefficienti devi dichiararli double PRIMA;
altrimenti il compilatore potrebbe eseguire una divisione intera e solo dopo fare la conversione a double

Il resto delle cose (come controllo sull'input dell'utente) sono "zucchero";

Comunque il mio intervento mirava più a spronare Pij87 a fare molti esercizi e risolvere problemi più che a conoscere ogni dettaglio del C (cosa che probabilmente neanche serve); tutto quello che impara se lo "spende" su tutti i linguaggi.
Prima si impara a risolvere i problemi nel modo più generale
poi si impara a codificarli in un linguaggio di programmazione (qualsiasi)
poi si cerca di affinare il codice in base a quanto si sa del linguaggio prescelto

Personalmente b*b non mi piace. Ma sono abitudini mie. Tant'è che ho preceduto il tutto da "opinione personale"
Per quanto riguarda il test con lo 0 se non ricordo male (sto andando a memoria, il C non lo uso da davvero molto tempo) dovrebbero esserci delle costanti di sistema che valutano lo 0 assoluto, qualcosa di simile al NaN di Java/php etc etc, ma al momento non ricordo la sintassi.

Per la divisione ho scritto un NON che non doveva esserci. mea culpa :D

Il fatto del controllo dell'input a mio parere non è zucchero, anzi lo ritengo più importante della questione "0" (sempre parere personale). Così facendo si abitua a controllare la validità di un dato in ingresso, cosa che in C non è autogestito come in java. In C il programma va in crash mentre in Java viene lanciata un'eccezione che non chiude il programma ma lo "sospende" (non è proprio così ma verrebbe lunga spiegarla tutta).
Facendo questi controlli miro al tuo stesso obiettivo, spronare Pij87 a risolvere i problemi nel miglior modo possibile.

Personalmente quando sviluppo applicativi per altre persone parto dal presupposto che chi usa il programma sia, GIUSTAMENTE, ignorante su quanto usano, ed è giusto che il programma li aiuti a non sbagliare, come per esempio controllare l'input dell'utente. Pensa solo ad un gestionale che permetta ad un manager d'azienda di inserire lettere nel posto di un prezzo per un articolo. Sarebbe un gestionale improponibile a mio avviso.

ultima considerazione: il bello dell'informatica è che ognuno a modo di creare dal nulla ciò che vuole e COME vuole. Ognuno opererà con il suo modus operandi, giusto o sbagliato che sia per un'altra persona. L'importante, alla fine, è che il programma faccia quello che deve fare poichè il come, all'utente finale, non interessa. :D ;)
 

Pij87

Nuovo Utente
17
1
mmmh
c'è da lavorare parecchio sul risolvere problemi e possibilmente farlo con efficienza, ragionare sui tipi ecc. ecc.;
per esempio, in questo caso particolare
- per calcolare un quadrato non si chiama una funzione, si fa una semplice moltiplicazione
- i coefficienti delle eq. normalmente sono numeri "con virgola" (double)
- una conseguenza è che i test di uguaglianza sui double sono pericolosi e portano ad errori (in questo caso il test delta==0)
- per il calcolo della radice r c'è una divisione tra interi, il compilatore potrebbe eseguirla come e troncare il risultato, in barba al fatto che r è un float, producendo un risultato errato
- con delta<0 l'equazione non è impossibile
- quando un calcolo si ripete uguale nel codice, si memorizza il risultato in una variabile e si usa quella, non si chiama inutilmente più volte una funzione per ripetere il calcolo (è il caso della chiamato di pow per calcolare una radice quadrata)

Anche da un esercizio in teoria semplicissimo si imaprano concetti utili in generale

Vorrei ringraziare a tutti per le risposte.

allora premetto che ho buttato queste due righe di codice di fretta (avevo da fare ma era forte la tentazione di programmare xD) comunque io ho fatto un bel po di esercizi inerenti agli argomeni che studiavo, ho imparato parecchie cose, non so solo la teoria sò anche applicarla. Praticamente riesco a centrare l' obbiettivo il mio poblema è che non so centrarlo nella maniera più efficente, cioè "ottengo ciò che voglio", ma magari non nel migliore dei modi
 

TheJudge

Utente Attivo
335
84
CPU
i5-8600k
Dissipatore
Cooler Master TX3 EVO
Scheda Madre
MSI Z370 SLI PLUS
HDD
SAMSUNG 840 Pro 250GB + SSD Sandisk 250GB
RAM
Hiperx 2x8GB DDR4 @2666Hz
GPU
Asus Strix 1070TI
Monitor
1 Asus 24" fullHD + BENQ 27" fullHD
PSU
EVGA SuperNova 850W 80+ gold
Case
NZXT S340
OS
Windows 10 Pro
Vorrei ringraziare a tutti per le risposte.

allora premetto che ho buttato queste due righe di codice di fretta (avevo da fare ma era forte la tentazione di programmare xD) comunque io ho fatto un bel po di esercizi inerenti agli argomeni che studiavo, ho imparato parecchie cose, non so solo la teoria sò anche applicarla. Praticamente riesco a centrare l' obbiettivo il mio poblema è che non so centrarlo nella maniera più efficente, cioè "ottengo ciò che voglio", ma magari non nel migliore dei modi
L'efficienza arriva con la pratica e con l'esperienza e confrontandoti con persone che magari sono nel campo da più tempo. Non puoi pretendere di fare tutto subito in modo perfetto.
 
  • Mi piace
Reazioni: Mursey

BAT

Moderatore
Staff Forum
Utente Èlite
22,948
11,581
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
scusate, solo per chiarire: quando parlo di "zucchero" non è inteso in senso dispregiativo, anzi tutto il contrario;
per "zucchero" intendo tutto il contorno di codice (GUI, controlli su input ecc. ecc.) che addolciscono l'esperienza dell'utente che userà il programma, per cui ben venga lo "zucchero"; mi pare che in realtà qui concordiamo tutti in pieno.

Non mi è chiaro ancora il background di Pij87: ok appassionato in informatica, non tentissima esperienza di programmazione (poco male: te la fai con gli esercizi);
ma che scuola? come stai messo con la matematica? non c'è bisogno di essere Gauss, ma un po' di cose bisogna saperle
 

TheJudge

Utente Attivo
335
84
CPU
i5-8600k
Dissipatore
Cooler Master TX3 EVO
Scheda Madre
MSI Z370 SLI PLUS
HDD
SAMSUNG 840 Pro 250GB + SSD Sandisk 250GB
RAM
Hiperx 2x8GB DDR4 @2666Hz
GPU
Asus Strix 1070TI
Monitor
1 Asus 24" fullHD + BENQ 27" fullHD
PSU
EVGA SuperNova 850W 80+ gold
Case
NZXT S340
OS
Windows 10 Pro
scusate, solo per chiarire: quando parlo di "zucchero" non è inteso in senso dispregiativo, anzi tutto il contrario;
per "zucchero" intendo tutto il contorno di codice (GUI, controlli su input ecc. ecc.) che addolciscono l'esperienza dell'utente che userà il programma, per cui ben venga lo "zucchero"; mi pare che in realtà qui concordiamo tutti in pieno.

Non mi è chiaro ancora il background di Pij87: ok appassionato in informatica, non tentissima esperienza di programmazione (poco male: te la fai con gli esercizi);
ma che scuola? come stai messo con la matematica? non c'è bisogno di essere Gauss, ma un po' di cose bisogna saperle
Perdonami per lo "zucchero", non ci eravamo capito. ;)

Sono curioso anche io di sapere il profilo di Pij87
 
U

Utente 16812

Ospite
mmmh
c'è da lavorare parecchio sul risolvere problemi e possibilmente farlo con efficienza, ragionare sui tipi ecc. ecc.;
per esempio, in questo caso particolare
- per calcolare un quadrato non si chiama una funzione, si fa una semplice moltiplicazione
- i coefficienti delle eq. normalmente sono numeri "con virgola" (double)
- una conseguenza è che i test di uguaglianza sui double sono pericolosi e portano ad errori (in questo caso il test delta==0)
- per il calcolo della radice r c'è una divisione tra interi, il compilatore potrebbe eseguirla come e troncare il risultato, in barba al fatto che r è un float, producendo un risultato errato
- con delta<0 l'equazione non è impossibile
- quando un calcolo si ripete uguale nel codice, si memorizza il risultato in una variabile e si usa quella, non si chiama inutilmente più volte una funzione per ripetere il calcolo (è il caso della chiamato di pow per calcolare una radice quadrata)

Anche da un esercizio in teoria semplicissimo si imaprano concetti utili in generale

1) Un'equazione di secondo grado che ha il discriminante negativo non ammette soluzioni reali, quindi nel dominio R tale tipo di equazione è impossibile :sisi:
2) Il mio suggerimento di utilizzare le funzioni con o senza parametri era "alternativo" rispetto all'uso del costrutto IF-ELSE ma non necessariamente costituisce la migliore soluzione, fatto sta che secondo i dettami dello sviluppo TOP-DOWN un programma deve essere "modulare", basandosi su una struttura ad albero che evidenzi le "gerarchie" delle funzioni (intese come sottoprogrammi) :sisilui:
Mi rivolgo soprattutto a @Pij87, dando per scontato che gli altri lo sappiano: i sottoprogrammi si rappresentano con le funzioni :sisilui:
Il grado di astrazione nella definizione delle istruzioni dipende, invece, solo dall'autore del programma e ovviamente dalle capacità dell'esecutore :asd:
3) Ho suggerito l'implementazione di due funzioni (senza parametri), una per il calcolo del discriminante (non per il calcolo di un quadrato), chiamata ad es. CalcoloDelta, e l'altra per la scrittura delle radici a video, chiamata ad es. ScriviRadici, a cui abbinare, eventualmente, una terza funzione PrimoGrado per il caso a=0 :sisilui:
Per il calcolo della radice quadrata sarebbe meglio utilizzare la funzione predefinita sqrt(x) anziché pow(x,y) :sisilui:
4) Infine @Pij87, che ringrazio, avrebbe potuto ignorare tranquillamente la mia "richiesta" (in realtà una domanda a cui si poteva rispondere sì oppure no), ha deciso di non farlo e a lui va dato merito di aver prodotto, nel poco tempo a sua disposizione, un programma funzionante, sebbene non privo di qualche "sbavatura" :ok:
A presto :ciaociao:

- - - Updated - - -

Ciao, ma l'indentazione è quella? oppure quando hai aperto con l'editor il file che ti ha mandato si è scombinata? perchè se l'indetazione originaria fosse quella, io consiglierei fortemente di scrivere in modo più ordinato.

No, i denti non sono quelli originari, li ho persi da tempo, adesso ho la dentiera ih ih ih ih :hihi: :sisilui: :asd:

- - - Updated - - -

Vorrei ringraziare a tutti per le risposte.

allora premetto che ho buttato queste due righe di codice di fretta (avevo da fare ma era forte la tentazione di programmare xD) comunque io ho fatto un bel po di esercizi inerenti agli argomeni che studiavo, ho imparato parecchie cose, non so solo la teoria sò anche applicarla. Praticamente riesco a centrare l' obbiettivo il mio poblema è che non so centrarlo nella maniera più efficente, cioè "ottengo ciò che voglio", ma magari non nel migliore dei modi

L'ho capito, non c'era bisogno di dirlo, il programma funziona :sisilui:
 

BAT

Moderatore
Staff Forum
Utente Èlite
22,948
11,581
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
1) Un'equazione di secondo grado che ha il discriminante negativo non ammette soluzioni reali, quindi nel dominio R tale tipo di equazione è impossibile :sisi:
E allora?
le soluzioni dell'equazione esistono perché i numeri reali non esauriscono la matematica:
chi programma deve fornire le soluzioni complesse coniugate, visto che basta aggiungere un IF al controllo del delta e mettere un paio di "i" nella stampa del risultato... ed è il motivo per cui tale esercizio è praticamente "standard" (lo assegnano tutti), prima di tutto perché è semplice e poi per abituare a fare le cose per bene a chi sta imparando a programmare, ivi comprese il controllo dell'input dell'utente ed il calcolo delle soluzioni (comprese quelle che coinvolgono i numeri complessi, che a quanto ricordo si fanno alla seconda del Liceo).
 
Ultima modifica:
U

Utente 16812

Ospite
E allora?
le soluzioni dell'equazione esistono perché i numeri reali non esauriscono la matematica:
chi programma deve fornire le soluzioni complesse coniugate, visto che basta aggiungere un IF al controllo del delta e mettere un paio di "i" nella stampa del risultato... ed è il motivo per cui tale esercizio è praticamente "standard" (lo assegnano tutti), prima di tutto perché è semplice e poi per abituare a fare le cose per bene a chi sta imparando a programmare, ivi comprese il controllo dell'input dell'utente ed il calcolo delle soluzioni (comprese quelle che coinvolgono i numeri complessi, che a quanto ricordo si fanno alla seconda del Liceo).

Non in tutti gli istituti di scuola superiore in cui si studia l'informatica (ad es. negli istituti economici) si insegnano i numeri complessi, di solito, per farti un esempio, in analisi infinitesimale lo studio di una funzione si svolge nel dominio dei numeri reali :sisilui:
Io stesso, se capita, spiego i numeri complessi in elettrotecnica, quando si studia la corrente alternata, mediante la rappresentazione "simbolica" di un segnale sinusoidale nel piano complesso di Gauss e, a volte, se c'è interesse da parte degli allievi, spiego anche la rappresentazione esponenziale mediante le formule di Eulero :sisilui:
Altre volte, durante le ore di "Sistemi e Reti", illustro i numeri complessi mentre sto spiegando i metodi "trasformazionali", in particolare la trasformata di Laplace per l'analisi in transitorio di segnali sinusoidali in reti lineari :asd:
Alcune equazioni differenziali, in particolare quelle lineari a coefficienti costanti, hanno radici complesse :sisi:
Grazie per il tuo feedback ;)
 

BAT

Moderatore
Staff Forum
Utente Èlite
22,948
11,581
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
Ottimo!
Quindi concordiamo sull'importanza che certe cose bisogna saperle quando si programma.
In questo caso particolare poi il "sapere" è veramente minimo, solo che la radice quadrata di -1 è l'unità immaginaria e che l'output del programma può essere completato contemplando il caso del delta<0.
E per rimanere in tema di C, essendo l'utente interessato ad impararne il più possibile, gli interesserà sapere che i numeri complessi sono supportati dal C11 e che molti compilatori lo facevano anche da prima.
 

Tinwor

Utente Attivo
932
143
Non sono del tutto d'accordo, ovviamente è una mia opinione personale.
Risponderò in ordine:
- Per calcolare un quadrato va benissimo chiamare una funzione, il codice risulta più compatto e ordinato. ovviamente il risultato finale non cambia
- Sono d'accordo con te
- Qui non ho capito a cosa ti riferisci. Il calcolatore può calcolare fino alla sua massima precisione oltre non può andare, precisione che verifichi con il comando DBL_DIG se ricordo bene. Se vuoi più precisione esistono del LONG DOUBLE. Nel 99.9% dei casi i double bastano e avanzano.
- Anche qui non sono d'accordo. Si risolve semplicemente seguendo il tuo punto 2, ovvero dichiarando i coefficienti double
- Vero, ma lui non può ancora saperlo. Non lo avrà ancora studiato. Inutile confondergli le idee
- d'accordo con te. Il ritorno delle due soluzioni, così scritto, è uno scempio. :D :D

Tutto sommato il programma fa quello che deve fare. E' solo scritto male. Si può ancora migliorare, magari mettendo a punto un sistema che riconosca le frazioni. Renderlo un pò più user-friendly e magari facendo un controllo sui dati in arrivo. Adesso non ricordo se C controlla in automatico le variabili in ingresso ma per assurdo, se io inserissi come coefficiente una lettera, Cosa succede?

Al punto uno: evidentemente non hai mai lavorato con l'assembly se preferisci utilizzare una funzione per una semplice moltiplicazione
 

TheJudge

Utente Attivo
335
84
CPU
i5-8600k
Dissipatore
Cooler Master TX3 EVO
Scheda Madre
MSI Z370 SLI PLUS
HDD
SAMSUNG 840 Pro 250GB + SSD Sandisk 250GB
RAM
Hiperx 2x8GB DDR4 @2666Hz
GPU
Asus Strix 1070TI
Monitor
1 Asus 24" fullHD + BENQ 27" fullHD
PSU
EVGA SuperNova 850W 80+ gold
Case
NZXT S340
OS
Windows 10 Pro
Al punto uno: evidentemente non hai mai lavorato con l'assembly se preferisci utilizzare una funzione per una semplice moltiplicazione
Assembly non l'ho mai usato nel mondo del lavoro, ma l'ho usato per altro.
Proprio perchè non è assembly uso una funzione. Se parli di tempo per istruzione o occupazione di registri ti dico già che è una ottimizzazione inutile. Vero che a chiamare una funzioni impieghi più cicli di clock ma è un'ottimizzazione che non serve a nulla. Non si sta parlando di un 8086 o di un processore che va a pedali.........
Io preferisco utilizzare una funzione perchè il codice PER ME risulta più ordinato.
 

Tinwor

Utente Attivo
932
143
Scusa @TheJudge ma è una mia priorità il risparmiare più cicli e memoria possibile. Molto meglio un bel commentone, a mio modo di vedere, che una funzione con una sola istruzione
 
  • Mi piace
Reazioni: BAT

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili