PDA

View Full Version : [c++]Mi aiutate a capire l'istruzione?


Bandit
06-05-2009, 11:37
Ciao a tutti ragazzi
vorrei capire un' istruzione a cosa serve: vi spiego il problema: devo visulizzare gli interi da 1 a 20 usando un ciclo for con variabile contatore x intera e inizializzata ad 1.Devo visualizzare 5 interi per linea , se il valore è 0, visualizza un carattere nuova linea se no carattere di tabulazione


for(x=1; x<=20 ; x++)
count<<x;
if (x%5==0) <<<questa if non la capisco cosa significa?<<<
cout<<endl;
else
cout<<"\t";

||ElChE||88
06-05-2009, 11:41
E' l'operatore modulo.

Significa: se x è divisibile per 5 (o meglio: se il resto della divisione x / 5 è uguale a 0).

yorkeiser
06-05-2009, 11:43
Quel % è l'operatore di modulo, restituisce il resto della divisione.
Quindi: se il resto della divisione di x / 5 è uguale a 0 (ovvero, se x è divisibile per 5) stampa endl.

EDIT: doppio :)

Bandit
06-05-2009, 13:24
e cosa c'entra con questa espressione "Devo visualizzare 5 interi per linea"?

||ElChE||88
06-05-2009, 13:43
e cosa c'entra con questa espressione "Devo visualizzare 5 interi per linea"?
Ogni 5 interi ce n'è uno divisibile per 5.
Quindi ogni 5 interi il programma andrà a nuova riga.

Bandit
06-05-2009, 13:54
Ogni 5 interi ce n'è uno divisibile per 5.
Quindi ogni 5 interi il programma andrà a nuova riga.

a ecco :D
grazie ;)

si fanno anche questo itpo di ragionamento? mi devo abituare allora...

banryu79
06-05-2009, 14:09
si fanno anche questo itpo di ragionamento? mi devo abituare allora...

Tieni presente che programmazione, logica booleana e matematica sono praticamente amanti tra di loro.

Bandit
06-05-2009, 14:19
ok, cercherò...

Bandit
12-05-2009, 10:36
ragazzi mi aiutate a capire le due funzioni che mi permettono di visualizzare l'orario in tempo universale-militare (18:30) e quello in tempo standard(6:30 PM)?

queste sono le funzioni

void stampamilitare (const Tempo &t)

void stampastandard (const Tempo &t)


questo è il programma dove creo un tipo Tempo , do dei valori ai membrei della struct tipo Tempo e cerco di visualizzarli

//Crea struttura ,imposto i membri e li visualizzo

#include <iostream>
using namespace std;

struct Tempo {
int ora;
int minuto;
int secondo;
};

void stampamilitare (const Tempo &);
void stampastandard (const Tempo &);

int main()
{
Tempo cenaTempo; //variabile del nuovo tipo Tempo

//ora inizializzo i membri con valori validi
cenaTempo.ora=18;
cenaTempo.minuto=30;
cenaTempo.secondo=0;

cout<<"cena sarà servita alle:";
stampamilitare(cenaTempo);

cout<<" tempo militare,\n che è :";
stampastandard(cenaTempo);
cout<<"in tempo standard.\n";

return 0;

}

//funzione stampa militare e stampa standard

void stampamilitare (const Tempo &t)
{
//da qui
cout<<(t.ora<10 ? "0" : "")<<t.ora<< ":"
<<(t.minuto<10 ? "0" : "")<<t.minuto;

//a qui

}

void stampastandard (const Tempo &t)
{

//da qui
cout<<((t.ora==0 ||t.ora==12)?
12 : t.ora %12)
<<":"<<(t.minuto<10 ? "0":"")<<t.minuto
<<":"<<(t.secondo<10 ? "0":"")<<t.secondo
<<(t.ora<12?" AM ":" PM ");

//a qui
}


perchè per visualizzare il il tempo scrivo in questo modo i due corpi della funzione, che cosa vuol dire?

||ElChE||88
12-05-2009, 10:58
perchè per visualizzare il il tempo scrivo in questo modo i due corpi della funzione che cosa vuol dire?
Non ho capito bene che cosa non ti è chiaro...

Bandit
12-05-2009, 11:03
ho messo i commenti in rosso dove non ho capito

||ElChE||88
12-05-2009, 11:08
void stampamilitare (const Tempo &t)
{
//da qui
cout<<(t.ora<10 ? "0" : "")<<t.ora<< ":"
<<(t.minuto<10 ? "0" : "")<<t.minuto;

//a qui

}
In questa funzione fa uso dell'operatore ternario.
(condizione ? #true : #false)
Praticamente se la condizione è vera viene eseguito il codice #true, se la condizione è falsa quello #false.
In questo caso se l'ora e i minuti sono inferiori a 10 (e quindi hanno una singola cifra) ci aggiunge uno 0 davanti. Se i numeri sono a due cifre invece ci aggiunge una stringa vuota, non cambiando niente.

void stampastandard (const Tempo &t)
{

//da qui
cout<<((t.ora==0 ||t.ora==12)?
12 : t.ora %12)
<<":"<<(t.minuto<10 ? "0":"")<<t.minuto
<<":"<<(t.secondo<10 ? "0":"")<<t.secondo
<<(t.ora<12?" AM ":" PM ");

//a qui
}
((t.ora==0 ||t.ora==12) ? 12 : t.ora %12)
controlla se l'ora è 0 o 12 e in quel caso ritorna 12, altrimenti ritorna ora % 12 (praticamente trasforma le ore 13-23 in 1-11).

goldorak
12-05-2009, 11:10
Cosa non ti e' chiaro ? Il modo in cui l'ora viene stampata ?

Se usi lo standard militare, devi mettere uno 0 davanti ogni cifra (sia per l'ora che per i minuti) se questi non hanno gia' una prima prima cifra diversa da 0.
Quindi 1 viene scritto 01, 2 viene scritto 02, 13 viene scritto 13 e non 013 perche' ce' gia' un 1 che precede il 3. Idem se scrivi 23:56, se scrivi 7:6 allora
verra' trasformato in 07:06.

Se usi lo standard civile invece l'ora va scritta in formato xx:yy:AM/PM con xx compreso tra 0 e 12 (ore), yy sono i minuti e AM o PM distinguono se le ore si riferiscono al mattino o al pomeriggio.
Quindi le 2:05 AM non sono uguali alle 2:05 PM.

Bandit
12-05-2009, 11:17
grazie della spiegazione :)
però è possibile scendere in dettaglio?

In questa funzione fa uso dell'operatore ternario.
(condizione ? #true : #false)
Praticamente se la condizione è vera viene eseguito il codice #true, se la condizione è falsa quello #false.
In questo caso se l'ora e i minuti sono inferiori a 10 (e quindi hanno una singola cifra) ci aggiunge uno 0 davanti. Se i numeri sono a due cifre invece ci aggiunge una stringa vuota, non cambiando niente.

t.ora<10 ? "0" : ""
se l'ora è <10, allora aggiungi un o 0 davanti, il "?" cosa indica?aggiungi?


Andando oltre
se qui consideriamo altrimenti


((t.ora==0 ||t.ora==12) ? 12 : t.ora %12)
controlla se l'ora è 0 o 12 e in quel caso ritorna 12, altrimenti ritorna ora % 12 (praticamente trasforma le ore 13-23 in 1-11).

((t.ora==0 ||t.ora==12) ? 12 : t.ora %12)
perchè invece del : non c'è ||?

||ElChE||88
12-05-2009, 11:23
grazie della spiegazione :)
però è possibile scendere in dettaglio?



t.ora<10 ? "0" : ""
se l'ora è <10, allora aggiungi un o 0 davanti, il "?" cosa indica?aggiungi?


Andando oltre
se qui consideriamo altrimenti


((t.ora==0 ||t.ora==12) ? 12 : t.ora %12)
perchè invece del : non c'è ||?
La risposta ad entrambe le domande è nel mio post sopra: si tratta dell'operatore ternario.
(condizione ? #true : #false)
Praticamente se la condizione è vera viene eseguito il codice #true, se la condizione è falsa quello #false.

goldorak
12-05-2009, 11:24
L'operatore ternario "? :" funziona cosi'

espressione1 ? espressione2 : espressione3.

Viene valutata l'espressione1, se e' vera viene restituito il valore dell'espressione 2, se invece espressione1 e' falsa viene restituito il valore dell'espressione3.

E un modo alternativo di scrivere una istruzione if then else. Ad ogni modo non sono totalmente equivalenti, perche' l'if-then-else e' una istruzione mentre ? : e' un espressione e puo' essere utilizzata in posti dove non potrebbe essere usata l'istruzione if-then-else.

Bandit
12-05-2009, 11:26
quindi ? e :
così scritti possono poter essere covisti come una specie di if (?) e else (:)

Bandit
12-05-2009, 11:27
L'operatore ternario "? :" funziona cosi'

espressione1 ? espressione2 : espressione3.

Viene valutata l'espressione1, se e' vera viene restituito il valore dell'espressione 2, se invece espressione1 e' falsa viene restituito il valore dell'espressione3.

E un modo alternativo di scrivere una istruzione if then else. Ad ogni modo non sono totalmente equivalenti, perche' l'if-then-else e' una istruzione mentre ? : e' un espressione e puo' essere utilizzata in posti dove non potrebbe essere usata l'istruzione if-then-else.

ok grazie mille chiarissimo ;)
abbiam orisposto in contemporanea


p.s. grazie a tutti, ma mi sto ambientando piano piano a questo c++

goldorak
12-05-2009, 11:38
ok grazie mille chiarissimo ;)
abbiam orisposto in contemporanea


p.s. grazie a tutti, ma mi sto ambientando piano piano a questo c++

Ti faccio un esempio veloce veloce in c (ma si puo' applicare anche a c++)




char cin ;

cin = getchar() // leggi un carattere dallo standard input

if (cin=='a') printf("%c", 'A'); else printf("%c", '\n') ;

....



con l'operatore ? : scriveresti una cosa del genere :



char cin ;

printf ("%c", ( (cin=getchar()) == 'a') ? 'A' : '\n') ;



Come vedi nel secondo esempio si fa a meno dell'istruzione if then else perche' non potresti inserirla nella printf.

Bandit
12-05-2009, 11:53
char cin ;

printf ("%c", ( (cin=getchar()) == 'a') ? 'A' : '\n') ;




ed in quest'ultimo codice
il "%c" viene sempre visualizzato, giusto?
visto che prima sia nell'if che nel else c'era

quindi è un modo di scrivere abbreviato

goldorak
12-05-2009, 11:57
ed in quest'ultimo codice
il "%c" viene sempre visualizzato, giusto?
visto che prima sia nell'if che nel else c'era

quindi è un modo di scrivere abbreviato

il "%c" e' la stringa di controllo (non viene stampato sullo schermo), indica alla funzione printf come devono essere interpretati i parametri che verranno stampati sullo schermo. In questo caso il "%c" indica che il valore di ritorno dell'espressione ? : va trattata come un carattere.

Forse la differenza non ti risulta chiara, ecco un altro piccolo esempio la stampa del numero piu' grande tra 2 numeri.



int a, b ;

if (a>b) printf("%d", a); else printf("%d",b)



Senza usare l'istruzione if then else



int a,b ;

printf("%d", (a>b) ? a : b) ;



I due frammenti di codice fanno la stessa cosa, stampano il numero piu' grande tra a e b. Solo che nel primo esempio usi una istruzione per decidere quale dei due e' piu' grande, nel secondo esempio viene valutata direttamente una espressione che puo' quindi essere impiegata direttamente nella printf.

Bandit
12-05-2009, 12:08
ora l'ho capito l'utilizzo del operatore ternario

non avevo capito che "%c"

indica alla funzione printf come devono essere interpretati i parametri che verranno stampati sullo schermo. In questo caso il "%c" indica che il valore di ritorno dell'espressione ? : va trattata come un carattere.
quindi tra "%c" e "%d" c'è differenza?

||ElChE||88
12-05-2009, 12:10
quindi tra "%c" e "%d" c'è differenza?
Si. %d indica che il parametro deve essere trattato come numero intero.

Bandit
12-05-2009, 12:20
quindi
c carattere
d numero

ok
tutto chiaro ,
tutto nuovo per me , ma tutto chiaro;)

grazie

||ElChE||88
12-05-2009, 12:27
tutto nuovo per me
Se studi il c++ dimentica pure printf e i suoi argomenti. ;)

goldorak
12-05-2009, 12:45
Se studi il c++ dimentica pure printf e i suoi argomenti. ;)

In linea di massima e' cosi', ma il c++ si basa sul c e si porta dietro molti dei suoi difetti. Quindi conoscere in linea di massima il c e' buona cosa, anche se non scrivera' mai una riga di codice c.
E poi il c e' un linguaggio semplice (forse troppo semplice :asd: ) e si impara alla svelta.

||ElChE||88
12-05-2009, 12:51
In linea di massima e' cosi', ma il c++ si basa sul c e si porta dietro molti dei suoi difetti. Quindi conoscere in linea di massima il c e' buona cosa, anche se non scrivera' mai una riga di codice c.
Conoscere si. Utilizzare assolutamente no (a meno di non avere una validissima ragione).

Bandit
14-05-2009, 11:52
ragazzi alla domanda: che differenza passa tra un puntatore a pippo e un riferimento a pippo?

il puntatore contiene l'indirizzo della variabile pippo
int *ptr=&pippo;

o anche separatamente
int *ptr;
ptr=&pippo


il riferimento?
&rif=pippo;
rif è riferimento, e che vuol dire? che l'indirizzo di rif è.....?

goldorak
14-05-2009, 12:20
Un puntatore e' una variabile, un riferimento e' soltanto un alias.

Per riprendere il tuo esempio :


int *ptr;
ptr=&pippo



p e' un puntatore inizializzato con l'indirizzo della variable pippo.
Se poi piu' in la nel codice faccio ptr++, incremento il valore della variable ptr (non il valore di pippo).
Certo incrementando ptr lo faccio puntare da qualche parte in memoria (e se cerco di dereferenziarlo nel 99,99% dei casi ottengo il crash dell'applicazione).

Se invece usi

&rif=pippo;


rif e' un riferimento alla variable pippo, un alias. Laddove usi il nome pippo puoi usare il nome rif. Altresi' se fai rif++ (contriamente al caso ptr dove andavi a incrementare il valore di ptr) in questo caso non fai che incrementare il valore di pippo.



int pippo = 3 ;
int &rif = pippo ;
rif++ // a questo punto pippo vale 4




int *ptr;
int pippo = 3
ptr=&pippo ;
ptr++; //ptr non punta piu' a pippo ma da qualche parte in memoria
// pippo vale sempre 3
*ptr ; //ottengo sicuramente un crash

Bandit
14-05-2009, 12:34
grazie tutto molto chiaro

tranne alcuni punti
(quando si utilizza il termine deferenziare e alias vado in tilt :D )


Se invece usi

&rif=pippo;


rif e' un riferimento alla variable pippo, un alias. Laddove usi il nome pippo puoi usare il nome rif. Altresi' se fai rif++ (contriamente al caso ptr dove andavi a incrementare il valore di ptr) in questo caso non fai che incrementare il valore di pippo.

rif con quel codice li, conterrà l'indirizzo di pippo, giusto? ed in questo caso rif verrà ad essere un alias

goldorak
14-05-2009, 12:42
grazie tutto molto chiaro

tranne alcuni punti
(quando si utilizza il termine deferenziare e alias vado in tilt :D )


rif con quel codice li, conterrà l'indirizzo di pippo, giusto? ed in questo caso rif verrà ad essere un alias


Diciamo che un riferimento non e' altro che un puntatore costante.
Quindi si, rif contiene l'indirizzo di pippo, ma ogni volta che usi rif, il sistema implicitamente deferenzia rif per darti il valore di pippo.
E siccome rif e' un puntatore costante, fare rif++ non cambia il valore di rif, ma quello della variable di cui rif e' riferimento.
Quindi rif++ va inteso (va inteso nel senso che ogni volta che fai rif++ il sistema lo trasforma in) *rif++.

Bandit
14-05-2009, 12:57
Quindi si, rif contiene l'indirizzo di pippo, ma ogni volta che usi rif, il sistema implicitamente deferenzia rif per darti il valore di pippo.


se puoi mi potresti fare un esempio semplice della frase in grassetto

goldorak
14-05-2009, 13:03
se puoi mi potresti fare un esempio semplice della frase in grassetto


Dunque quello che devi capire e' come viene implementato il concetto di riferimento in c++.

Quando scrivi


int pippo=4;
int &rif = pippo ;


Quello che succede dietro le quinte e' che rif e' un puntatore, ma un puntatore costante. Questo vuol dire che il suo valore (il valore di rif, quello che tecnicamente si chiama right-value) non si puo' modificare e viene inizializzato nel momento in cui esegui l'istruzione int &rif = pippo.
Il sistema fa in modo che ogni volta che tu scrivi rif, oppure rif++ oppure rif-- etc... questo viene trasformato in rispettivamente (*rif) oppure (*rif)++ oppure (*rif)--. Il che fa senso poiche' rif dal punto di vista del sistema non e' altro che un puntatore (un puntatore costante) e quindi per accedere al valore di pippo devi(1) deferenziare rif.

(1) il devi qui e' fatto dal sistema, non dall'utente.

Bandit
14-05-2009, 13:14
quindi con la parola deferenziare intendiamo ciò che il c++ fa lui solo, quindi mai nessuno mi potrà dire "dererenzia questo e quello"
il problema più che altro è capire con alias (che ora ho capito) e con la parola deferenziare cosa si intende

goldorak
14-05-2009, 13:21
quindi con la parola deferenziare intendiamo ciò che il c++ fa lui solo, quindi mai nessuno mi potrà dire "dererenzia questo e quello"
il problema più che altro è capire con alias (che ora ho capito) e con la parola deferenziare cosa si intende


Deferenziare una variable p di tipo puntatore significa accedere al valore della variable il cui indirizzo sta in p.
Chiaramoci su un punto importante, una variable di tipo puntatore si puo' sempre deferenziare, il punto e' che con i riferimenti e' il sistema stesso che dereferenzia in automatico, mentre se tu usassi una variable puntatore normale (non un riferimento) il compito di deferenziare spetterebbe al programmatore.

Bandit
14-05-2009, 13:26
Deferenziare una variable p di tipo puntatore significa accedere al valore della variable il cui indirizzo sta in p.
Chiaramoci su un punto importante, una variable di tipo puntatore si puo' sempre deferenziare, il punto e' che con i riferimenti e' il sistema stesso che dereferenzia in automatico, mentre se tu usassi una variable puntatore normale (non un riferimento) il compito di deferenziare spetterebbe al programmatore.
quindi il p della prima frase è un puntatore

ok credo di aver capito
ora ci ragiono un pò su ma con questo tuo ultimo intervento chiarissimo ,si sono aperte diverse porte mentali :D

grazie

Bandit
23-05-2009, 11:15
ciao a tutti ragazzi
mi dareste una mano per far girare questo programma? da quello che ho capito ci sono tanti diversi programmi che devono collegarsi insieme tra loro, ma non so come?

forse è un problema di eclipsE?

/ricavi.h
//definizione della classe ricavi
//le funzioni membro definite in ricavi.cpp

#ifndef ricavi
#define ricavi

class ricavipersona{
public:
ricavipersona(); //costruttore
void immettiricavi (); //input dei ricavi mensili
void impostaricavi (int,double); //input ricavi di 1 mese

void stamparicaviannuali ();

private:
double totalericaviannuali(); //funzioni di utilità
double ricavi[12]; //i 12 ricavi mensili

};

#endif

#include <iostream>
#include <iomanip>
#include <ricavi>
using namespace std;

//il costruttore inizializza l'array
ricavipersona::ricavipersona()
{
for(int i=0;i<12;i++)
ricavi[i]=0;
}
//per immettere i 12 ricavi mensili
void ricavipersona::immettiricavi()
{
double ricavifigura;
for (int i =0; i<12;i++)
{
cout<<"immetti ricavo per il mese"<<i+1<<";";
cin>>ricavifigura;
impostaricavi(i,ricavifigura);
}
}
//funzione per impostare uno dei 12 ricavi mensili

void ricavipersona::impostaricavi (int mese, double somma)
{

if (mese>=0 && mese<12 && somma>0)
ricavi[mese]=somma;
else
cout<<"mese o ricavifigura scorretto"<<endl;

}

//visualizzoil totale di vendita in un anno

void ricavipersona::stamparicaviannuali()
{cout<<"\n ricavi annuali totali sono: "<<totalericaviannuali()<<endl;
}


//funzione di utilità private per il calcolo del
//totale di vendita

double ricavipersona::totalericaviannuali()
{
double totale=0;
for (int i=0;i<12;i++)
totale + = ricavi[i];
return totale;
}


//mostra funzione di utilità
//da compilare con ricavi.cpp
#include <iostream>
#include "ricavi"

int main ()
{ricavipersona s; //crea oggetto ricavi persona s


s.immettiricavi ();
s.stamparicaviannuali();
return 0;
}







sul libro da cui sto studiano c'è scritto, consulatare la documentazione del vostyro compilatore per sapere come compilare ed effettuare il linking dei programmi composti da più file sorgenti....ma non so da dove cominciare ne cercare