programmare in C, primi passi

« Older   Newer »
  Share  
view post Posted on 16/4/2012, 10:44
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


Ciao a tutti, vorrei aprire un 3d che spero interessi a tutti: muovere i primi passi di programmazione con il linguaggio C.

Facciamo un passo indietro. Tempo fa, volevo usare il display grafico unito al pic, per visualizzare grafici e quant'altro, siccome i Glcd, richiedono
un "pilotaggio" un po' più complesso dei classici lcd, mi sono accorto, che per fare cose un po' serie, senza ammattire, mi sarei dovuto appoggiare al C,
con le sue vaste librerie.

Era da tempo in effetti che avevo in mente di studiare questo linguaggio di programmazione, credo sia sempre meglio conoscerne più di uno.
Per ora "conosco" (parola un po' grossa) l'assembler, quello riferito ai microcontrollori, non a un microprocessore di un pc, ma la logica, è più o
meno quella, non si scappa.

Cercando allora in rete per iniziare a programmare in C, mi sono imbattuto in un bel pdf, che mi sono stampato, e a cui sto facendo riferimento, ecco il link:

http://blacklight.gotdns.org/guidac.pdf


Parlando poi, con persone più esperte di me, è saltato fuori che quel pdf, è più adatto alla programmazione del C per un pc, piuttosto che un pic.
O meglio, la logica è sempre la stessa, ma parla anche di cose che un pic, non può gestire, tipo le stringhe e altro ancora che adesso mi sfugge.

Così, ho pensato di mettere un attimo da parte i pic e dedicarmi seriamente allo studio di questo linguaggio, che a detta degli esperti, è molto
potente...diciamo il più a basso livello dei linguaggi ad alto livello.

Forse con altri tipo il Pyton, si possono fare cose molto più velocemente, ma sono troppo evoluti, alla fine (secondo me) fai solo cose già pre-impacchettate da altri...
e a me non va molto. Poi è un linguaggio che ti lega ad avere il software installato sulla macchina, non genere dei .exe, è un linguaggio
interpretato e non compilato...se non dico boiate e ho interpretato giusto quello che fino adesso ho studiato.

Allora dicevo che mi sono scaricato il pdf, e un programma per fare le prove (DEV-c++) anche se io sto usando il c e non il c++.

Sono partito al solito con le prove elementari che si fanno, dichiarazioni di variabili int, float, char ecc.... cicli for, do-while- break ecc...
Giusto per prendere confidenza, e abituarsi anche alla sintassi (che odio con tutte quelle graffe....va bhè).
Direi, che avendo rudimenti di anni fa col basic, tutto sommato, ci siamo, anche se da quanto letto, non c'è paragone tra il basic e il C a livello di potenza.

La cosa che mi sta un pò spiazzando, venendo dall'assembler, è il fatto di dichiarare una variabile, e non sapere dove la mette.. cioè
in assembler farei:

MOVLW 10
MOVWF 0X20

cioè carico 10 in w, e lo metti all'indirizzo 0x20

in c invece farei
int a;
a=10;

oppure
int a=10;

la prima cosa che mi sono chiesto è.....ok a vale 10, ma fisicamente dove lo metti?
Per il momento, ho preso per buona questa cosa, mi sono detto, è così...poi arrivando al capitolo dei puntatori, qualcosa si sta smuovendo, anche se
sui puntatori, credo che ci sia da soffermarsi parecchio...da quello che intravedo, credo che siano uno dei punti di forza del C
la parte più bassa del linguaggio, quello che ti fa lavorare come l'assembler.

Anche la gestione delle CALL abituato con l'assembler, mi spiazza un po' in C...ha dei salti che mi confondono...il prototipo della procedura allìinizio...
l'implementazione della procedura/funzione stessa dopo...insomma mi ci devo abituare.

Per ora, ripeto, sto facendo solo prove, l'unico programmino un po' serio che ho fatto è quello di un input da tastiera che ti calcola se un numero è primo.
L'avevo trovato in rete, e l'ho riscritto da me, perchè quello trovato sul web, secondo me aveva un difetto, non si interrompeva se il numero non era primo
finiva tutti i cicli for...sprecando un sacco di tempo.
Se scrivevo 1234567890 .... che sappiamo già a priori non essere primo, s'inchioda per tot secondi, il mio no...

Comunque, spero che v'interessi questa cosa, magari come in passato, quando avrò dubbi, posterò porzioni di codice...e mi farò sentire quando qualcosa non capisco

Grazie a tutti :)

mò ho finito!!! :D :D :sick:
 
Top
view post Posted on 23/4/2012, 16:33
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


Sto iniziando a fare prove con quel poco di istruzioni che finora ho studiato, ho voluto vedere se riuscivo a fare una routine d'elevamento a potenza,

anche se so che esiste nella libreria Math, sotto il nome di POW mi pare...quindi in un futuro è ovvio che mi appoggerò a quella, non voglio

certo reinventare la ruota (come si usa spesso dire nei manuali).

Non può fare elevamenti con numeri negativi e con la virgola, è ho usato variabili int, quindi devo stare in un certo range, che comunque viene segnalato nel caso
con la scritta OVERFLOW.

Ho usato il caro vecchio GOTO per riprendere il programma dall'inizio, anche se so che in C è sconsigliato ed è meglio un WHILE.
Comunque chi ha voglia gli dia un'occhiata...e magari ditemi....non so consigli, metodi migliori ecc...

Ecco l'allegato


Download attachment
exp.txt ( Number of downloads: 37 )

 
Top
MattiaEM
view post Posted on 23/4/2012, 22:13




Interessante Gila, io ho fatto un pò di C in università ma mi è stato spiegato moolto col c**o!

Io usavo il libro C corso completo di programmazione dei fratelli Deitel.. è molto interessante perchè ha anche esempi con programmi completamente funzionanti di logica (carte, sudoku..)
ho anche delle slide carine ma forse un pò troppo astratte.. (ovviamente se vuoi di quel libro si trova anche il pdf :rolleyes: )

Per il discorso registri e caricamento variabile dai un occhiata al paragrafo dei puntatori di quel libro li che secondo me è molto chiaro!

Io il programma per l'elevazione a potenza l'ho fatto così all'epoca.. (il tuo è più completo, il mio non tratta i casi particolari e non si ripete, quando ha calcolato una volta esce dal programma)



Download attachment
Potenza.txt ( Number of downloads: 25 )

 
Top
view post Posted on 24/4/2012, 16:43
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


CITAZIONE
Interessante Gila

Grazie...:)
CITAZIONE
Io usavo il libro C corso completo di programmazione dei fratelli Deitel..

Si, ho anche quel pdf, molto bello...a dire la verità l'ha scovato la mia ragazza in rete.

Ho provato il tuo programma, e ho cercato di capirne la logica....

potenza=potenza*x

inizializzando potenza a 1... interessante!!!
io ho usato una variabile d'appoggio, ma è più snello il tuo metodo..sapevo che a chiedere c'è sempre qualcuno che trova la furbata migliore :)

[QUOTEIo il programma per l'elevazione a potenza l'ho fatto così all'epoca.. (il tuo è più completo, il mio non tratta i casi particolari e non si ripete, quando ha calcolato una volta esce dal programma)
][/QUOTE]

si, ho messo i casi particolari con degli IF e l'overflow. Anche se mi sono accorto di una cosa:

if ((r>2147483647)||(r<0))
io ho scritto se r maggiore di 2147483647 o minore di zero.
Il numerone è la cifra massima che può gestire l'int, ma avrei potuto fare semplicemente se r<0, visto che significherebbe che siamo già in overflow
e quindi sconfiniamo nella parte negativa che può gestire una variabile int...no?

In più noto, che con il tuo metodo, non sono necessarie le condizioni... se exp =0 stampa 1 ecc...
Solo quella dell'overflow mancherebbe....bene,bene...ne farò tesoro....Grazie Mattia !! :)
 
Top
Elemento 38
view post Posted on 24/4/2012, 17:02




Per far ripartire il programma da capo i GOTO non vanno bene, di solito si usa un ciclo do-while (che è identico al while, ma il primo giro lo fa sempre).
Il Deitel l'hanno fatto prendere anche a noi, lo sconsiglio perché è molto dispersivo e secondo me per chi è alle prime armi non è molto adatto; alle superiori mi sono trovato bene con Linguaggio e C++ di T.Canonico.
Nel ciclo for, nel controllo, metti i<b, è più semplice che i<=(b-1) (e più veloce).
 
Top
view post Posted on 24/4/2012, 17:23
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


Grazie Ele...si, ho letto che i goto sono sconsigliati e poco eleganti...devo "riprogrammare" :) il cervello e non pensare all'assembler dove si usa molto.

Vero anche quello che dici sul ciclo for...diciamo che era un abbozzo di prova, per mettere assieme le cose fin'ora studiate.

Il ciclo while e do while, li ho studiati, devo solo prendere confidenza un po' a usarli.
Però una domanda: al di la dell'eleganza, che differenza fa usare il GOTO?

ok, è più brutale e appunto meno elegante, poi impegna 2 cicli macchina anzichè uno come la call in assembler, quindi fa perdere più tempo (almeno coi pic).

O forse cosa più grave: quando io faccio dei salti con una call per esempio (mi riferisco all'assembler), la CPU memorizza nello stack, i vari valori dei registri
la riga a cui stacca, per poi ripristinare il tutto con l'istruzione return.

Forse in C la cosa non è così e bisogna stare più attenti a non perdere dati, o rischiare qualcosa del genere?
é molto diverso il C dall'assembler... in certe cose mi confondo un po'. Vero che in assembly fare 5/3=1.666666 ti porta alla neuro in tempo zero
ma per certi aspetti è più spartano...più semplice. Lavori con i tuoi registri e basta, non si scappa.

Comunque Ele, se mi puoi dire un po' la storia del goto, se è questione di tempi, eleganza o un discorso dello stack.... intanto grazie :)
 
Top
Elemento 38
view post Posted on 24/4/2012, 18:19




Non c'è differenza, il file che esce dal compilatore è uguale, ma i GOTO non si usano in C. Soprattutto perché con i GOT perdi la leggibilità del codice, se ci sono molti cicli è un mezzo casino e alla fine se scrivevi il codice in assembler era la stessa cosa. CALL e GOTO sono due cose diverse, la GOTO carica direttamente un indirizzo nel registro PC, la CALL prima salva il contesto (contenuto attuale del PC, variabili, ecc...) nello stack che sarà poi ripristinato quando si ritornerà a quel punto del programma, Essenzialmente le CALL si hanno nelle chiamate a funzioni, le GOTO nei cicli, ma in ogni modo non si usa quell'istruzione nel codice, perché se no si perde la leggibilità di alto livello che ha un programma C.
 
Top
view post Posted on 25/4/2012, 11:20
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


Si Ele i goto e le call sono diverse...mi sono espresso male...la cosa che mi sta spiazzando un po' nel C è appunto che non ci sono le call.
Devi farti una funzione, il prototipo, l'invocazione ecc....molto simile dirai tu, ma con le call in assembler mi trovavo molto comodo.

Va bhè, è solo questione di prendere la mano, no?
 
Top
view post Posted on 26/4/2012, 17:52
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


Come dicevo, sto iniziando a studiare i puntatori, che da come capisco, sono una cosa un po' ostica. In rete si dice che è fondamentale capirne a fondo il significato, dal momento che si può accedere
alla memoria della macchina e lavorare a basso livello, sempre che questo sia necessario.

Ho trovato un esempio, dove vengono inizializzate due variabili es a=3 b=4. Poi si chiede di fare lo scambio cioè a=4, b=3. La cosa risulta facilissima usando una variabile temporanea:
temp=a;
a=b;
b=temp;

se scriviamo tutto senza un salto a una funzione, tutto funziona a dovere, mentre se lo scambio lo facciamo invocando una funzione, i valori restano immutati, perchè operiamo
sulle copie delle variabili. In pratica vengono fatte delle copie sullo Stack che al ritorno della funzione, viene distrutto. Quindi l'esempio fa vedere che usando i puntatori, tutto funziona a
dovere, le variabili vengono scambiate.

Ma una cosa non capisco bene, o meglio mi da sospetto: se io posso vedere a che indirizzo di memoria viene messa una variabile, quindi leggerne il contenuto, potrò fare anche il contrario:
cioè io all'indirizzo xxxx scrivo il numero 100.

per esempio:

int *g; // creo puntatore g
g=2686796; // lo indirizzo a 2686796

printf ("ora leggo indirizzo 2686796 %d",*g );

in questo modo, io ho creato il puntatore g, che mi fa leggere la locazione di memoria che desidero.
Ma, domanda: non è pericoloso scartabellare con i puntatori se non si sa bene dove si mettono le mani e come si mettono?

Se io non so dove inizia e dove finisce lo spazio di memoria adibito alle variabili, non è che posso andare a toccare dati che non devono essere toccati?
se io punto ad un indirizzo balordo, ho provato con 50, il programma mi va in crash.

Molto interessante il discorso dei puntatori, ma da quello che intravedo, anche pericoloso no? Mi sapete dire qualcosa a riguardo?
 
Top
Lakier15
view post Posted on 3/5/2012, 10:33




Devo premettere che io programmo in C e C++ come un mulo.
Ho fatto motori grafici, reti neuronali, intelligenze artificiali etc...

Questo per dire che in tutti i miei programmi mai una volta ho scritto qualcosa in un dato indirizzo di memoria come hai fatto tu

QUOTE
int *g; // creo puntatore g
g=2686796; // lo indirizzo a 2686796

printf ("ora leggo indirizzo 2686796 %d",*g );

Questo perche' come hai detto tu, e' un'operazione pericolosa. Se tocchi un indirizzo che non dovresti c'e' il rischio di corrompere i dati nella ram e quindi ti si potrebbe impallare il pc dopo che il programma e' stato eseguito multeplici volte. Comunque e' relativamente pericoloso perche' un buon restart del computer rimette a posto tutto ;)

Questo certo riguarda la scrittura. Per la lettura chiaramente puoi fare quello che ti pare, pero' a meno che non conosci l'indirizzo di un certo dato che ti interessa e' alquanto inutile.

Le operazioni che si fanno con i puntatori in genere sono diverse da quelle che intendi tu. In genere ti serve leggere gli indirizzi di variabili pre-esistenti o di variabili dichiarate ma non inizializzate.
Un' altra cosa che si usa fare e' usare i puntatori per creare variabili a dimensioni dinamiche etc...

Quando un puntatore e' allocato, e' allocato automaticamente nella memoria che non e' utilizzata, quindi non c'e' rischio di andare ad utilizzare un indirizzo di memoria che sia pericolosa per il funzionamento del programma.
 
Top
view post Posted on 3/5/2012, 17:10
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


Grazie mille Lakier :). Ho scritto perchè in rete, mi pare di aver letto che i puntatori e l'allocazione dinamica della memoria, sono 2 cose importanti..un punto di forza del c.

Sicuramente, sono cose che verranno dopo.
Grazie ancora ;)
 
Top
view post Posted on 4/5/2012, 08:15
Avatar

Immane Rompiball

Group:
Administrator
Posts:
18,287
Location:
Orlo esterno della cintura di Orione stella 1957

Status:


Credo che sia importante dire che un programma scritto in C e compilato su di un PC perchè giri nel PC è una cosa, mentre, un'altra cosa completamente diversa è un programma scritto in C su di un PC e compilato perchè giri su di un sistema basato su di un altro processore in un'altra macchina, leggi, PIC, POC, PUK o quant'altro. Se si alloca una variabile statica in una macchina che non è un PC e si sa esattamente questo indirizzo di memoria da chi viene usato e a quale scopo allora non ci sono problemi. Se lo si fa in un PC dove non si sa mai a quale indirizzo quel programma girerà e cosa ci sarà a quella locazione di memoria allora sono rischi veramente grandi. :)
 
Web  Top
Lakier15
view post Posted on 4/5/2012, 08:35




Si è vero che fare l'operazione su di un uP potrebbe essere utile. Comunque per quanto riguarda il rischio credo che scrivere il suddetto programma per un uP è dannatamente rischioso.

Il PC ha delle protezioni particolari cosicché è praticamente impossibile creare danni permanenti.
Su di un uP, che sia PIC che sia AtMega, non sarei tanto tranquillo a scrivere nei registri se non sono sicuro di aver scritto nell'indirizzo giusto. :unsure:
I uP sono elementari se comparati ai processori per PC e non vorrei per qualche errore mio ( faccio sempre un sacco di errori quando programmo ) giocarmi il uP. :(
 
Top
view post Posted on 4/5/2012, 16:37
Avatar

Rompiball

Group:
Appassionati
Posts:
2,612
Location:
briansa

Status:


CITAZIONE
Su di un uP, che sia PIC che sia AtMega, non sarei tanto tranquillo a scrivere nei registri se non sono sicuro di aver scritto nell'indirizzo giusto.

Ok,fino a qui ci sono: se io metto valori a caso nei registri di un up o uc, rischio davvero di fare casino. Io con i pic, visto che non so il C, usavo l'assembler, e li, non si scappa:
datasheet alla mano e compili i vari registri.

Col C usandolo sul pc, se fai errori con i puntatori, windows, ti dice che il programma ha smesso di funzionare. Forse la mia guida (quella del link), fa l'errore di mettere i puntatori
e l'allocazione dinamica della memoria nelle prime pagine, quando invece sarebbe meglio affrontare questi problemi più avanti no?

Ora sto passando alla gestione delle stringhe, che sembra (per un principiante come me) più abbordabile...
Comunque, davvero interessante, ci sono esempi di algoritmi, che vale davvero la pena di studiare, per capire come altri hanno risolto, cosa che in assembler, ti farebbe davvero
diventare pazzo. Ho visto per esempio i vari programmi per ordinare array: naive sort, bubble sort, quick sort...davvero interessante :)
 
Top
Lakier15
view post Posted on 4/5/2012, 16:54




Si sono estremamente interessanti. Che poi ti insegnano le strategie generali per la creazione di nuovi algoritmi.

Il mio preferito è sicuramente il Bubble Sort. Semplice ma efficace. :)
 
Top
31 replies since 16/4/2012, 10:44   689 views
  Share