[C] Conversione binario decimale
Ciao a tutti!
Sono alle prese con questo nuovo esercizio di programmazione in C in cui non mi tornano alcune cose. So che in internet ci sono un sacco di esempi già pronti, però ho provato a realizzarne uno io e la conversione non torna
L'utente inserisce le cifre del numero binario (in questo caso fino a 4 cifre). Il programma scambia gli elementi acquisiti ed esegue la conversione utilizzando la funzione
Ho aggiunto la funzione chiamata
Se provo ad eseguire il codice ed inserire la sequenza
Dov'è l'errore?
Grazie mille
Ciaoo!
Sono alle prese con questo nuovo esercizio di programmazione in C in cui non mi tornano alcune cose. So che in internet ci sono un sacco di esempi già pronti, però ho provato a realizzarne uno io e la conversione non torna

#include <stdio.h> #include <math.h> void scambia(int *); int main() { int binario[4], i, conv=0, pot=0, nuovo[4]; int *pi; pi = binario; printf("Inserisci i singoli numeri del codice binario uno per volta:\n"); // L'utente inserisce i singoli numeri del suo codice binario for (i=0;i<4;i++) { printf("==> "); scanf("%d", &binario[i]); // Se i numeri immessi sono diversi da 0 e 1 allora deve inserire nuovamente il numero if (binario[i]!=0 && binario[i]!=1) { i--; } } // Scambio gli elementi del vettore per riuscire a convertire correttamente il numero scambia(pi); for (i=0;i<4;i++) { nuovo[i]=binario[i]; } // Funzione di debug per verificare che lo scambio sia stato effettuato correttamente printf("\nNuovo binario inserito:\t"); for (i=0;i<4;i++) { printf("%d", nuovo[i]); } // Eseguo la conversione utilizzando la funzione pow del file <math.h> for (i=0;i<4;i++) { if (binario[i]==1) { pot = pow (2,i); conv=conv+pot; } } // Stampo il numero convertito in decimale printf("\nEcco il numero converito: %d", conv); return 0; } // Dichiaro la funzione scambio void scambia(int *p) { int temp; int i; for (i=0;i<4;i++) { temp = p[0+i]; p[i] = p[3-i]; p[3-i] = temp; } }
L'utente inserisce le cifre del numero binario (in questo caso fino a 4 cifre). Il programma scambia gli elementi acquisiti ed esegue la conversione utilizzando la funzione
pow(x,y)della libreria
math.h
Ho aggiunto la funzione chiamata
scambiaperchè altrimenti se l'utente inserisce:
1100al posto di avere 12 ottiene 3, a causa dell'ordine dei numeri nel vettore.
Se provo ad eseguire il codice ed inserire la sequenza
1100ottengo sempre 3 al posto di 12.
Dov'è l'errore?

Grazie mille
Ciaoo!
Risposte
Se inserisci 1100 non risulta 12 ma 3 (cioè 0011)
Se inserisci 1000 non risulta 8 ma 1 (cioè 0001)
Se inserisci 0010 non risulta 2 ma 4 (cioè 0100)
Il motivo è che non hai scambiato nulla.
L'errore e' qui;
Devi scrivere i<2 e non i<4 altrimenti fai lo scambio due volte ed è come se non avessi scambiato nulla.
Se inserisci 1000 non risulta 8 ma 1 (cioè 0001)
Se inserisci 0010 non risulta 2 ma 4 (cioè 0100)
Il motivo è che non hai scambiato nulla.
L'errore e' qui;
"floppyes":
for (i=0;i<4;i++)
Devi scrivere i<2 e non i<4 altrimenti fai lo scambio due volte ed è come se non avessi scambiato nulla.
Ciao Atem!
Grazie mille.. in effetti non ci avevo pensato!!
Altra domanda
Mettiamo il caso che sia l'utente a decidere quanto è lungo il vettore, in quel caso allora modifico il codice in questo modo:
Tutto funziona bene tranne il pezzo del void, perchè non tiene in memoria la dimensione dim acquisita all'interno del
Sai se esiste un modo per mantenere in memoria la dimensione dim anche nel void? Così da fare lo scambio all'interno del vettore e convertire poi il numero.
Grazie
Ciao
Grazie mille.. in effetti non ci avevo pensato!!
Altra domanda

Mettiamo il caso che sia l'utente a decidere quanto è lungo il vettore, in quel caso allora modifico il codice in questo modo:
#include <stdio.h> #include <math.h> void scambia(int *); int main() { int dim; printf("Quanto è lungo il tuo codice binario? "); scanf("%d", &dim); int binario[dim], i, conv=0, pot=0, nuovo[dim]; int *pi; pi = binario; printf("Inserisci i singoli numeri del codice binario uno per volta:\n"); // L'utente inserisce i singoli numeri del suo codice binario for (i=0;i<dim;i++) { printf("==> "); scanf("%d", &binario[i]); // Se i numeri immessi sono diversi da 0 e 1 allora deve inserire nuovamente il numero if (binario[i]!=0 && binario[i]!=1) { i--; } } // Scambio gli elementi del vettore per riuscire a convertire correttamente il numero scambia(pi); for (i=0;i<dim;i++) { nuovo[i]=binario[i]; } // Funzione di debug per verificare che lo scambio sia stato effettuato correttamente printf("\nNuovo binario inserito:\t"); for (i=0;i<dim;i++) { printf("%d", nuovo[i]); } // Eseguo la conversione utilizzando la funzione pow del file <math.h> for (i=0;i<dim;i++) { if (binario[i]==1) { pot = pow (2,i); conv=conv+pot; } } // Stampo il numero convertito in decimale printf("\nEcco il numero converito: %d", conv); return 0; } // Dichiaro la funzione scambio void scambia(int *p) { int temp; int i; for (i=0;i<(dim/2);i++) { temp = p[0+i]; p[i] = p[(dim-1)-i]; p[(dim-1)-i] = temp; } }
Tutto funziona bene tranne il pezzo del void, perchè non tiene in memoria la dimensione dim acquisita all'interno del
int main ()
Sai se esiste un modo per mantenere in memoria la dimensione dim anche nel void? Così da fare lo scambio all'interno del vettore e convertire poi il numero.
Grazie
Ciao

dim è un parametro che devi passare alla procedura.
scambia(pi);
diventa
scambia(pi, dim);
E poi la funzione e'
void scambia(int *p, int dim)
Ovviamente devi modificare anche il prototipo.
scambia(pi);
diventa
scambia(pi, dim);
E poi la funzione e'
void scambia(int *p, int dim)
Ovviamente devi modificare anche il prototipo.
Grazie mille ora funziona alla perfezione!! 
Devo ricordarmi allora di utilizzare questo metodo per richiamare le variabili anche nelle altre funzioni!
Grazie mille per l'aiuto
Ciaoo

Devo ricordarmi allora di utilizzare questo metodo per richiamare le variabili anche nelle altre funzioni!
Grazie mille per l'aiuto
Ciaoo

Ciao!
Una sola domanda. Nel caso in cui la sequenza di numeri inserita sia in complemento a due, allora dovrò scambiare tutti i numeri del vettore, se 0 mettere 1 e se 1 mettere 0, e poi sottrarre 1 al nuovo vettore?
Grazie
Ciaoo
Una sola domanda. Nel caso in cui la sequenza di numeri inserita sia in complemento a due, allora dovrò scambiare tutti i numeri del vettore, se 0 mettere 1 e se 1 mettere 0, e poi sottrarre 1 al nuovo vettore?
Grazie
Ciaoo

Se il primo bit è uno 0 allora il numero è positivo e non devi fare niente.
Se il primo bit è un 1 allora il numero è negativo.
In questo caso prima devi sottarre uno, e poi complementare tutti i bit in modo da ottenere il corrispondente numero positivo.
Oppure (sempre che il primo bit sia 1) puoi fare come c'è scritto su Wikipedia e cioè prima complementi tutti i bit e poi sommi 1:
http://it.wikipedia.org/wiki/Complement ... ento_a_due
Se il primo bit è un 1 allora il numero è negativo.
In questo caso prima devi sottarre uno, e poi complementare tutti i bit in modo da ottenere il corrispondente numero positivo.
Oppure (sempre che il primo bit sia 1) puoi fare come c'è scritto su Wikipedia e cioè prima complementi tutti i bit e poi sommi 1:
http://it.wikipedia.org/wiki/Complement ... ento_a_due
Ciao!
Perfetto grazie mille, ora finisco l'altro esercizio e poi completo questo
perchè la richiesta era proprio in complemento a due!
Grazie
Ciaoo
Perfetto grazie mille, ora finisco l'altro esercizio e poi completo questo

Grazie
Ciaoo

Ciao!
Ho provato a riscrivere il codice:
Nel mio esercizio viene chiesto di immettere il seguente numero di 16bit:
Il risultato è di -4339, mentre a me esce -4338.
Secondo te il codice è giusto? Perchè mi sa che il passaggio in cui vado a sommare 1 non è molto corretto
Grazie mille
Ciaoo!
Ho provato a riscrivere il codice:
/* Programma che serve a convertire un numero binario in decimale. L'utente inserisce la lunghezza del numero e poi ogni singola cifra. Tema esame di Guida. */ #include <stdio.h> #include <math.h> void scambia(int *p, int dim); int main() { int dim; // Qui definisco quanto è lungo il mio codice printf("Quanto è lungo il tuo codice binario? "); scanf("%d", &dim); int binario[dim], i, conv=0, pot=0, nuovo[dim]; // Questo mi serve per scambiare i numeri del vettore in modo da convertirlo giusto int *pi; pi = binario; printf("Inserisci i singoli numeri del codice binario uno per volta:\n"); // L'utente inserisce i singoli numeri del suo codice binario for (i=0;i<dim;i++) { printf("==> "); scanf("%d", &binario[i]); // Se i numeri immessi sono diversi da 0 e 1 allora deve inserire nuovamente il numero if (binario[i]!=0 && binario[i]!=1) { i--; } } // Scambio gli elementi del vettore per riuscire a convertire correttamente il numero if (binario[0]==1) { printf("\nComplemento a due:\n"); for (i=0;i<dim;i++) { if (binario[i]==1) { binario[i]=0; } else (binario[i]=1); } for (i=0;i<dim;i++) { binario[i]=binario[i]+1; } for (i=0;i<dim;i++) { if (binario[i]==1) { binario[i]=0; } else (binario[i]=1); } for (i=0;i<dim;i++) { printf("%d", binario[i]); } } scambia(pi,dim); for (i=0;i<dim;i++) { nuovo[i]=binario[i]; } for (i=0;i<dim;i++) { if (binario[i]==1) { pot = pow (2,i); conv=conv+pot; } } if (binario[0]==0) { printf("\n\nIl numero in decimale equivale a : -%d", conv); } else (printf("\n\nIl numero in decimale equivale a : %d", conv)); return 0; } // Dichiaro la funzione scambio che mi serve per fare in modo che il vettore sia nella posizione giusta void scambia(int *p, int dim) { int temp; int i; for (i=0;i<(dim/2);i++) { temp = p[0+i]; p[i] = p[(dim-1)-i]; p[(dim-1)-i] = temp; } }
Nel mio esercizio viene chiesto di immettere il seguente numero di 16bit:
1110111100001101
Il risultato è di -4339, mentre a me esce -4338.
Secondo te il codice è giusto? Perchè mi sa che il passaggio in cui vado a sommare 1 non è molto corretto

Grazie mille
Ciaoo!
Io crerei 3 funzioni
1-scambia (l'hai già fatta)
2-complementa (l'hai scritta nel MAIN, ma sarebbe più elegante avere una procedura/funzione apposta)
3-converti (idem)
Poi nel MAIN farei così:
1.Inserisci il numero.
2.usa la funzione scambia.
3.
4.Visualizza il numero decimale ottenuto.
1-scambia (l'hai già fatta)
2-complementa (l'hai scritta nel MAIN, ma sarebbe più elegante avere una procedura/funzione apposta)
3-converti (idem)
Poi nel MAIN farei così:
1.Inserisci il numero.
2.usa la funzione scambia.
3.
Se binario[dim-1]==0 //(cioè se il numero è positivo) a.converti Altrimenti: //(cioè se il numero è negativo) a.complementa b.converti c.Al numero decimale ottenuto, somma 1
4.Visualizza il numero decimale ottenuto.
Ciao!
Grazie mille ora provo a riscrivere il codice come mi hai suggerito. Solo una domanda, quando vado ad aggiungere 1, come posso fare per calcolare ed aggiungere i riporti?
Ad esempio, se immetto il numero:
Lo complemento:
Aggiungo 1:
Nel terzo passaggio come posso fare per tenere conto del riporto?
Grazie mille
Ciaoo
Grazie mille ora provo a riscrivere il codice come mi hai suggerito. Solo una domanda, quando vado ad aggiungere 1, come posso fare per calcolare ed aggiungere i riporti?
Ad esempio, se immetto il numero:
0100
Lo complemento:
1011
Aggiungo 1:
1100
Nel terzo passaggio come posso fare per tenere conto del riporto?
Grazie mille
Ciaoo

Se rileggi quello che ho scritto vedrai che non c'è nessun bisogno di tener conto dei riporti...
1 lo sommi al corrispettivo decimale, non c'è bisogno di sommarlo al binario, è solo complicarsi la vita per niente...
1 lo sommi al corrispettivo decimale, non c'è bisogno di sommarlo al binario, è solo complicarsi la vita per niente...
Ciao Antem!
Ammetto che le funzioni non le ho ancora capite bene bene
potrebbe andare bene questo codice per quanto riguarda le funzioni?
Perchè ho provato ad inserire un numero ma ho sempre 0 come risultato finale.
Grazie mille
Ciaoo!
Ammetto che le funzioni non le ho ancora capite bene bene

Perchè ho provato ad inserire un numero ma ho sempre 0 come risultato finale.
#include <stdio.h> #include <math.h> void scambia(int *p, int dim); void complementa(int*comp, int dim, int binario[dim]); void converti(int*conve, int dim, int binario[dim], int pot, int conv); int main() { int dim; printf("Quanto è lungo il tuo codice binario? "); scanf("%d", &dim); int binario[dim], i, conv=0, pot=0, nuovo[dim]; // Richiami alle funzioni void int *pi; pi = binario; int *comp; comp = binario; int *conve; conve = binario; printf("Inserisci i singoli numeri del codice binario uno per volta:\n"); // L'utente inserisce i singoli numeri del suo codice binario for (i=0;i<dim;i++) { printf("==> "); scanf("%d", &binario[i]); // Se i numeri immessi sono diversi da 0 e 1 allora deve inserire nuovamente il numero if (binario[i]!=0 && binario[i]!=1) { i--; } } // Scambio gli elementi del vettore per riuscire a convertire correttamente il numero if (binario[dim-1]==0) { converti (conve,dim,&binario[dim],pot,conv); } printf("Numero convertito: %d", conv); if (binario[dim-1]!=0) { complementa (comp,dim,&binario[dim]); converti (conve,dim,&binario[dim],pot,conv); conv+=1; } printf("Numero convertito: %d\n", conv); return 0; } // Elenco tutte le funzioni di cui ho bisogno // Funzione scambia void scambia(int *p, int dim) { int temp; int i; for (i=0;i<(dim/2);i++) { temp = p[0+i]; p[i] = p[(dim-1)-i]; p[(dim-1)-i] = temp; } } // Funzione complementa void complementa(int*comp, int dim, int binario[dim]) { int i; for (i=0;i<dim;i++) { if (binario[i]==1) { binario[i]=0; } else (binario[i]=1); } } // Funzione converti void converti(int*conve, int dim, int binario[dim], int pot, int conv) { int i; for (i=0;i<dim;i++) { if (binario[i]==1) { pot = pow (2,i); conv=conv+pot; } } }
Grazie mille
Ciaoo!
Alle funzioni/procedure devi passare solamente i parametri necessari.
Ad esempio, le tue 3 funzioni hanno bisogno di ricevere dal MAIN solamente 2 parametri: il vettore, e la dimensione del vettore. Il resto puoi dichiararlo internamente visto che sono cose che non ti servono nelle future istruzioni del MAIN.
Nel MAIN devi mettere solo le cose che servono, e così vale anche per le funzioni.
Te l'ho corretto:
Inoltre il risultato finale va visualizzato dopo l'IF altrimenti visualizzi due cose e non una.
Comunque guarda quello che ti ho corretto, riflettici bene, e poi se c'è qualcosa che non hai capito, chiedi.
Ad esempio, le tue 3 funzioni hanno bisogno di ricevere dal MAIN solamente 2 parametri: il vettore, e la dimensione del vettore. Il resto puoi dichiararlo internamente visto che sono cose che non ti servono nelle future istruzioni del MAIN.
Nel MAIN devi mettere solo le cose che servono, e così vale anche per le funzioni.
Te l'ho corretto:
#include <stdio.h> #include <math.h> void scambia(int *p, int dim); void complementa(int binario[], int dim); int converti(int binario[], int dim); int main() { int dim; printf("Quanto è lungo il tuo codice binario? "); scanf("%d", &dim); int binario[dim], i, conv; printf("Inserisci i singoli numeri del codice binario uno per volta:\n"); // L'utente inserisce i singoli numeri del suo codice binario for (i=0;i<dim;i++) { printf("==> "); scanf("%d", &binario[i]); // Se i numeri immessi sono diversi da 0 e 1 allora deve inserire nuovamente il numero if (binario[i]!=0 && binario[i]!=1) { i--; } } scambia(binario, dim); // Scambio gli elementi del vettore per riuscire a convertire correttamente il numero if (binario[dim-1]==0) { conv=converti (binario, dim); } else { complementa (binario, dim); conv=converti (binario, dim); conv+=1; conv*=-1; } printf("Numero convertito: %d\n", conv); return 0; } // Elenco tutte le funzioni di cui ho bisogno // Funzione scambia void scambia(int *p, int dim) { int temp; int i; for (i=0;i<(dim/2);i++) { temp = p[i]; p[i] = p[(dim-1)-i]; p[(dim-1)-i] = temp; } } // Funzione complementa void complementa(int binario[], int dim) { int i; for (i=0;i<dim;i++) { if (binario[i]==1) { binario[i]=0; } else (binario[i]=1); } } // Funzione converti int converti(int binario[], int dim) { int pot; int conv=0; int i; for (i=0;i<dim;i++) { if (binario[i]==1) { pot = pow (2,i); conv=conv+pot; } } return conv; }
Inoltre il risultato finale va visualizzato dopo l'IF altrimenti visualizzi due cose e non una.
Comunque guarda quello che ti ho corretto, riflettici bene, e poi se c'è qualcosa che non hai capito, chiedi.
Solo un piccolo commento:
In questo estratto del tuo codice
Questo opzione degli ultimi due standard del C non sono supportati da tutti i compilatori e il loro uso è spesso criticato. Detto questo, in questo programma, dato la dimensione limitata di dim, l'uso dei VLA è considerato accettabile e talvolta anche consigliato. Sinceramente trovo però che il suo uso vada fatto sempre consapevolmente. Il suo uso sconsiderato è infatti sempre da evitare.
Ho notato che Atem non l'ha corretto nel suo codice. Le alternative sono o l'allocazione dinamica o una dimensione fissa prefissata. Considerando il tipo di problema direi che l'uso di una dimensione fissa (di 32 o 64) sia accettabile.
--------------------------
Una cosa un po' più grave consiste nell'uso di int senza fare alcun controllo sul fatto o meno che un int possa contenere l'array di bit considerato. Un codice più ragionato userebbe la libreria stdint.h (o inttypes.h se hai bisogno di usare le macro per printf) introdotta negli ultimi standard o, alternativamente, controlli i limiti attraverso la libreria limits.h
-------------------------
Sarebbe infine secondo me più sensato caricare i bit come stringa di caratteri e interpretarla. Così sei invece costretto a dividere le varie cifre.
In questo estratto del tuo codice
int dim; // Qui definisco quanto è lungo il mio codice printf("Quanto è lungo il tuo codice binario? "); scanf("%d", &dim); int binario[dim], i, conv=0, pot=0, nuovo[dim]; [...]stai volutamente usando i variable lenght array del c99-c11 oppure stai dando per scontato che il tuo codice usi le estensioni del c90 di gcc?
Questo opzione degli ultimi due standard del C non sono supportati da tutti i compilatori e il loro uso è spesso criticato. Detto questo, in questo programma, dato la dimensione limitata di dim, l'uso dei VLA è considerato accettabile e talvolta anche consigliato. Sinceramente trovo però che il suo uso vada fatto sempre consapevolmente. Il suo uso sconsiderato è infatti sempre da evitare.
Ho notato che Atem non l'ha corretto nel suo codice. Le alternative sono o l'allocazione dinamica o una dimensione fissa prefissata. Considerando il tipo di problema direi che l'uso di una dimensione fissa (di 32 o 64) sia accettabile.
--------------------------
Una cosa un po' più grave consiste nell'uso di int senza fare alcun controllo sul fatto o meno che un int possa contenere l'array di bit considerato. Un codice più ragionato userebbe la libreria stdint.h (o inttypes.h se hai bisogno di usare le macro per printf) introdotta negli ultimi standard o, alternativamente, controlli i limiti attraverso la libreria limits.h
-------------------------
Sarebbe infine secondo me più sensato caricare i bit come stringa di caratteri e interpretarla. Così sei invece costretto a dividere le varie cifre.
"Atem":
Alle funzioni/procedure devi passare solamente i parametri necessari.
Ad esempio, le tue 3 funzioni hanno bisogno di ricevere dal MAIN solamente 2 parametri: il vettore, e la dimensione del vettore. Il resto puoi dichiararlo internamente visto che sono cose che non ti servono nelle future istruzioni del MAIN.
Nel MAIN devi mettere solo le cose che servono, e così vale anche per le funzioni.
Te l'ho corretto:
Inoltre il risultato finale va visualizzato dopo l'IF altrimenti visualizzi due cose e non una.
Comunque guarda quello che ti ho corretto, riflettici bene, e poi se c'è qualcosa che non hai capito, chiedi.
Ciao Atem!
Grazie per la risposta! Ora confrontando il tuo codice con la teoria sulle funzioni mi è già più chiaro

Solo due domande sul codice che hai scritto:
Nelle prime righe
void complementa(int binario[], int dim); int converti(int binario[], int dim);
non bisognerebbe dichiarare la dimensione del vettore binario? oppure posso lasciarla anche "vuota"?
Alla riga 37 poi non ho capito questo passaggio:
else { complementa (binario, dim); conv=converti (binario, dim); conv+=1; conv*=-1; }
Che funzione ha il
conv*=-1;?
Infine come mai nella funzione converti hai utilizzato
int converti(int binario[], int dim)
Al posto della funzione void? Inoltre il return va inserito solamente nella dichiarazione dell'int?
Grazie mille come sempre per l'ottimo aiuto!

"vict85":
Solo un piccolo commento:
In questo estratto del tuo codiceint dim; // Qui definisco quanto è lungo il mio codice printf("Quanto è lungo il tuo codice binario? "); scanf("%d", &dim); int binario[dim], i, conv=0, pot=0, nuovo[dim]; [...]stai volutamente usando i variable lenght array del c99-c11 oppure stai dando per scontato che il tuo codice usi le estensioni del c90 di gcc?
Questo opzione degli ultimi due standard del C non sono supportati da tutti i compilatori e il loro uso è spesso criticato. Detto questo, in questo programma, dato la dimensione limitata di dim, l'uso dei VLA è considerato accettabile e talvolta anche consigliato. Sinceramente trovo però che il suo uso vada fatto sempre consapevolmente. Il suo uso sconsiderato è infatti sempre da evitare.
Ho notato che Atem non l'ha corretto nel suo codice. Le alternative sono o l'allocazione dinamica o una dimensione fissa prefissata. Considerando il tipo di problema direi che l'uso di una dimensione fissa (di 32 o 64) sia accettabile.
--------------------------
Una cosa un po' più grave consiste nell'uso di int senza fare alcun controllo sul fatto o meno che un int possa contenere l'array di bit considerato. Un codice più ragionato userebbe la libreria stdint.h (o inttypes.h se hai bisogno di usare le macro per printf) introdotta negli ultimi standard o, alternativamente, controlli i limiti attraverso la libreria limits.h
-------------------------
Sarebbe infine secondo me più sensato caricare i bit come stringa di caratteri e interpretarla. Così sei invece costretto a dividere le varie cifre.
Ad essere sincero lo sto utilizzando inconsapevolmente

#define dim1 2
Quindi per evitare problemi sarebbe meglio utilizzare l'allocazione dinamica? In questo caso il codice che ho riscritto ora potrebbe andare bene?
#include <stdio.h> #include <math.h> #include <stdlib.h> void scambia(int *p, int dim); void complementa(int binario[], int dim); int converti(int binario[], int dim); int main() { int dim; printf("Quanto è lungo il tuo codice binario? "); scanf("%d", &dim); int *binario = malloc(dim*sizeof(int*)); int i, conv; printf("Inserisci i singoli numeri del codice binario uno per volta:\n"); // L'utente inserisce i singoli numeri del suo codice binario for (i=0;i<dim;i++) { printf("==> "); scanf("%d", &binario[i]); // Se i numeri immessi sono diversi da 0 e 1 allora deve inserire nuovamente il numero if (binario[i]!=0 && binario[i]!=1) { i--; } } scambia(binario, dim); // Scambio gli elementi del vettore per riuscire a convertire correttamente il numero if (binario[dim-1]==0) { conv=converti (binario, dim); } else { complementa (binario, dim); conv=converti (binario, dim); conv+=1; conv*=-1; } printf("Numero convertito: %d\n", conv); free(binario); return 0; } // Elenco tutte le funzioni di cui ho bisogno // Funzione scambia void scambia(int *p, int dim) { int temp; int i; for (i=0;i<(dim/2);i++) { temp = p[i]; p[i] = p[(dim-1)-i]; p[(dim-1)-i] = temp; } } // Funzione complementa void complementa(int binario[], int dim) { int i; for (i=0;i<dim;i++) { if (binario[i]==1) { binario[i]=0; } else (binario[i]=1); } } // Funzione converti int converti(int binario[], int dim) { int pot; int conv=0; int i; for (i=0;i<dim;i++) { if (binario[i]==1) { pot = pow (2,i); conv=conv+pot; } } return conv; }
Infine per caricare i bit come stringa di caratteri, devo utilizzare la funzione getchar? Vorrei imparare ad utilizzarla perchè in tutti gli esercizi viene chiesto di immettere stringhe di caratteri.
Grazie anche a te per l'aiuto

Buona serata!
Ciaoo!
"floppyes":
non bisognerebbe dichiarare la dimensione del vettore binario? oppure posso lasciarla anche "vuota"?
In C, quando si passano gli argomenti (variabili) alle funzioni, bisogna prestare attenzione al passaggio di array ad una o più dimensioni; la regola dice che la prima dimensione dell’array può non essere specificata, mentre la seconda e le altre devono esserlo.
http://www.html.it/pag/15409/le-funzioni/
Che funzione ha ilconv*=-1;?
La funzione di conversione ti restituisce il modulo del numero decimale, quindi dato che il primo bit è 1, sappiamo che il nostro numero decimale è negativo, e per trasformare un numero positivo nel suo opposto dobbiamo moltiplicare per -1.
conv=-1 * conv
Infine come mai nella funzione converti hai utilizzato
int converti(int binario[], int dim)
Al posto della funzione void? Inoltre il return va inserito solamente nella dichiarazione dell'int?
Per convenzione chiamiamo "procedure" le funzioni che non restituiscono nessun valore, cioè le funzioni di tipo "void".
Ma le funzioni in senso stretto sono quelle che restituiscono un valore e questo valore puo' essere di qualsiasi tipo:
int, char, float, "nuovo_tipo" (cioè i nuovi_tipi che crei col typedef) etc. etc.
Nel nostro caso la funzione converti doveva trasformare un numero dal binario al decimale quindi chiaramente restituiva un valore per cui l'ho dichiarata "int".
Comunque avrei anche potuto dichiararla "void" e fornire un ulteriore parametro passato per indirizzo....
Quando si raggiunge un’istruzione “return“, il controllo del programma ritorna a chi ha chiamato la funzione. Il valore ritornato è quello posto dopo la parola return;se si chiude la funzione prima di mettere un’istruzione “return“, la funzione ritorna automaticamente, ed il valore ritornato potrebbe non avere un significato valido.
[...]
Una funzione void non deve contenere necessariamente un’istruzione return, anche se essa può essere usata per uscire dalla funzione in maniera opportuna, un po’ come l’uso del “break” all’interno dei cicli.
http://www.html.it/pag/15409/le-funzioni/
In ogni caso ti consiglio di studiare la teoria da qualche guida, risparmi tempo ed impari meglio.
Ehm diciamo che non sono molto bravo a spiegare la teoria perchè fino al... 25 Luglio... non sapevo nulla di C.
Io mi sono letto queste 2 guide:
http://www.html.it/guide/guida-c/
http://blacklight.gotdns.org/guidac.pdf
La prima è molto sintetica e si fa in poche ore, ti spiega tutti i fondamentali del C (uso delle funzioni, liste, files etc..).
La seconda è un pò più approfondita (nel senso che spiega più cose e nel dettaglio, ma è anche più facile rispetto alla prima che è molto stringata) ma è molto molto utile secondo me... (penso che t'interessi fino a pag.146)
Secondo me faresti bene a guardartele, faresti passi da gigante...
Poi, ripeto, entrambe spiegano solo i "fondamentali" infatti, ad esempio, gli alberi non sono spiegati in nessuna delle 2 guide, ma secondo me queste 2 guide sono comunque utili per farsi delle buone fondamenta...
Ciao Atem!
Grazie mille per le guide, il secondo pdf mi sembra ottimo perchè spiega tutte le basi. Ora lo studio per bene e ti faccio sapere
Grazie ancora
Ciaoo!
Grazie mille per le guide, il secondo pdf mi sembra ottimo perchè spiega tutte le basi. Ora lo studio per bene e ti faccio sapere

Grazie ancora
Ciaoo!
Ciao!
Volevo provare a realizzare lo stesso programma però utilizzando la conversione in caratteri come suggerito da vict85, in modo da poter immettere tutti i numeri in un solo colpo.
Per fare questa cosa mi conviene utilizzare la funzione fgets() e utilizzale la funzione realloc in modo da allocare la memoria in base a quanti numeri vengono inseriti?
Grazie
Ciao
Volevo provare a realizzare lo stesso programma però utilizzando la conversione in caratteri come suggerito da vict85, in modo da poter immettere tutti i numeri in un solo colpo.
Per fare questa cosa mi conviene utilizzare la funzione fgets() e utilizzale la funzione realloc in modo da allocare la memoria in base a quanti numeri vengono inseriti?
Grazie
Ciao

Intanto devi avere ben chiaro il motivo per cui vuoi dichiarare la variabile che conterrà il tuo valore binario (es: "1100") di tipo "array di caratteri" piuttosto che di tipo int. E il motivo è che gli interi hanno un limite, quindi se tu dichiarassi la tua variabile di tipo int, ad esempio non potresti convertire "11110101010100101010100" cosa che invece puoi fare dichiarandolo come array di caratteri.
I limiti di ogni tipo li puoi scoprire così:
http://www.tutorialspoint.com/c_standar ... mits_h.htm
Sulle stringhe, dipende da quello che vuoi fare.
char s1[100]; //l'array di caratteri è stato dichiarato staticamente quindi la dimensione massima sarà 100
char *s2; //qui l'allocazione è dinamica e devi usare malloc: la sua dimensione è decisa nel corso del programma tramite, malloc e realloc
Se usi l'allocazione dinamica devi scrivere
Per usare le funzioni delle stringhe (es: strcpy) devi scrivere
La fgets serve per le leggere un numero massimo di caratteri.
es:
fgets(s1,100,stdin) legge al più 100 caratteri e li mette in s1 quindi se tu digiti 120 caratteri ti prende solo i primi 100.
Se usi la fgets devi mettere il limite massimo di caratteri.
Se usi la scanf
scanf ("%s" , s1);
Legge i caratteri digitati fino al primo spazio.
Se vuoi leggere fino all'invio puoi usare
scanf("%[^\n]", s1);
Ma solitamente si usa comunque la fgets() quindi quella scrittura è praticamente inutile.
In questo caso dentro s1 verrà memorizzato anche l'invio. Quindi hai la stringa con "\n" incluso.
Invece diventa utile se vuoi leggere fino a un carattere determinato, ad esempio se vuoi leggere fino a "#" (escluso) è:
scanf("%[^#]", s1);
Invece per l'allocazione dinamica dinamica è sempre il solito procedimento.
Se non conosci dall'inizio la dimensione della stringa, puoi inserire un carattere alla volta usando la realloc.
Ma devi sempre ricordarti di allocare uno spazio in più rispetto alla sua dimensione effettiva perchè bisogna memorizzare anche il carattere di fina stringa. L'inserimento termina quando l'utente ha premuto INVIO. "\n".
In questo modo la stringa occupa proprio lo spazio di memoria necessario.
Non sprechi memoria ma sprechi comunque risorse per niente visto che la "realloc" costa...
Oppure se proprio non ti va di "sprecare" memoria ma non ti va nemmeno di fare questo procedimento.
Potresti fare così
s1 occupa 100 bytes solamente all'interno della funzione, ma quando la funzione termina, s1 viene distrutta e la memoria liberata. Il risultato è che la memoria allocata è esattamente quella necessaria per la stringa, cioè non hai sprecato memoria e non hai nemmeno fatto tutte quelle operazioni di realloc.
In questo esempio ho usato la scanf ("%s", s1) ma ovviamente questo lo usi solamente se vuoi leggere la stringa fino al primo spazio. Altrimenti se vuoi leggere oltre o fino ad un determinato carattere riguarda quello che ho scritto sopra.
Tornando all'esercizio sui numeri binari invece penso che bisogni fare così:
1.Leggi la stringa
2.Controlli che ogni carattere della stringa inserita sia '0' oppure '1'.
Se è così converti, altrimenti lanci un messaggio d'errore.
Per trasformare un char in intero sottrai alla variabile il carattere '0'.
Cioè se tu hai un carattere c=="1" e vuoi che venga trasformato in un intero n==1 devi fare:
n=c-'0';
che equivale a
n=c-48;
Infatti '0' è esattamente la costante 48 in quanto il carattere '0' è rappresentato nel codice ascii dal valore 48.
Se premi alt+48 ti uscirà 0.
Quindi alt+49 è 1 e così via....
In ogni caso ricordarsi i valori a memoria non serve a niente.
Quindi è di gran lunga preferibile usare:
n=c-'0';
I limiti di ogni tipo li puoi scoprire così:
#include <stdio.h> #include <limits.h> int main() { printf("The number of bits in a byte %d\n", CHAR_BIT); printf("The minimum value of SIGNED CHAR = %d\n", SCHAR_MIN); printf("The maximum value of SIGNED CHAR = %d\n", SCHAR_MAX); printf("The maximum value of UNSIGNED CHAR = %d\n", UCHAR_MAX); printf("The minimum value of SHORT INT = %d\n", SHRT_MIN); printf("The maximum value of SHORT INT = %d\n", SHRT_MAX); printf("The minimum value of INT = %d\n", INT_MIN); printf("The maximum value of INT = %d\n", INT_MAX); printf("The minimum value of CHAR = %d\n", CHAR_MIN); printf("The maximum value of CHAR = %d\n", CHAR_MAX); printf("The minimum value of LONG = %ld\n", LONG_MIN); printf("The maximum value of LONG = %ld\n", LONG_MAX); return(0); }
http://www.tutorialspoint.com/c_standar ... mits_h.htm
Sulle stringhe, dipende da quello che vuoi fare.
char s1[100]; //l'array di caratteri è stato dichiarato staticamente quindi la dimensione massima sarà 100
char *s2; //qui l'allocazione è dinamica e devi usare malloc: la sua dimensione è decisa nel corso del programma tramite, malloc e realloc
Se usi l'allocazione dinamica devi scrivere
#include <malloc.h>
Per usare le funzioni delle stringhe (es: strcpy) devi scrivere
#include <string.h>
La fgets serve per le leggere un numero massimo di caratteri.
es:
fgets(s1,100,stdin) legge al più 100 caratteri e li mette in s1 quindi se tu digiti 120 caratteri ti prende solo i primi 100.
Se usi la fgets devi mettere il limite massimo di caratteri.
Se usi la scanf
scanf ("%s" , s1);
Legge i caratteri digitati fino al primo spazio.
Se vuoi leggere fino all'invio puoi usare
scanf("%[^\n]", s1);
Ma solitamente si usa comunque la fgets() quindi quella scrittura è praticamente inutile.
In questo caso dentro s1 verrà memorizzato anche l'invio. Quindi hai la stringa con "\n" incluso.
Invece diventa utile se vuoi leggere fino a un carattere determinato, ad esempio se vuoi leggere fino a "#" (escluso) è:
scanf("%[^#]", s1);
Invece per l'allocazione dinamica dinamica è sempre il solito procedimento.
Se non conosci dall'inizio la dimensione della stringa, puoi inserire un carattere alla volta usando la realloc.
Ma devi sempre ricordarti di allocare uno spazio in più rispetto alla sua dimensione effettiva perchè bisogna memorizzare anche il carattere di fina stringa. L'inserimento termina quando l'utente ha premuto INVIO. "\n".
char *get_string() { char *s=malloc(1); char ch; int dim=0; while ((ch=getchar())!='\n') { ++dim; s=(char*) realloc (s, (dim+1)*(sizeof(char))); *(s+dim-1)=ch; } *(s+dim)=0; //carattere di fine stringa return s; }
In questo modo la stringa occupa proprio lo spazio di memoria necessario.
Non sprechi memoria ma sprechi comunque risorse per niente visto che la "realloc" costa...
Oppure se proprio non ti va di "sprecare" memoria ma non ti va nemmeno di fare questo procedimento.
Potresti fare così
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <malloc.h> char *get_string(); int main() { char *s; printf ("Inserisci la stringa "); s=get_string(); printf ("La stringa e' %s", s); } char *get_string() { char s1[100]; char *s2; scanf ("%s", s1); s2 = malloc (sizeof(strlen(s1))+1); strcpy(s2,s1); return s2; }
s1 occupa 100 bytes solamente all'interno della funzione, ma quando la funzione termina, s1 viene distrutta e la memoria liberata. Il risultato è che la memoria allocata è esattamente quella necessaria per la stringa, cioè non hai sprecato memoria e non hai nemmeno fatto tutte quelle operazioni di realloc.
In questo esempio ho usato la scanf ("%s", s1) ma ovviamente questo lo usi solamente se vuoi leggere la stringa fino al primo spazio. Altrimenti se vuoi leggere oltre o fino ad un determinato carattere riguarda quello che ho scritto sopra.
Tornando all'esercizio sui numeri binari invece penso che bisogni fare così:
1.Leggi la stringa
2.Controlli che ogni carattere della stringa inserita sia '0' oppure '1'.
Se è così converti, altrimenti lanci un messaggio d'errore.
Per trasformare un char in intero sottrai alla variabile il carattere '0'.
Cioè se tu hai un carattere c=="1" e vuoi che venga trasformato in un intero n==1 devi fare:
n=c-'0';
che equivale a
n=c-48;
Infatti '0' è esattamente la costante 48 in quanto il carattere '0' è rappresentato nel codice ascii dal valore 48.
Se premi alt+48 ti uscirà 0.
Quindi alt+49 è 1 e così via....
In ogni caso ricordarsi i valori a memoria non serve a niente.
Quindi è di gran lunga preferibile usare:
n=c-'0';
"Atem":
La fgets serve per le leggere un numero massimo di caratteri.
es:
fgets(s1,100,stdin) legge al più 100 caratteri e li mette in s1 quindi se tu digiti 120 caratteri ti prende solo i primi 100.
Intendo dire che legge "al più" 100 caratteri, ma ovviamente se ne inserisci di meno te li legge comunque tutti fino al '\n' (incluso). Se non vuoi che '\n' sia memorizzato nella stringa devi fare così:
int main() { char nome[30]; printf ("Inserisci il tuo nome e il tuo cognome: "); fgets ( nome, 30, stdin ); nome[strlen(nome)-1] = 0; //prova a commentare questa riga... printf ("Ti chiami %s", nome); printf ("Fine"); }
Se provi a commentare la riga:
nome[strlen(nome)-1] = 0;
ti accorgerai della differenza.
E cioè se commenti quella riga, "Fine" verrà visualizzato una riga di sotto.
Invece se non lo commenti, "fine" verrà visualizzato attaccato al tuo nome, perchè la fgets nella stringa memorizza anche "\n" come ultimo carattere.
La funzione memorizza al più N caratteri, dove l'ultimo è sempre il carattere di fine stringa 0 ('\0').
Se inserisci meno di N-1 caratteri allora il penultimo carattere memorizzato sarà '\n' mentre l'ultimo sarà '\0'.
Se inserisci più di N-1 caratteri, ti salverà tutti i caratteri fino a N-1, gli altri verranno tagliati, e l'N-esimo carattere sarà '\0'.
Dunque tornando al codice di sopra (preso dalla guida di Blacklight) :
"Il comando dato dopo fgets() è necessario perché tale funzione legge anche il carattere '\n', mettendolo alla fine della stringa. Se non si vuole terminare la stringa con un '\n' si piazza il carattere terminatore '\0' al suo posto (ovvero una posizione prima della fine della stringa)."
http://blacklight.gotdns.org/guidac.pdf
Poi dipende, se tu vuoi che venga memorizzato anche '\n' allora non c'è bisogno di quella riga. Dipende solo da quello che vuoi...