How to improve this code? Simple Question in C

Asked

Viewed 98 times

1

I have a question asking to calculate a due value of each car by parking and print on a tabular exit, ex:

Carro           Horas           Valor
1               2.0             2.0
2               3.0             2.0
3               4.0             2.5

TOTAL           9.0             6.5

I was basically having trouble reading the value of hours and printing on a tabular output the values of car number, hours and value(The error was because reading the hours interfere with tabular output). So, I made this program with the switch structure but I think this is not the best way to solve this problem because I had to create a variable for each thing (time of car 1, time of car 2, value to pay of car 1.... ). Any indication? (OBS, I need the function calculateTaxa, the function Imprimetela is not required. Also I don’t know anything yet about arrays, pointers and so on, only functions).

    #include <stdio.h>
    #include <math.h>
    
    double calcularTaxas(float);
    void ImprimeTela(int, double, double);
    
    int main(){
        double horas, horas1, horas2, a , b, c, totalHoras = 0, totalTaxa = 0;
        for (int cont = 1; cont <=3; ++cont){
            printf("Digite quantas horas cada carro ficou no estacionamento: ");
            scanf("%lf", &horas);
            switch (cont){
                case 1:
                    a = calcularTaxas(horas);
                    horas1 = horas;
                    break;
                case 2:
                    b = calcularTaxas(horas);
                    horas2 = horas;
                    break;
                case 3:
                    c = calcularTaxas(horas); 
                    break;           
                default:
                    break;
                }
        totalHoras = horas + horas1 + horas2;
        totalTaxa = a + b + c;
        }
        for (int cont = 1; cont <= 4; ++cont)
            switch (cont){
                case 1:
                    printf("\n%s\t\t%s\t\t%s\t\t\n","Carro", "Horas", "Valor");
                    ImprimeTela(cont, horas1, a);
                    break;
                case 2:
                    ImprimeTela(cont, horas2, b);
                    break;
                case 3:
                    ImprimeTela(cont, horas, c);
                    break;
                case 4: 
                    ImprimeTela(cont, totalHoras, totalTaxa);
                default:
                    break;
                }         
        return 0;
    }
    // função para calculo do valor a ser pago para cada carro
    double calcularTaxas(float horas){
        float valor;
        if (horas <= 3)
            valor = 2;
        else if (horas >= 20)
            valor = 10;
        else
            valor = 2 + ceil(horas - 3) * 0.5;
        return valor;
    }
    void ImprimeTela(int a, double b, double c){
        if (a == 4)
            printf("\n%s\t\t%.1f\t\t%.1f\t\t\n", "TOTAL", b, c);
        else
            printf("%d\t\t%.1f\t\t%.1f\t\t\n", a, b, c);
    }
  • Think about it: if from now on you needed to register 5 cars you would have to change your code by adding 2 more cases? I don’t think that’s a good solution. After treating each car you just need to print the line referring to it and accumulate the print values of the total at the end of the program.

1 answer

2


Whenever you have variables like algo1, algo2, algo3, etc, is a strong indication that you probably need to use an array. In your case, it seems to be exactly that, because you want to keep a certain amount of hours for different cars. So use an array of double.

By reading the time data, you can already compute the total.

And when printing the hours, you can calculate the rate, because it seems to me that this information is only relevant there (if I needed to save the fees as well, I would create another array, or else I would use one struct containing both information).

Anyway, I’d be like this:

double calcularTaxas(double horas){
    if (horas <= 3)
        return 2;
    if (horas >= 20)
        return 10;
    return 2 + ceil(horas - 3) * 0.5;
}

int main() {
    int qtd = 3;
    double totalHoras = 0, totalTaxas = 0;
    double horas[qtd];

    for (int i = 0; i < qtd; i++) {
        printf("Digite quantas horas o carro %d ficou no estacionamento: ", i + 1);
        scanf("%lf", &horas[i]);
        totalHoras += horas[i];
    }

    printf("%-15s%-15s%s\n", "Carro", "Horas", "Valor");
    for (int i = 0; i < qtd; i++) {
        double taxa = calcularTaxas(horas[i]);
        printf("%-15d%-15.1f%.1f\n", i + 1, horas[i], taxa);
        totalTaxas += taxa;
    }
    printf("\n%-15s%-15.1f%.1f\n", "TOTAL", totalHoras, totalTaxas);

    return 0;
}

I used the formatting options of printf: in the case, %-15s aligns the text to the left, occupying 15 positions (and filling in with spaces), and %-15.1f aligns the number to the left, occupying 15 positions and with a house after the comma.

I also changed the function calcularTaxas, for that variable valor it was not necessary: you can simply return the value depending on each case (and the return closes the execution of the function, eliminating the need for the else). Although it does not validate negative values (is the improvement tip).

And notice how totals are calculated in loops (the totalHoras could also be calculated in the second loop, then it wouldn’t make a difference).

Example of how the output looks:

Carro          Horas          Valor
1              2.0            2.0
2              5.0            3.0
3              25.0           10.0

TOTAL          32.0           15.0

As already said, if you want to keep also the rates along with the hours (not to have to calculate them all the time, for example), an alternative is to group these data into one struct:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

typedef struct {
    double horas;
    double taxa;
} DadosEstacionamento;

double calcularTaxas(double horas){
    if (horas <= 3)
        return 2;
    if (horas >= 20)
        return 10;
    return 2 + ceil(horas - 3) * 0.5;
}

int main() {
    size_t qtd = 3;
    DadosEstacionamento *dados = malloc(qtd * sizeof *dados);
    double totalHoras = 0.0, totalTaxas = 0.0;

    for (int i = 0; i < qtd; i++) {
        printf("Digite quantas horas o carro %d ficou no estacionamento: ", i + 1);
        scanf("%lf", &dados[i].horas);
        dados[i].taxa = calcularTaxas(dados[i].horas);
        totalHoras += dados[i].horas;
        totalTaxas += dados[i].taxa;
    }

    printf("%-15s%-15s%s\n", "Carro", "Horas", "Valor");
    for (int i = 0; i < qtd; i++) {
        printf("%-15d%-15.1f%.1f\n", i + 1, dados[i].horas, dados[i].taxa);
    }
    printf("\n%-15s%-15.1f%.1f\n", "TOTAL", totalHoras, totalTaxas);

    free(dados);

    return 0;
}

The rest is similar to the previous code, the difference is that I calculate the rate right after I read the amount of hours, and already update both totals. Thus in the second loop I just print the data.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.