Faire une calculatrice
- Introduction
- Code source
1. Introduction
Sur ce TP, nous allons voir comment créer une calculatrice en langage C. Notre calculatrice permettra :
- de faire les calculs arithmétiques élémentaires (addition, soustraction, multiplication et division).
- de calculer le produit factoriel, le logarithme népérien, le logarithme à base de 10, le carré, l’exponentielle,
l’inverse, le pourcentage et la racine carrée d’un nombre.
- de faire quelques calculs trigonométriques
- de convertir des euros en francs comoriens
Le but de ce TP n’est pas seulement de créer une calculatrice mais surtout de mettre en pratique certaines
notions que nous avons vues dès le premier cours de langage C jusqu’ici.
Et pour fermer l’introduction, voici une capture de ce que nous allons faire:

2. Code source
Le code source n’est constitué que de certaines notions déjà vues sur ce site. Ce qui sous-entend qu’il n’est
pas nécessaire de perdre du temps à faire des explications. Mais bon, dans le code même, j’ai laissé pas mal
d’explications sous forme des commentaires.
Code :
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include <ctype.h>
- #include <gtk/gtk.h>
-
- static float a = 0;
- static char derncar = (char) 0;
- static char prev = (char) 0;
- #define BUF_SIZE 88
-
-
-
-
-
- typedef struct {
-
- char *Labeldubouton;
- int ligne;
- int colonne;
- GtkWidget *bouton;
-
- } TypedeBouton;
-
-
-
-
-
- TypedeBouton ListedesBoutons [] = {
-
-
-
-
-
-
-
-
-
-
- {"C", 1, 0, NULL},
- {"7", 2, 0, NULL},
- {"4", 3, 0, NULL},
- {"1", 4, 0, NULL},
- {"+/-", 5, 0, NULL},
-
-
-
- {"CE", 1, 1, NULL},
- {"8", 2, 1, NULL},
- {"5", 3, 1, NULL},
- {"2", 4, 1, NULL},
- {"0", 5, 1, NULL},
-
-
- {"eur/kmf", 1, 2, NULL},
- {"9", 2, 2, NULL},
- {"6", 3, 2, NULL},
- {"3", 4, 2, NULL},
- {".", 5, 2, NULL},
-
-
-
- {"/", 1, 3, NULL},
- {"*", 2, 3, NULL},
- {"-", 3, 3, NULL},
- {"+", 4, 3, NULL},
- {"=", 5, 3, NULL},
-
-
- {"%", 1, 4, NULL},
- {"Rac", 2, 4, NULL},
- {"1/x", 3, 4, NULL},
- {"x^2", 4, 4, NULL},
- {"x!", 5, 4, NULL},
-
- {"asin", 1, 5, NULL},
- {"acos", 2, 5, NULL},
- {"atan", 3, 5, NULL},
- {"exp", 4, 5, NULL},
- {"ln", 5, 5, NULL},
-
- {"sin", 1, 6, NULL},
- {"cos", 2, 6, NULL},
- {"tan", 3, 6, NULL},
- {"pi", 4, 6, NULL},
- {"log10", 5, 6, NULL},
-
- };
-
-
-
-
- int nButtons = sizeof (ListedesBoutons) /
- sizeof (TypedeBouton);
-
-
- GtkWidget *label;
- GtkWidget *zoneresultat;
-
-
-
-
- gint FermerApp (GtkWidget *bouton, gpointer data)
- {
- gtk_main_quit ();
-
- return (FALSE);
- }
-
-
-
-
-
-
- void GestiondesZerosSansSens (char *ChiffreZero)
- {
- int nIndex;
- int bDecimal = FALSE;
- int nPos = -1;
-
-
- for (nIndex = 0; nIndex < strlen (ChiffreZero); nIndex++) {
-
-
- if (ChiffreZero[nIndex] == '.') {
- bDecimal = TRUE;
- }
-
-
-
-
- if (bDecimal) {
-
-
- if (ChiffreZero[nIndex] == '0') {
- if (nPos < 0) {
- nPos = nIndex;
- }
- } else {
- nPos = -1;
- }
- }
- }
- if (nPos > 0) {
- ChiffreZero[nPos] = (char) 0;
- }
- }
-
-
-
-
-
-
-
- void CouperlesZeros (char *ChiffreZero)
- {
- int nPos;
- if (ChiffreZero == NULL) return;
- for (nPos = 0; (ChiffreZero[nPos] && ChiffreZero[nPos] == '0'); nPos++) {
- if (isdigit (ChiffreZero[nPos+1])) {
- ChiffreZero[nPos] = ' ';
- }
- }
- }
-
-
-
-
-
- int Command (char op)
- {
- switch (op) {
- case '+':
- case '-':
- case '/':
- case '*':
- case '=':
- return (TRUE);
- }
- return (FALSE);
- }
-
- int FloatingPointChar (char op)
- {
-
- return (isdigit (op) || op == '.');
- }
-
-
-
-
-
- void key_press (GtkWidget *bouton,
- GdkEventKey *event,
- gpointer data)
- {
- int nIndex;
-
-
- for (nIndex = 0; nIndex < nButtons; nIndex++) {
-
-
-
- if (event->keyval == ListedesBoutons[nIndex].Labeldubouton[0] &&
- ListedesBoutons[nIndex].Labeldubouton[1] == (char) 0) {
-
-
- gtk_widget_grab_focus (ListedesBoutons[nIndex].bouton);
-
- gtk_button_clicked (GTK_BUTTON (ListedesBoutons[nIndex].bouton));
- return;
- }
- }
- }
-
-
-
-
-
- void HandleDigit (char *str, char op)
- {
- char *labelText;
- char buffer[BUF_SIZE];
- int len;
-
-
- if (Command (derncar)) {
-
-
- gtk_label_set (GTK_LABEL (label), "");
- if (derncar == '=') {
-
- derncar = (char) 0;
- prev = (char) 0;
- }
- }
-
- gtk_label_get (GTK_LABEL (label), &labelText);
- strcpy (buffer, labelText);
- len = strlen (buffer);
- buffer[len] = (gchar) op;
- buffer[len+1] = (gchar) 0;
-
- CouperlesZeros (buffer);
-
-
- gtk_label_set (GTK_LABEL (label), (char *) buffer);
- gtk_entry_set_text (GTK_ENTRY(zoneresultat), buffer);
-
- }
-
-
-
-
-
- void OperationsNonArthmetiqueElementaire (char *str)
- {
- char *labelText;
- char buffer[BUF_SIZE];
- float b;
-
-
- gtk_label_get (GTK_LABEL (label), &labelText);
- b = atof (labelText);
-
-
- if (strcmp (str, "%") == 0) {
- b = b / 100;
-
-
- } else if (strcmp (str, "1/x") == 0) {
-
-
- if (b == 0) {
-
- return;
- }
- b = 1 / b;
-
-
- } else if (strcmp (str, "Rac") == 0) {
- b = sqrt ((double) b);
-
-
- }
- else if (strcmp (str, "x^2") == 0) {
- b = b * b;
- }
-
- else if (strcmp (str, "pi") == 0) {
- b = 3.14159265359;
-
-
- }
- else if (strcmp (str, "exp") == 0) {
- b = exp ((double) b);
- }
-
- else if (strcmp (str, "cos") == 0) {
- b = cos ((double) b*3.14159 / 180.0);
- }
-
- else if (strcmp (str, "sin") == 0) {
- b = sin ((double) b*3.14159 / 180.0);
- }
-
- else if (strcmp (str, "asin") == 0) {
- b = asin ((double) b* 180.0 /3.14159);
- }
-
- else if (strcmp (str, "acos") == 0) {
- b = acos ((double) b* 180.0 /3.14159);
- }
-
- else if (strcmp (str, "tan") == 0) {
- b = tan ((double) b*3.14159 / 180.0);
- }
-
- else if (strcmp (str, "atan") == 0) {
- b = atan ((double) b* 180.0 /3.14159);
- }
-
- else if (strcmp (str, "ln") == 0) {
- b = log ((double) b);
- }
-
- else if (strcmp (str, "log10") == 0) {
- b = log10 ((double) b);
- }
-
- else if (strcmp (str, "x!") == 0) {
- int i = b-1;
- while (i > 1)
- {
- b = b * i;
- --i;
- }
- b = b;
- }
-
-
- else if (strcmp (str, "eur/kmf") == 0) {
- b=b*491.968;
- }
-
-
- sprintf (buffer, "%f", (float) b);
- GestiondesZerosSansSens (buffer);
- CouperlesZeros (buffer);
- gtk_label_set (GTK_LABEL (label), buffer);
-
-
-
- }
-
-
- void OperationArthmetiqueElementaire ()
- {
- char buffer[BUF_SIZE];
- char *labelText;
- float b;
-
-
- gtk_label_get (GTK_LABEL (label), &labelText);
- b = atof (labelText);
-
- switch (prev) {
- case '+':
- a = a + b;
- break;
-
- case '-':
- a = a - b;
- break;
-
- case '*':
- a = a * b;
- break;
-
- case '/':
- a = a / b;
- break;
-
- case '=':
- a = b;
- break;
-
- default:
- a = b;
- break;
- }
-
-
- sprintf (buffer, "%f", (float) a);
- GestiondesZerosSansSens (buffer);
- CouperlesZeros (buffer);
- gtk_label_set (GTK_LABEL (label), buffer);
- gtk_entry_set_text (GTK_ENTRY(zoneresultat), buffer);
-
-
- }
-
-
-
- void bouton_clicque (GtkWidget *bouton, gpointer data)
- {
- char op = *((char *) data);
- char *str;
-
-
- str = (char *) data;
-
-
- if (FloatingPointChar (op) && strlen (str) == 1) {
-
- HandleDigit (str, op);
-
- } else {
-
-
- if (strcmp (str, "CE") == 0) {
- gtk_label_set (GTK_LABEL (label), "0");
- gtk_entry_set_text (GTK_ENTRY(zoneresultat), "0");
- return;
-
-
- } else if (strcmp (str, "C") == 0) {
- prev = (char) 0;
- derncar = (char) 0;
- gtk_label_set (GTK_LABEL (label), "0");
- gtk_entry_set_text (GTK_ENTRY(zoneresultat), "0");
- return;
-
- } else {
-
-
- OperationsNonArthmetiqueElementaire (str);
- }
-
-
- OperationArthmetiqueElementaire ();
-
- prev = op;
- }
- derncar = op;
- }
-
-
-
-
- GtkWidget *CreateButton (GtkWidget *table, char *Labeldubouton, int ligne, int colonneumn)
- {
- GtkWidget *bouton;
-
-
- bouton = gtk_button_new_with_label (Labeldubouton);
-
-
- gtk_signal_connect (GTK_OBJECT (bouton), "clicked",
- GTK_SIGNAL_FUNC (bouton_clicque), Labeldubouton);
-
-
- gtk_table_attach (GTK_TABLE (table), bouton,
- colonneumn, colonneumn+1,
- ligne, ligne + 1,
- GTK_FILL | GTK_EXPAND,
- GTK_FILL | GTK_EXPAND,
- 5, 7);
-
-
- gtk_widget_show (bouton);
-
-
- return (bouton);
- }
-
-
-
-
-
-
- void CreerlesBoutonsduCalculatrice (GtkWidget *table)
- {
- int nIndex;
-
-
- for (nIndex = 0; nIndex < nButtons; nIndex++) {
-
-
- ListedesBoutons[nIndex].bouton =
- CreateButton (table,
- ListedesBoutons[nIndex].Labeldubouton,
- ListedesBoutons[nIndex].ligne,
- ListedesBoutons[nIndex].colonne);
- }
- }
-
-
-
-
-
- int main (int argc, char *argv[])
- {
- GtkWidget *mafenetre;
- GtkWidget *table;
-
- gtk_init (&argc, &argv);
-
-
- mafenetre = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
-
- gtk_window_set_title (GTK_WINDOW (mafenetre), "Samomoi calculatrice");
-
-
- gtk_widget_set_usize (mafenetre, 390, 280);
-
- gtk_window_set_icon_from_file(GTK_WINDOW(mafenetre), "icone.gif", NULL);
-
-
- gtk_signal_connect (GTK_OBJECT (mafenetre), "key_press_event",
- GTK_SIGNAL_FUNC (key_press), NULL);
- gtk_signal_connect (GTK_OBJECT (mafenetre), "delete_event",
- GTK_SIGNAL_FUNC (FermerApp), NULL);
- table = gtk_table_new (5, 7, TRUE);
- CreerlesBoutonsduCalculatrice (table);
- label = gtk_label_new ("0");
- zoneresultat= gtk_entry_new();
- gtk_entry_set_text (GTK_ENTRY(zoneresultat), "0");
- gtk_table_attach_defaults (GTK_TABLE (table), zoneresultat, 0, 4, 0, 1);
- gtk_container_add (GTK_CONTAINER (mafenetre), table);
- gtk_widget_show_all (mafenetre);
-
-
- gtk_main ();
- return (0);
- }