Rispondo io. Il celeberrino.
Intanto ti prego. Controllati! Non farmi più complimenti. E' una richiesta ben precisa, 'che altrimenti non ti rispondo più.
Domanda 1: perchè no? Si può fare. Avere double dappertutto invece che 'semplici' float.
Domanda 2: E' una convenzione. Così come è stata una convenzione, agli SLE, dire che uno spostamento del baricentro , concorde con la compressione sia anch'esso positivo.
Ovviamente da tale convenzione discende tutto il resto.
Domanda 3: Quelle che riporti sono 'prototipi' delle funzioni.
In sintesi, informi il compilatore, prima che esso le debba compilare, di che natura sono le varie funzioni che incontrerà nel proseguo del listato.
Praticamente è come con le variabili. Per prima cosa le dichiari, poi le utilizzi.
In questo modo il compilatore si 'organizza' (non saprei dirti come ovviamente) lasciando i giusti spazi in memoria, ecc.
Nel C di Kernigan e Ritchie le funzioni avevano bisogno del prototipo prima solamente se non restituivano un valore int. Quando il comitato ANSI decise di standardizzare i vari dialetti C che prorompevano sulla scena, decise che era buona norma che tutte le funzioni fossero prima 'prototipate'.
Andiamo agli esempi. Parto dal semplice, andando verso il difficile
void inversione_poligono (int);
Protopito della funzione denominata inversione_poligono. Essa accetta in ingresso (parametri formali) una variabile di tipo int (mi pare fosse il numero del poligono da invertire) e restituisce il valore......NULLA (attenzione, non NULL, o 0) semplicemente questa è una funzione che non restituisce alcun valore, questo il significato di void che se lo cerchi come vocabolo inglese è letteralmente: indefinito.
float parabola_rett(float,float);
Prototipo della funzione denominata parabola_rett. Essa accetta in ingresso due variabili di tipo float, e restituisce alla fine un valore di tipo float.
struct deform verifica_SLE(struct soll_esterne);
Prototipo della funzione denominata verifica_SLE. Essa accetta in ingresso una variabile di tipo struct (una struct è una struttura dati che al suo interno contiene variabili di tipo più elementare, come float, int, ecc.) in particolare una variabile struct denominata soll_esterne.
La variabile struct soll_esterne deve essere dichiarata prima di protopizzare questa specifica funzione (perchè altrimenti il compilatore, non sapendo di che cosa è fatta la struttura dati soll_esterne, non può 'protopizzare' bene la funzione).
Altra cosa attenzionare bene è che soll_esterne non una vera e propria variabile. Essa a sua volta è il 'prototipo' della struttura dati. In sintesi, un nuovo tipo di dati, come float, int, double, per intenderci. Così come tu dichiari nel tuo listato una variabile:
int pippo;
così dichiarerai:
struct soll_esterne soll;
Ovvero hai creato la struttura dati soll, che ha le caratteristiche del prototipo struct soll_esterne.
Pare complicato, ed in parte lo è. Ma se guardi nel file .h e nel file .cpp troverai tanti esempi che ti consentiranno di capire meglio.
Infine la funzione in oggetto restituisce un valore che è di tipo struct deform (altra struttura dati che deve essere dichiarata prima del prototipo della funzione in oggetto). Anche in questo caso struct deform è il prototipo della struttura dati.
Piccolo inciso. In tutti i linguaggi strutturati alle funzioni possono essere passate un numero qualsiasi di variabili in ingresso, nessuno, 1, 2, 100. Invece in uscita le funzioni prevedono o void (nessuna uscita) o una ed una sola variabile.
Per cui se tu avessi una funzione a cui fornisci in ingresso i lati di un rettangolo, e volessi che in uscita ti desse sia l'area che il perimetro, non potresti farlo. O inserisci in ingresso della funzione un flag (voglio in uscita a*b, oppure voglio in uscita 2*(a+b)), e chiami la funzione due volte, oppure crei due funzioni differenti, specializzate, una per il calcolo dell'area, una per il calcolo del perimetro.
Se però il valore restituito dalla funzione è un 'puntatore', ovvero una posizione in memoria, all'uscita dalla funzione tu avrai la possibilità, sapendo come è strutturata la memoria nei 'dintorni' del puntatore, di avere più informazioni dell'unica variabile che ti viene fornita dalla funzione stessa.
Io con i puntatori non sono mai entrato troppo in confidenza.
Nel caso della restituzione di una variabile di tipo struct, in effetti ti viene restituito di fatto un puntatore (anche se non sembra), il puntatore alla posizione in memoria della struttura stessa. Se la struttura dati ha al suo interno 10 variabili elementari, io all'uscita dalla funzione, mi trovo tutti e 10 i valori che mi servono, in quanto 'incapsulati' all'interno della struttura restituita.
Infine andiamo al prototipo più complicato:
struct geometria_sezione calcola_caratt_geometriche (struct poligono_sezione *);
struct poligono_sezione * cos'è? Un puntatore.
Traducendo, si informa il compilatore che in ingresso non ci sarà una struttura dati di tipo struct poligono_sezione, ma un array (un vettore) di variabili di tipo struct poligono_sezione. Poichè il compilatore conosce la forma di tale struttura (ovvero quanto spazio occupa in memoria ogni variabile di tipo poligono_sezione) è anche in grado di 'saltare' da una variabile struct all'altra. Per cui in fase di chiamata della funzione troverai la riga:
geo=calcola_caratt_geometriche(poli);
Ma prima avevo dichiarato le variabili poli come:
struct poligono_sezione poli[5];
Ovvero un vettore di variabili poli[0], poli[1], ecc. e poli che vedi nella chiamata, cosè? Il puntatore del vettore.
Ovvero io passo alla funzione calcola_caratt_geometriche la locazione in memoria dove è contenuto il primo valore di poli[0].
D'altra parte per determinare le caratteristiche geometriche dell'intera sezione devo sapere tutto dei singoli poligoni che la costituiscono.
Ovviamente, ed è il bello della programmazione strutturata, avrei potuto agire anche in maniera differente. Piuttosto che far ingoiare ad una funzione tutti i poligoni, avrei potuto creare una funzione che agiva sul singolo poligono, restituendomi le caratteristiche geometriche dei singolo poligono, e quindi con una funzione più in 'alto' trattare i singoli risultati per arrivare a quelli della sezione nella sua totalità.
Penso che già così sia anche troppo.