Arduino Forum

International => Italiano => Software => Topic started by: zinim on Oct 08, 2012, 11:48 am

Title: Creare Librerie
Post by: zinim on Oct 08, 2012, 11:48 am
Salve,
qualcuno sa indicarmi una guida per creare librerie per arduino, ho comprato quattro libri sulla programmazione di arduino e nessuno di questi spiega come creare le librerire.
grazie
Title: Re: Creare Librerie
Post by: uwefed on Oct 08, 2012, 12:00 pm
http://arduino.cc/en/Hacking/LibraryTutorial
Ciao Uwe
Title: Re: Creare Librerie
Post by: zinim on Oct 13, 2012, 07:29 pm
Non esiste un'altra guida che spiega come creare librerie, perchè quella riportata da arduino non spiega molto bene e vedendo librerie create da altri, mi sembra non spieghi nemmeno tutto.

Grazie
Title: Re: Creare Librerie
Post by: leo72 on Oct 14, 2012, 07:19 am

Non esiste un'altra guida che spiega come creare librerie, perchè quella riportata da arduino non spiega molto bene e vedendo librerie create da altri, mi sembra non spieghi nemmeno tutto.

Grazie

Allora ti devi prendere un manuale di C++ e lì imparare tutto quello che ti serve sulla suddivisione dei programmi in file .h e .cpp.
Title: Re: Creare Librerie
Post by: zinim on Oct 14, 2012, 01:58 pm
Sapete indicarmi una buona guida per il c++?
Grazie
Title: Re: Creare Librerie
Post by: mastraa on Jan 16, 2014, 03:23 pm
Sfrutto questo vecchio topic per non aprirne di nuovi inutilmente.

Volevo un paio di chiarimenti per quanto riguarda le librerie:

innanzitutto volevo sapere se nel file.h dove indichiamo le istanze è possibile inserire più di un'istanza un costruttore (ad esempio voglio settare un pin diverso per tre o quattro cose che può fare la libreria, anche contemporaneamente).

Inoltre è corretta il seguente schema come 'base' per tutte le librerie per il file *.c?

Code: [Select]
#ifndef Mille_h
#define Mille_h
#if ARDUINO >=100
#include "Arduino.h"
#else
#include "WProgramm.h"
#include "pins_arduino.h"
#endif


class Mille{

public:
Costruttore_1(int pin);
       Costruttore_2(int pin); //Intendo questo, è possibile?
void securOff();

private:
int _pin;
};

#endif
Title: Re: Creare Librerie
Post by: PaoloP on Jan 16, 2014, 04:36 pm
Puoi sfruttare l'overload del C++
Nomini la funzione con lo stesso nome ma passandogli numero o tipi di dati diversi.
Il compilatore seleziona la funzione che corrisponde alla chiamata.

Esempio la libreria Ethernet.h (https://github.com/arduino/Arduino/blob/master/libraries/Ethernet/Ethernet.h (https://github.com/arduino/Arduino/blob/master/libraries/Ethernet/Ethernet.h))
Tutte le funzioni si chiamano begin ma hanno un numero diverso di parametri.
Oppure la Print.h dove le funzioni print o println che hanno un solo parametro (a volte due) ma cambia il tipo passato (https://github.com/arduino/Arduino/blob/master/hardware/arduino/cores/arduino/Print.h (https://github.com/arduino/Arduino/blob/master/hardware/arduino/cores/arduino/Print.h)).
Title: Re: Creare Librerie
Post by: lestofante on Jan 16, 2014, 04:37 pm
normalmente le "librerie" arduino non sono altro che delle classi C++
Title: Re: Creare Librerie
Post by: nid69ita on Jan 16, 2014, 04:40 pm

Inoltre è corretta il seguente schema come 'base' per tutte le librerie per il file *.c?


Non vorrei dire una cavolata, ma se il file contiene delle classi, deve essere .cpp e non .c
Mi sembra che il compilatore faccia questa differenziazione.
Title: Re: Creare Librerie
Post by: lestofante on Jan 16, 2014, 04:50 pm
anche se non la facesse è sarebbe comunque uno standard de faco da rispettare.

ps. la mia risposta di prima era basata sulla pagina 1 del topic, non avevo notato la 2

Title: Re: Creare Librerie
Post by: PaoloP on Jan 16, 2014, 04:52 pm
Nel Reference ci sono anche delle guida utili
--> http://arduino.cc/en/Reference/StyleGuide
--> http://arduino.cc/en/Reference/APIStyleGuide
Title: Re: Creare Librerie
Post by: mastraa on Jan 16, 2014, 04:55 pm
si scusa, ho scritto c perchè pensavo a un file c, chiaramente mi riferisco al cpp ;)

Quindi se non ho capito male conviene spostarsi alla funzione (come dice PaoloP) e quindi dichiarare x funzioni con ugual nome, ma diversi parametri

Oppure dichiarare più classi, ognuna con il suo costruttore (come dice lesto)

Capisco bene?

Quello che servirebbe a me è di fatto riunire in un unico codice alcuni funzioni matematiche, altre più 'personali' che mi servono per un progetto abbastanza pesante. In questo modo evito di inserire decine di funzioni che poi non mi servono, non scrivo tutto nel file ino che poi diverrebbe un casino e raccolgo tutto nello stesso posto.

Faccio un esempio: per una questione di sicurezza volevo fare in modo che il sistema fosse alimentato da un relay tenuto chiuso da Arduino stesso durante il lavoro, e si aprisse in caso un sensore mi desse un valore allarmante.
Ad esempio la classe Off viene inizializzata sul pin 13 che comanda il relay. la funzione Off.securOff(); sa che spegne il relay indicato prima.

Nella stessa libreria però volevo inserire anche altre funzioni, che lavorano con pin differenti...

Quindi conviene fare una seconda classe e inizializzarla su un altro pin?


Scusate le domande idiote, ma conosco C++ solo lato Arduino in quanto ho avuto a che fare con altri linguaggi, seppur simili, all'università
Title: Re: Creare Librerie
Post by: lestofante on Jan 16, 2014, 05:11 pm

Oppure dichiarare più classi, ognuna con il suo costruttore (come dice lesto)

eh? dove? comunque no, anche il costuttore può essere sovracaricato, esattamente comne una normale funzione.

Quote
Nella stessa libreria però volevo inserire anche altre funzioni, che lavorano con pin differenti

SE vuoi usare le stesse funzioni ma su pin differenti, allora conviene istanziare un secondo oggetto passando come parametro il pin. Se le funzioni sono differenti, il problema non si pone, se non che teoricamente il codice va diviso in classi secondo logica, ovvero una classe che gestisce il relè di sicurezza non fa cose di matematica, ma ci sarà un altra classe che fa la matematica.
Title: Re: Creare Librerie
Post by: mastraa on Jan 16, 2014, 05:40 pm


Oppure dichiarare più classi, ognuna con il suo costruttore (come dice lesto)

eh? dove? comunque no, anche il costuttore può essere sovracaricato, esattamente comne una normale funzione.

Quote
Nella stessa libreria però volevo inserire anche altre funzioni, che lavorano con pin differenti

SE vuoi usare le stesse funzioni ma su pin differenti, allora conviene istanziare un secondo oggetto passando come parametro il pin. Se le funzioni sono differenti, il problema non si pone, se non che teoricamente il codice va diviso in classi secondo logica, ovvero una classe che gestisce il relè di sicurezza non fa cose di matematica, ma ci sarà un altra classe che fa la matematica.


Avevo interpretato la tua risposta data ad un altro, ma l'ho letto in seguito questo.
Ok grazie mille a tutti :)
Title: Re: Creare Librerie
Post by: PaoloP on Jan 16, 2014, 05:51 pm
Altrimenti prendi il tuo sketch, tagli le funzioni dal file .ino e le incolli in un file funzioni.h e lo #includi nello sketch.
Più semplice ancora, apri una nuova tab nell'IDE (pulsantino sotto quello del Serial Monitor) e sposti le funzioni che non ti interessano nel corpo principale.
Title: Re: Creare Librerie
Post by: BaBBuino on Jan 16, 2014, 06:45 pm
Ma diamine! Siamo nel 2014 e ancora di questi post?

Digita su Google: "Creare librerie per arduino", ti escono 50 link solo in italiano!
Title: Re: Creare Librerie
Post by: Maurotec on Jan 16, 2014, 08:07 pm

Ma diamine! Siamo nel 2014 e ancora di questi post?

Digita su Google: "Creare librerie per arduino", ti escono 50 link solo in italiano!


Che a seguirli tutti è una perdita di tempo dove non impari quasi nulla.

Chi riesce a condensare in 10 pagine l'argomento partendo da zero? Risposta: nessuno

Ciao.
Title: Re: Creare Librerie
Post by: BaBBuino on Jan 16, 2014, 08:27 pm

Salve,
qualcuno sa indicarmi una guida per creare librerie per arduino, ho comprato quattro libri sulla programmazione di arduino e nessuno di questi spiega come creare le librerire.
grazie



Mauro, rileggi bene la richiesta. Non deve diventare un professionista del C, ma creare librerie per Arduino.

E se ci sono riuscito io (che sono una pigna) con quegli articoli , ci può riuscire chiunque. E questo senza leggere libri esoterici o diventare un Guru del C++
Title: Re: Creare Librerie
Post by: leo72 on Jan 17, 2014, 08:56 am

Ma diamine! Siamo nel 2014 e ancora di questi post?

Digita su Google: "xxxxxxxxxx", ti escono yyy link solo in italiano!


Ecco, messo così lo si potrebbe applicare al 70% dei post che vengono pubblicati. :smiley-roll:
Title: Re: Creare Librerie
Post by: lestofante on Jan 17, 2014, 11:09 am
però poi lui ha postato il codice chiedendo una valutazione e consiglio sull'organizzazione del codice.. cosa che solo noi poveri umani possiamo fare.

Certo, avesse conosciuto il linguaggio a fondo avrebbe visto subilto la soluzione, ma inzomma siam stati tutti nabbi.
Title: Re: Creare Librerie
Post by: mastraa on Jan 18, 2014, 03:37 pm
Se io ho bisogno di una funzione che mi ritorni 3 valori float come posso fare?

E' meglio dichiarare tre variabili pubbliche poi utilizzarle nello sketch?
Title: Re: Creare Librerie
Post by: PaoloP on Jan 18, 2014, 03:48 pm
Se hai necessità che restituisca tre diversi valori potresti passarli come puntatori ed elaborarli all'interno della funzione oppure li dichiari globali e li hai sempre a disposizione.
Title: Re: Creare Librerie
Post by: mastraa on Jan 18, 2014, 04:07 pm
grazie!!!
Title: Re: Creare Librerie
Post by: mastraa on Jan 18, 2014, 07:32 pm
Una delucidazione, spero sia l'ultima per vedere se ho capito bene:

Variabile public:
Le posso usare sia nelle funzioni della classe, sia al di fuori e rimangono definite per 'sempre'
Variale private:
Utilizzabili solo dentro alla classe, rimangono valide per 'sempre'
Variabile dichiarate dentro una funzione (di una classe o meno):
Valgono solo dentro quella funzione e vengono ridichiarate ad ogni ciclo

E' corretto?

Quindi se io ho bisogno di una variabile solo dentro una funzione di una classe, ma che rimanga anche alla chiamata successiva per una iterazione, la dovrei mettere private, se una mi serve averla sempre e accessibile 'dallo sketch' la devo mettere pubblica.
Se mi basta averla dentro a una funzione la dichiaro li dentro
Title: Re: Creare Librerie
Post by: lestofante on Jan 19, 2014, 01:39 pm
prima di tutto c'è il tempo di vita delle variabili.
Una variabile che viene istanziata all'interno di un blocco,muore alla sua fine.
Un blocco è delimitatato da { }
quindi una bariabile dichiartata in un blocco if, morirà al termine dell'if.

Poi c'è la visibilità;
una variabile/funzione/classe public è richiamabile all'esterno della classe;
una variabile/funzione/classe protected è richiamabile dalle sotto classi;
una variabile/funzione/classe private è richiamabile dalla classe che la istanzia;
Title: Re: Creare Librerie
Post by: mastraa on Mar 22, 2014, 06:33 pm
Riesumo nuovamente un topic sulle librerie per chiedere una spiegazione:

Innanzitutto ho trovato in giro delle librerie che non hanno bisogno di essere inizializzate dal costruttore, si tratta di librerie che non lavorano a classi?
(Ho letto che le librerie non per forza devono essere organizzate in classi, come si fanno queste ultime?)

Ad esempio prendiamo la libreria Wire.h... non ha il costruttore no? come faccio a creare una libreria simile?

Se poi io volessi usare una libreria dentro un'altra libreria, oppure una funzione di comodo dentro alla funzione che non uso all'esterno, ma che alcune funzioni della stessa libreria richiamano. Come devo dichiararla?

Faccio un esempio pratico: ho 2-3 funzioni che elaborano dei dati letti da un sensore I2C, per la lettura voglio fare una funzione a sé che richiamo senza scrivere ogni volta...la dichiaro sempre allo stesso modo type CLASS::function(){}? e quando la richiamo la chiamo senza il costruttore (che ovviamente dentro alla libreria non so visto che è a discrezione)?

Spero di essere stato chiaro, anche se mi rendo conto di essere stato un po' contorto in alcuni punti
Title: Re: Creare Librerie
Post by: mastraa on Mar 22, 2014, 07:49 pm
Ho fatto delle prove quindi esplicito meglio le mie domande e i miei dubbi:



Ho poi provato a vedere come funziona richiamare una funzione in una seconda funzione della stessa classe, ho visto che non serve il costruttore, ma se io ho bisogno di usare la funzione di un'altra classe o di un'altra libreria?
Faccio un esempio: devo creare una libreria che mi serve a leggere due sensori I2C:


Spero di essermi spiegato meglio :)
Title: Re: Creare Librerie
Post by: Maurotec on Mar 22, 2014, 09:43 pm
Sicuramente hai dato il massimo per spiegarti, ma non sono riuscito a seguirti.

La Wire, come la Serial sono classi che hanno un costruttore (in C++ il costruttore c'è sempre) e vengono pre-istanziate nel codice di libreria. Se apri Wire.h e Wire.cpp ti accorgi che in all'ultima riga del .cpp, che la creazione di una istanza:
Code: [Select]
TwoWire Wire = TwoWire();

nel .h c'è la dichiarazione di Wire extern:

Code: [Select]
extern TwoWire Wire;

Quest'ultima rende visibile la variabile Wire a tutto il codice che include l'header file Wire.h.

Se tu vuoi fare la stessa cosa prendi esempio da Wire, se non è questo che ti serve, spiega cosa ti serve.
Forse sarebbe più semplice se spiegassi un solo punto per volta e così' ci si concentra su una sola cosa.

Ciao.
Title: Re: Creare Librerie
Post by: mastraa on Mar 22, 2014, 10:43 pm
Beh si diciamo che hai dato soluzione a molti miei dubbi, ora vorrei capire bene cosa vuol dire quel codice, ma ho capito che di fatto fa l'istanza già dentro la libreria e l'Arduino ovviamente la vede come parte di codice integrando tutto assieme.

Solo che in genere l'istanza la si fa tipo

nomeClasse name;
oppure se necessita di parametri nomeClasse name(parametri);

quindi perché abbiamo TwoWire Wire=TwoWire(); cioè a cosa fanno riferimento? Wire sicuramente al 'name' indicato prima, il primo TwoWire sarà il 'nomeClasse', ma il secondo TwoWire?

Il resto me lo sono appena risolto da solo con l'aiuto della Cookbook

grazie mille:)
Title: Re: Creare Librerie
Post by: Maurotec on Mar 22, 2014, 11:05 pm
Quote
Il resto me lo sono appena risolto da solo con l'aiuto della Cookbook


Quale libro? link please (sempre se c'è link).

Argomentare sarebbe lungo e io non ho informazioni fresche su C++.
Non ho idea del perché abbia usato quella sintassi, per me sarebbe bastato TwoWire Wire;
In quel caso si è chiamato in causa il costruttore di copia e non ho indagato se nella classe ne è stato fornito uno
esplicito. Quando ho qualche dubbio, apro QtCreator creo un progetto C++ e sperimento sul PC.

Ciao.
Title: Re: Creare Librerie
Post by: mastraa on Mar 23, 2014, 12:38 am
Il link alla cookbook si trova in giro, io ce l'ho, ma non so se sia legale e quindi se si possa inserire qui nel forum/sito...ad ogni modo con una piccola ricerca su google lo trovi.
Si chiama Arduino Cookbook della O'reilly.

Grazie comunque!!!
Title: Re: Creare Librerie
Post by: lestofante on Mar 23, 2014, 01:46 am
Quote
Innanzitutto ho trovato in giro delle librerie che non hanno bisogno di essere inizializzate dal costruttore, si tratta di librerie che non lavorano a classi?


dipende. A colpo d'occhio puoi distuinguere una classe (quindi C++) da una libreria (quindi C) (quindi sì, chiamare "librerie" quelle di arduino è un errore, sono quasi tutte classi) dal fatto che di solito una classe ha un file .cpp che si chiama come il file .h e ne implementa i metodi. Poi se apri il .h e vedi "class" o "interface" da qualche parte, allora sai che hai a che fare con una classe :) )

Dal punto di vista funzionale invece cambia tantissimo; avere un oggetto fa in modo tale che tu possa fare nomeOggetto.funzione(parametro); invece una vera libreria è una raccolta di funzioni che vengono appese (immagina un copia/incolla) al tuo codice, il che vuol dire che hai un sacco di problemi; niente funzioni con lo stesso nome, niente "memorizzazione di stato" per la amancanza di variabili etc..

Quindi una classe può contenere una o più altre classi, o perfino estenderle, mentre una libreria è una grezza raccolta di funzioni.

Di default tutte le classi hanno un costruttore "void", ovvero senza parametri e che non fa nulla. Se vuoi tu puoi sovrascrivere (override) questo costruttore, aggiungendo anche parametri (sovraccaricarlo).

quindi

Code: [Select]


TwoWire::TwoWire(){//override costruttore void
}

TwoWire::TwoWire(int parametro){//sovraccarico costruttore
}


In generale temo ti manchino le basi per riuscire a capire a fondo il tema. Parti dall'idea ad oggetti (C++) o lineare (C) perchè sono due cose fondamewntalmente differenti.

Consiglio di programmareil C puro su pc (copn arduino è pressochè impossibile) e vedrai che le differenze e tantecose le capirai
Title: Re: Creare Librerie
Post by: mastraa on Mar 23, 2014, 10:53 am
Grazie lesto,

quindi detta in parole spicce: si può fare una classe che ti permette di avere molte 'funzionalità' in più. Cioè di chiamare più funzioni con lo stesso nome perché poi sono richiamate dal costruttore di classe ecc. ecc.

Oppure fare un semplice elenco di funzioni (C non l'ho usato molto, però con PHP e Javascript è lo stesso) dove si mettono le funzioni e poi si caricano nello sketch e via. Questa seconda opzione con Arduino non è possibile giusto? Quello che io utilizzo senza istanza (Wire, Serial, SD) è solo perché è già istanziato nella libreria?

Poi andrò chiaramente a cercare qualche guida, ma cerco di fare le cose mirate, anche perché purtroppo il tempo che ho non è molto e in quella, poca, esperienza che ho, mi sono reso conto che apprendo molto di più a pormi i problemi facendo cose anche 'ambiziose' e rispondendomi (anche non partendo dalle basi basi) che prendere una guida, leggerla senza 'giocare' e finire per dover rileggere ogni volta che mi serve una cosa
Title: Re: Creare Librerie
Post by: lestofante on Mar 23, 2014, 03:58 pm
Quote
(C non l'ho usato molto, però con PHP e Javascript è lo stesso)

attento che PHP e JS inseriscono qualche cosa di oggetti, per esempio puoi incapsulare variabilioltre che funzioni e giochetti simili..


Quote
non è possibile giusto


si che è possibile, basta aprire un secondo tab (o più) nell'edito ed inserire le propire funzioni. Non si fa così nel C vero, ma ci avvicianiamo abbastanza. ( l'ide arduino non gioca proprio pulito, per questo consigliavo di fare programmi lato pc)

Quote
Quello che io utilizzo senza istanza (Wire, Serial, SD) è solo perché è già istanziato nella libreria?

esatto, la classe crea un istanza (di solito statica) di se stessa, così tu non rischi di istanzairala due volte e creare casini. Invece la Servo, per esempio, non si auto istanzia, perchè ogni pin è comandabile a sè. Immagina di fare la stessa cosa con le funzioni e basta; non puoi,dovresti essere te a mantenere un array di strutture contenenti i dadi da passare alle funzioni in base a quale pin vuoi comandare.


Se vai nel reference, troverai come scrivere una "libreria" in aruino, che poi è una classe. Ti consiglio di seguirla,
Title: Re: Creare Librerie
Post by: mastraa on Mar 24, 2014, 10:12 pm
Grazie mille, ti rompo ancora per una cosa:

quando scrivo una funzione in libreria e inserisco dei parametri anticipati da *nome o &nome che significa?

Credo di aver capito che si tratta di indicare tipo l'indirizzo della variabile da modificare o qualcosa del genere, nel senso che modificando, all'interno della funzione, la variabile 'nome' vado in realtà a fare la modifica alla variabile che ho passato durante lo sketch nella posizione di nome.

E' corretto? cosa cambia per le due sintassi?
Title: Re: Creare Librerie
Post by: lestofante on Mar 24, 2014, 11:11 pm
cosa cambia? il mondo.
Non sto scherzando, la differenza è che stai usando i puntatori, concetto fondamentale non solo del C, ma di TUTTI i linguaggi di programmazione, anche se fanno di tutto per nasconderteli. Molto potenti, e per questo molto facile combinare casini :)

Segui la guida che ho in firma, ti porta ad una guida su HTML.it sul C in italiano ottima per iniziare.
Title: Re: Creare Librerie
Post by: Maurotec on Mar 25, 2014, 12:24 am
Il C++ ha introdotto il passaggio di parametri per rifermento o alias tramite l'operatore &.
La confusione deriva dal fatto che & ricava l'indirizzo di una variabile.
L'operatore & usato su un parametro significa passa il riferimento ed è come se passassi il puntatore, cioè non viene fatta una copia locale del parametro.

Passare un puntatore o un riferimento e più rapido, più efficiente. Alle volte non vogliamo modificare il valore, ci basta leggere il contenuto della variabile passata per riferimento o come puntatore, in tal caso si usa anteporre il qualificatore "const", es: (const type &nameVar) o (const type *nameVar).
Ci sono varianti che per essere comprese si devono sperimentare sul pc, es: (type * const nameVar) il puntatore è costante ma il contenuto di nameVar lo posso cambiare senza ricevere errore in fase di compilazione.

Con (const type *nameVar) se provi a cambiare il contenuto della variabile da dentro la funzione ricevi errore in fase di compilazione.

Sono convinto che la difficoltà di comprensione con i puntatore e gli alias deriva dal fatto che non si ha bene chiaro
come è organizzata la RAM, un buon libro C/C++ spiega i puntatori usando delle caselle numerate con indirizzi esadecimali e mostra cosa accade graficamente.

Ciao.
Title: Re: Creare Librerie
Post by: lestofante on Mar 25, 2014, 01:37 pm
Quote
Il C++ ha introdotto

??? il passaggio di puntatori come parametri c'è anche in C
Title: Re: Creare Librerie
Post by: gpb01 on Mar 25, 2014, 01:47 pm
Solito link "legale per uso personale" da dove reperire un bel libro sull'argomento ... Understanding and Using C Pointers (http://it-ebooks.info/book/2265/)

@ mastraa : studiatelo bene ... ;)

Guglielmo
Title: Re: Creare Librerie
Post by: mastraa on Mar 25, 2014, 02:02 pm

cosa cambia? il mondo.
Non sto scherzando, la differenza è che stai usando i puntatori, concetto fondamentale non solo del C, ma di TUTTI i linguaggi di programmazione, anche se fanno di tutto per nasconderteli. Molto potenti, e per questo molto facile combinare casini :)

Segui la guida che ho in firma, ti porta ad una guida su HTML.it sul C in italiano ottima per iniziare.


Adesso la guardo, non mi veniva la parola così al posto di puntatori ho messo indirizzo credo  ]:D
Title: Re: Creare Librerie
Post by: lestofante on Mar 25, 2014, 02:09 pm
i puntatori puntando ad un indirizzo (o aria di memoria) quindi il termine non è errato
Title: Re: Creare Librerie
Post by: mastraa on Mar 25, 2014, 02:44 pm

i puntatori puntando ad un indirizzo (o aria di memoria) quindi il termine non è errato


Ho letto la guida, ma tra l'altro già ci avevo dato un'occhiata tempo fa e infatti cosa sono i puntatori ce l'ho più o meno chiaro, ora ho chiaro anche quale sia la differenza tra & e *:

* serve per memorizzare il valore della variabile puntata
& serve per memorizzare l'indirizzo della variabile puntata

quello che non riesco a immaginare è cosa succeda passando a una funzione l'uno e l'altro.

Cioè nella guida fa l'esempio di una funzione (swap) che richiede due *puntatori e vengon a passati due &parametri
quindi crea di fatto un puntatore (con *) e io passo l'indirizzo (con &). Giusto?
Su questo non mi è chiarissimo, ma diciamo che ha la sua logica e credo si tratti di fare esperienza.

Io però ho un codice dove il codice della funzione chiede direttamente dei parametri con &, in questo caso cosa fa?

Ad esempio viid funzione (chat pinco, unsigned int &palla){...};

Cosa fa? memorizza solo l'indirizzo del parametro che gli passerò?

e quando dentro alla funzione poi vedo "palla = x+y;" cosa sta facendo? nel senso che io ora in palla ho il valore dell'indirizzo a quanto ho capito dalla guida...


Cioè a me non è che non sia chiaro cos'è un puntatore, piuttosto non capisco cosa succede quando passo dei parametri in questo modo a una funzione :smiley-red:
Title: Re: Creare Librerie
Post by: gpb01 on Mar 25, 2014, 03:05 pm
Hai visto il libro che ti ho indicato poco sopra ???  Perché li c'è di tutto e di più !  ]:D

Guglielmo
Title: Re: Creare Librerie
Post by: Maurotec on Mar 25, 2014, 03:06 pm

Quote
Il C++ ha introdotto

??? il passaggio di puntatori come parametri c'è anche in C


Certo, ciò che non c'è in C ANSI è il passaggio di parametri per rifermento o alias, cioè la seguente riga
è un errore:
Code: [Select]

myFunc(const int &nameVar) {

}

Mentre è valida per C++.


Quote
* serve per memorizzare il valore della variabile puntata
& serve per memorizzare l'indirizzo della variabile puntata


La confusione come ho già scritto prima deriva dal fatto che * e & svolgono compiti differenti in base a come e dove vengono scritti. & Ricava l'indirizzo di una variabile, oppure se usato nella lista dei parametri specifica il passaggio per riferimento o alias, che ti permette di accedere alla variabile da dentro la funzione.

La stessa cosa si può fare con i puntatori, ma per accedere alla variabile puntata devi anteporre *, operatore di risoluzione.

La cosa è molto semplice, quasi banale, tuttavia io compreso mi confondevo.

Come faccio a ricavare l'indirizzo di una variabile?
Uso l'operatore &. es: int *intPtr = &intVar;
Da destra verso sinistra: intVar è una variabile da cui ricavo l'indirizzo che assegno a intPtr che è un puntatore a tipo intero. PS: intPtr è anche una variabile per cui posso ricavare l'indirizzo di intPtr: &intPtr

Come faccio a passare un argomento per riferimento?
Uso l'operatore &

Da dentro la funzione come uso l'argomento passato per riferimento?
Nel modo normale di usare una variabile.

Come ricavo il valore da una variabile puntatore?
Uso * prima della variabile puntatore, per ricavare (leggere) il contenuto della cella di memoria.

Una cella di memoria ha due proprietà:
1) L'indirizzo della cella
2) Il dato conservato nella cella.

Ciao.
Title: Re: Creare Librerie
Post by: lestofante on Mar 25, 2014, 03:13 pm

* serve per memorizzare il valore della variabile puntata
& serve per memorizzare l'indirizzo della variabile puntata


non si "scrivere", ma di "usare".  In oltre sfortunatamente chi ha scritto il C ha deciso di usare il * anche per la dichiarazione

Quote
Certo, ciò che non c'è in C ANSI è il passaggio di parametri per rifermento o alias, cioè la seguente riga

oddio hanno spostato la & dalla chiamata alla funzione... cosa brutta secondo me, non ti accorgi se la tua variabile potrebbe essere modificata dalla funzione.. altri vantaggi?
Title: Re: Creare Librerie
Post by: Maurotec on Mar 25, 2014, 03:18 pm
@lesto
Puoi impedire alla funzione di modificare una variabile passata per riferimento o alias tramite il qualificatore  "const", stessa cosa per il passaggio di una variabile puntatore. Questo però l'ho già scritto nei post precedenti. 8)

Ciao.

Title: Re: Creare Librerie
Post by: mastraa on Mar 25, 2014, 03:22 pm
Il libro della O'Reilly lo sto aprendo ora che ho un computer disponibile e lo guardo!

Grazie Mauro, mi hai chiarito diversi aspetti, provo a riassumere per vedere se ci sono:

&var ricava l'indirizzo della variabile
io posso dichiarare *pointer (ferma restando la compatibilità tra tipi di variabili)
a questo punto posso assegnare a pointer l'indirizzo di var: pointer=&var
e quindi leggere var anche per mezzo di *pointer.

Nelle funzioni, nei parametri da passare:

'chiedere' &value permette di utilizzare value come se fosse la mia variabile che passo, quindi modificando value modifico anche la mia variabile. Però non posso leggerla perché ne ho solo l'indirizzo, se non tramite il 'giochetto' di prima passando per un puntatore.
Se ho necessita di leggere e modificare la richiedo tramite *value?
Title: Re: Creare Librerie
Post by: Maurotec on Mar 25, 2014, 03:28 pm
Quote

'chiedere' &value permette di utilizzare value come se fosse la mia variabile che passo, quindi modificando value modifico anche la mia variabile. Però non posso leggerla perché ne ho solo l'indirizzo, se non tramite il 'giochetto' di prima passando per un puntatore.
Se ho necessita di leggere e modificare la richiedo tramite *value?


Non è chiaro, fai un esempio di codice, così evitiamo fraintendimenti.
Il termine 'chiedere' &value, non è comprensibile.

Vuoi potere accedere ad una variabile da dentro una funzione nello stesso modo in cui la usi da fuori la funzione, ma senza usare puntatori? Nella lista di parametri della funzione usa & prima del nome della variabile, da dentro la funzione la userai nel modo consueto. Questo ovviamente modifica la variabile, in quanto non viene fatta copia locale come per il passaggio per valore.

ops ho dimenticato di chiarire una cosa.

Nella dichiarazione della funzione, i parametri sono da considerarsi essi stessi una dichiarazione, per cui
int &myAlias è una dichiarazione, che potrebbe anche essere detta in questi termini:
hei tu C myAlias è un argomento da passare per riferimento, capito!!
Mentre quando ricavi l'indirizzo di una variabile tramite &, l'indirizzo deve essere ricavato a tempo di esecuzione, qua la cosa si complica un pò a causa della allocazione dinamica della memoria, comunque il compilatore se conosce l'indirizzo di una variabile durante la compilazione risolve in modo statico, diversamente ricava il valore a tempo di esecuzione, cioè durante l'esecuzione del programma.

Ciao.
Title: Re: Creare Librerie
Post by: mastraa on Mar 25, 2014, 05:01 pm
Vorrei capire la differenza tra le due funzioni, nel senso che entrambe vanno a modificare la variabile che io passo nella posizione di value(s).

Dopodichè in alcuni esempi (anche nei link che mi sono stati postati prima) vedo che quando ha l'* poi nel richiamarla devo usare & (ma qui ad esempio non lo fa, la seconda ad un certo punto richiama la prima).

Rimango 'ingannato' dal fatto che l'esito sembra lo stesso, ma sicuramente c'è un motivo perché si usa uno o l'altro modo.

Code: [Select]
char SFE_BMP180::readBytes(unsigned char *values, char length)
// Read an array of bytes from device
// values: external array to hold data. Put starting register in values[0].
// length: number of bytes to read
{
char x;

Wire.beginTransmission(BMP180_ADDR);
Wire.write(values[0]);
_error = Wire.endTransmission();
if (_error == 0)
{
Wire.requestFrom(BMP180_ADDR,length);
while(Wire.available() != length) ; // wait until bytes are ready
for(x=0;x<length;x++)
{
values[x] = Wire.read();
}
return(1);
}
return(0);
}

char SFE_BMP180::readUInt(char address, unsigned int &value)
// Read an unsigned integer (two bytes) from device
// address: register to start reading (plus subsequent register)
// value: external variable to store data (function modifies value)
{
unsigned char data[2];

data[0] = address;
if (readBytes(data,2))
{
value = (((unsigned int)data[0]<<8)|(unsigned int)data[1]);
return(1);
}
value = 0;
return(0);
}
Title: Re: Creare Librerie
Post by: lestofante on Mar 25, 2014, 05:34 pm
quando hai un puntatore, allora devi passre un undirizzo. Una cosa strana sono gli array; essi infatti sono dei puntatori sotto mentite spoglie! quindi NON hanno necessità di mettere lo & davanti, anzi, se usi il nome dell'array con il * è come fare
Code: [Select]
[0] (leggi il primo elemento).

Devi studiare bene quelle guide, i puntatori non si imparano dall'oggi al domani, ti mancano puntaori a funzioni, puntatori doppi (e così via), puntatori void, puntatori a strutture, liste dinamiche, e un intero mondo.
Title: Re: Creare Librerie
Post by: Maurotec on Mar 25, 2014, 10:44 pm
@lock
Anche in asm puoi usare una cella di memoria al cui interno ci scrivi un indirizzo di memoria, che equivale a creare puntatori, ma in quel caso ricavi il contenuto della prima cella e lo usi per accedere alla cella di memoria che risiede a quell'indirizzo. Quindi non credo che si tratti di C, C++ o pascal o modula ecc, semplicemente la ram è fatta così. Ma poi che mi fai scrivere che lo sai meglio di me  :smiley-yell:

Quote
Rimango 'ingannato' dal fatto che l'esito sembra lo stesso, ma sicuramente c'è un motivo perché si usa uno o l'altro modo.


Nella tua testa c'è una grande confusione, che diminuirà solo dopo che sperimenti in prima persona come funzionano il C/C++, e l'unico modo è quello di usare un compilatore per PC o (IDE). Crei alcune variabili e stampi i loro indirizzo, crei funzioni e passi i parametri in tutti i modi conosciuti, nessuna variante esclusa. Sperimentare con il C/C++ su un dispositivo embedded non è pratico nè comodo, se ti convinci di ciò ti renderai conto come stanno le cose e alla fine considererai anche banale l'argomento che comunque non mancherà di fregarti quando meno te lo aspetti.

readBytes prende un puntatore ad tipo unsigned char, quindi il puntatore sarà grande 16 bit ma la cella a cui punta è grande 8 bit. Nella chiamata puoi passare un puntatore o un array (vedi cosa dice lesto).

Nel caso specifico di readBytes la funzione è pensata per gestire l'array passatogli attraverso il puntatore "values", infatti il parametro seguente si chiama length, cioè lunghezza di che ? dell'array.

readUInt prende due argomenti, il primo passato per valore e il secondo passato per riferimento.

Se vuoi puoi scrivere dei pezzi di programma piccoli a cui aggiungi i commenti (chiari chiari) che poi noi qui li correggiamo.

char *charPtr; // Un puntatore non ha segno quindi unsigned char al posto di char, ma non è un obbligo
charPtr prende 2 celle di memoria in quanto il puntatore in AVR è grande 16 bit.
Il dato a cui punta invece è grande 8 bit (lo specifica char).
Per ricavare il dato (valore) a cui punta charPtr si antepone *, es: char myChar = *charPtr; // ricavo il valore e lo salvo in myChar, il valore può avere segno negativo o positivo.

charPtr++; incrementa il puntatore di 1 cella, questo mi da accesso alla cella seguente charPtr.
*(charPtr++) incremento e ricavo il valore.

Sono un poco maligno perché voglio che ti convinci a sperimentare il C/C++ su un pc, sarò ancora più maligno
(se prima non lo fa lesto) la prossima volta con i puntatori a puntatori (che mi procurano mal di testa). 

Ciao.
Title: Re: Creare Librerie
Post by: lestofante on Mar 26, 2014, 11:58 am
@lock: guarda, a ta punto potrei salvarti un saccod i mal di testa con codesto programma, che interpreta il codice in modo matematico e becca tutti gli undefined behaviur

https://code.google.com/p/c-semantics/

edit: ah occhio che si sono spostati su https://github.com/kframework/c-semantics
Title: Re: Creare Librerie
Post by: mastraa on Aug 09, 2014, 10:10 pm
Torno a sfruttare questo topic con un'altra domanda per la libreria che finalmente ho trovato il tempo di scrivere!

Sono arrivato al punto in cui ho bisogno di sfruttare una libreria trovata in giro dentro la mia. Mi spiego, devo usare la libreria OneWire (le sue funzioni) all'interno della mia classe DS18B20. So che esiste già la DallasTemperature, ma per questioni di spazio e velocità ho bisogno di crearmi la mia versione.

Ora ho letto che si può fare qualcosa del tipo class DS18B20: public OneWire, ma non trovo degli esempi con cui capire bene la sintassi e come funziona la cosa.

Qualcuno mi può aiutare?
Title: Re: Creare Librerie
Post by: mastraa on Aug 10, 2014, 04:28 pm
Ho capito il mio problema, ma non ho capito come risolverlo (sempre che sia una cosa ammessa in C):

per dichiarare una classe derivata di un'altra è sufficiente scrivere

class miaClasseDerivata: public miaClassePrincipale {...}

il mio problema deriva qualora miaClassePrincipale richiedesse dei parametri nel costruttore (come appunto OneWire)
Title: Re: Creare Librerie
Post by: leo72 on Aug 11, 2014, 10:19 am
A parte che stiamo parlando di C++ e non di C, non sono ferratissimo sull'argomento ma credo che tu abbia sbagliato qualcosa nel tuo codice (che non fornisci per cui vado ad intuito).
Leggi prima qui:
http://www.learncpp.com/cpp-tutorial/114-constructors-and-initialization-of-derived-classes/

Title: Re: Creare Librerie
Post by: mastraa on Aug 12, 2014, 12:06 am
alla fine sono riuscito a risolvere grazie anche all'aiuto di un amico più esperto. In pratica in tutti i tutoria che avevo trovato facevano sempre esempi di classi in cui il costruttore non richiedeva parametri. In tal caso (benché consigliato) non è obbligatorio richiamare il costruttore della principale dentro a quello della derivata. Cosa che invece è necessaria avendo costruttori che richiedono parametri nella classe principale (come appunto OneWire).

Title: Re: Creare Librerie
Post by: mastraa on Aug 19, 2014, 11:08 pm
Torno nuovamente a porre una questione, sto lavorando con la solita libreria e ora mi viene un errore che non capisco, ho già affrontato diverse volte la classe derivata da un altra, ma ora mi da un errore che non capisco.

Code: [Select]
class LCD_CLASSIC: public LiquidCrystal
{//riga 133!!!
public:
    LCD_CLASSIC(byte rs, byte enable, byte d4, byte d5, byte d6, byte d7);
    void start();
private:
    byte _col;
    byte _row;
};


Questo è il codice che ho scritto e mi dice che:

Code: [Select]


In file included from MPU6050.ino:4:
/Users/mastraa/Documents/Arduino/libraries/Mille/Mille_UNO.h:134: error: expected class-name before '{' token


alla riga 4 inserisco la mia libreria.
dentro la libreria ho incluso LiquidCrystal.h così come ho fatto per la Wire.h e anche la LiquidCrystal_I2C.h...

dove sbaglio?
Title: Re: Creare Librerie
Post by: leo72 on Aug 20, 2014, 07:04 am
Pare che ti sia scordato una parentesi.
Allega tutto il codice che usi (file .h, file .cpp e file .ino).
Title: Re: Creare Librerie
Post by: mastraa on Aug 20, 2014, 12:35 pm
Era una cosa ancora più stupida, forse non devo più mettermi alle 23 a fare ste robe!

Semplicemente avevo incluso LiquidCrystal dappertutto, meno che nello sketch di Arduino  :smiley-roll-sweat:

PS: ma il problema ancora più grosso è che mi sono sbagliato stanotte con la soluzione  :smiley-eek:
Title: Re: Creare Librerie
Post by: lestofante on Aug 20, 2014, 04:53 pm
se estendila classe onewire è perchè vuoi aggiungerene/modificarne le funzionalità. se vuoi solo usarla allora la usi e basta come fai conla Serial (che però è statica) o la Servo.

se apri la libreria DSblabla vedrai che è una semplice classe che USA la OneWire per fare quello che vuoi fare tu: quindi la libreria stessa che vuoi sostituire è la tua base di partenza!