[C]Gestione di un garage(con struttura)

frab1
Buondi',
sto cercando di capire queste maledette strutture in C, sbattendo,non poco, la testa contro il muro..
Ho il dato quesito:
"Un garage addebita $ 2£ $ per un parcheggio fino a $3$ ore. Addebita un'addizionale di $ 0.5£ $ per ogni ora o frazione di essa che ecceda le tre di base. Il massimo dell'addebito è di $ 10£ $ per $24$ ore di parcheggio.(Assunto che nessuno possa parcheggiare oltre le $24$ ore.
Dati 3 clienti, e forniti da tastiera il numero di ore di parcheggio per ogni cliente, scrivere una funz "calcolaAddebito()" che calcoli l'addebito per ognuno. Stampare a video una tabella che contenga :"

CLIENTE ORE ADDEBITO
1 1.5 2.00
2 4.0 2.5
3 24.0 10.00

Ecco come ho provato a scrivere il programma:
#include <stdio.h>

struct garage{
	int Cliente;
	float Ore;
	double Addebito;
}; 

double calcolaAddebito(float cl.Ore);
int main(void)
{
	int i=1;
	struct garage cl;
	for(i=1;i<=3;i++) {
		cl.Cliente=i;
	}
	i=0;
	printf("Inserire le ore di parcheggio per ogni cliente:\n");
	for(i=0;i<4;i++) {
		scanf("%f ",&cl.Ore);
	}
	calcolaAddebito(cl.Ore);

	printf("-------------------------------------------------\n");

	printf("-------------------------------------------------\n");
	
}

double calcolaAddebito(float cl.Ore)
{
	struct garage cl;
	float i=0;
	if (Ore<=3.0) {
		cl.Addebito=2.0;
	}
	else if (Ore == 24.0) {
		cl.Addebito=10.0;
	}
	else {	
		cl.Addebito=3.0;
		for(i=3.0;i<=Ore;) {
			cl.Addebito=+0.5;
		}
	}
}


PRIMI PROBLEMI RISCONTRATI:
-non mi lascia dichiarare la prototipizzazione e la funzione con il "cl.Ore"
-Legge le ore all'infinito

Qualcuno ha qualche suggerimento per mettermi sulla giusta strada? Gazie :cry:

Risposte
vict85
Ripassati il passaggio di parametri ad una funzione e al loro significato. Il problema non è nelle strutture. Comunque avrebbe avuto più senso che avessi passato a funzione un reference o un puntatore alla struttura invece che ad un suo elemento.

frab1
per una funzione c'è bisogno:
-PROTIPO
-CHIAMATA nel main(tra parentesi metto le variabili da passarle);
-DICHIARAZIONE fuori main( dichiarando il tipo restituito e il tipo di dato del parametro);

ora con la struttura non saprei proprio da che parte prenderlo...

il puntatore alla struttura lo posso dichiarare cosi giusto?
struct garage *ptr;


fatto questo ho riscritto il main con il puntatore:
int main(void)
{
	struct garage *ptr;
	int i=0;
	struct garage cl;
	ptr=&cl;
	for(i=0;i<2;i++) {
		ptr->Cliente=i;
	}
	i=0;
	printf("Inserire le ore di parcheggio per ogni cliente:\n");
	for(i=0;i<4;i++) {
		scanf("%f ",&ptr->Ore);
	}
	//calcolaAddebito(cl.Ore);

	printf("-------------------------------------------------\n");

	printf("-------------------------------------------------\n");
	
}


Ma mi legge ancora 5 valori invece di 3 :?: :?: :!: :roll:
Per la funzione non riesco a uscirne..

vict85
In realtà intendevo dire usare il seguente prototipo
void calcolaAddebito(struct garage *pgr);

con la solita chiamata
calcolaAddebito(&cl);



Quello che ti sei perso della teoria sulle chiamate di funzioni è che ciò che sta tra parentesi è una dichiarazione di variabili. Tu stai dichiarando delle nuove variabili locali che assumeranno i valori che gli stai passando.

Supponi per esempio di avere la banalissima funzione
double somma(int a, int b)
{
  return a + b;
}

e la chiamata
/* parte prima della chiamata*/
res = somma(num1, num2);
/* parte dopo la chiamata*/

allora la chiamata è, in un certo senso, equivalente al seguente codice:
/* parte prima della chiamata*/
{
  int a = num1;
  int b = num2;
  res = a + b;
}
/* parte dopo la chiamata*/

dove le parentesi graffe non sono opzionali perché a e b sono definite solo in quel blocco.

Capisci quindi che int cl.Ore non è una buona dichiarazione di variabili.

frab1
"vict85":

Supponi per esempio di avere la banalissima funzione
double somma(int a, int b)
{
  return a + b;
}

e la chiamata
/* parte prima della chiamata*/
res = somma(num1, num2);
/* parte dopo la chiamata*/

allora la chiamata è, in un certo senso, equivalente al seguente codice:
/* parte prima della chiamata*/
{
  int a = num1;
  int b = num2;
  res = a + b;
}
/* parte dopo la chiamata*/

dove le parentesi graffe non sono opzionali perché a e b sono definite solo in quel blocco.

Questa parte si, mi è chiara.

"vict85":
In realtà intendevo dire usare il seguente prototipo
void calcolaAddebito(struct garage *pgr);

con la solita chiamata
calcolaAddebito(&cl);


Quello che ti sei perso della teoria sulle chiamate di funzioni è che ciò che sta tra parentesi è una dichiarazione di variabili. Tu stai dichiarando delle nuove variabili locali che assumeranno i valori che gli stai passando.

Questa non molto. Come argomento gli passo il puntatore alla struttura, perche' devo scriverci dentro giusto?
la porzione di codice:
int a = num1;

si puo'dire che equivalga nel "mondo dei puntatori" al codice:
ptr=&cl;
??

PS:Ora riscritto come mi hai suggerito, ho sempre il problema dell'acquisizione del numero di ore..Cicla 5 volte invece di 3.. :roll: :roll:
#include <stdio.h>

struct garage{
	int Cliente;
	float Ore;
	double Addebito;
}; 

void calcolaAddebito(struct garage *ptr);
int main(void)
{
	struct garage *ptr;
	int i=0;
	struct garage cl;
	ptr=&cl;
	for(i=0;i<2;i++) {
		ptr->Cliente=i;
	}
	i=0;
	printf("Inserire le ore di parcheggio per ogni cliente:\n");
	for(i=0;i<4;i++) {
		scanf("%f ",&ptr->Ore);
	}
	calcolaAddebito( &cl);

	printf("-------------------------------------------------\n");

	printf("-------------------------------------------------\n");
	
}

void calcolaAddebito(struct garage *ptr)
{
	float i=0;
	if (ptr->Ore<=3.0) {
		ptr->Addebito=2.0;
	}
	else if (ptr->Ore == 24.0) {
		ptr->Addebito=10.0;
	}
	else {	
		ptr->Addebito=3.0;
		for(i=3.0;i<=ptr->Ore;) {
			ptr->Addebito=+0.5;
		}
	}
}


vict85
No, stai mescolando cose. Il puntatore è necessario solo nella funzione per poter scrivere sulla struttura definita altrove. Inoltre non capisco i for nella lettura, dato che possiedi una sola struttura e leggi 2 volte il cliente e 4 volte le ore, e ogni volta riscrivi la stessa identica struttura contenendo alla fine solo il secondo cliente e la quarta ora. Inoltre calcoli il risultato ma non lo mostri. C'è inoltre un i=0; di troppo.

frab1
eh infatti non capisco molto bene...
ad esempio per memorizzare i campi relativi a 3 clienti, devo crearmi 3 variabili di questo tipo?
struct garage cl1;
        struct garage cl2;
       struct garage cl3;

vict85
Puoi anche creare un array di strutture. Si fa come per le altre variabili.

frab1
e il tipo dell'array?

come potrei dichiarare l'array?

ora sono in piena confusione :-(

Dante.utopia
#include <stdio.h>

struct garage{
   int Cliente;
   float Ore;
   double Addebito;
}; 

double calcolaAddebito(float);

int main(void)
{
	int i;
   	float ore; //variabile di supporto
   	struct garage cl[3];  //array constante 3 elementi con indice da 0 a 2 (Occhio alle tane dei piccioni!)

   	printf("-------------------------------------------------\n");

        //scorriamo l'array e assegniamo al campo Cliente della struttura i valori:
                                                       //quando i = 0, cl[i].Cliente = 1
                                                       //quando i = 1, cl[i].Cliente = 2
	for(i=0;i<3;i++)
   		cl[i].Cliente = i+1;

	for( i=0; i<3; i++) {
   		printf("Inserire le ore di parcheggio del cliente %d: ", cl[i].Cliente);
   		scanf("%f", &ore);
		cl[i].Ore = (float) ore;
	}

	for( i=0; i<3; i++)
   		cl[i].Addebito = calcolaAddebito(cl[i].Ore);

	for( i=0; i<3; i++)
   		printf("%d\t%f\t%f\n",cl[i].Cliente,cl[i].Ore, cl[i].Addebito);

   printf("-------------------------------------------------\n");

}

double calcolaAddebito(float ore)
{
   double addebito;
   /*
    codice per il calcolo dell'addebito
 */
    //calcoliamo l'addebito in funzione delle ore e ne restituiamo il valore
   return addebito;
}

frab1
GRAZIE a Dante.Utopia, e al file che mi ha passato gentilmente nell'altro post, ho rivisto da cima a fondo il mio programma e ho potuto comprendere un bel po di cose sulle strutture...scrivendo un sorgente funzionante.
Grazie a anche a VIC come sempre!
Da oggi le strutture sono un pelo piu chiare.. :D

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.