Ouvrir un terminal sous linux.
# Création d un répertoire de travail
$ mkdir langage_c
$ cd langage_c
|
BASH TERMINAL
|
Afin de rendre la compilation plus simple, un makefile permet d’effectuer la compilation, puis l’édition de lien ( placement mémoire ).
Dès lors qu’un fichier makefile est présent dans un répertoire, la commande make exécute ce fichier.
|
BASH TERMINAL
|
Les exemples ci-dessous pourront être testés avec les 2 environnements suivants :
L’option “-g” dans gcc permet de compiler un programme avec possibilité de debug.
( installation : cf installations )
$ dbg first_prog
Comme nous allons par la suite utiliser STM32CubeIDE , basé sur eclipse, nous pouvons également utiliser ce logiciel pour compiler et tester du code en natif ( sur PC ).
Chargement d’un projet :
Dans les exemples ci-dessous, après avoir récupéré et extrait le dossier compressé (.zip), décompresser le fichier.
Lancer stm32cubeide :
$ stm32cubeide
sélectionner le répertoire WORKSPACE*
L’arborescence du projet est alors visible :
Pour compiler : CTRL+B
Si la compilation s’effectue sans erreur, un exécutable est généré ( prog_base )
Pour tester ( debuggage ), basculer dans l’environnement debug :
Sélectionner la configuration de debug :
Le programme est alors chargé, pour :
Pour visualiser les variables, on peut utiliser soit la fenêtre Variables ( Window -> Show View -> Variables ) ou Watch Expression ( Window -> Show View -> Watch Expression )
Les printf s’affichent dans la fenêtre Console
La variable a contenant la donnée 5 est située à l’adresse
0x20000000.
Pour désigner l’adresse d’une variable, on utilise le symbole & ( &a).
Au cours de l’exécution d’un programme, le processeur effectue des calculs.
Ces calculs sont réalisés avec des variables.
En langage C il faut être précis sur les types utilisés.
Dans un premier temps nous allons retenir les types suivants :
Les Conditions
|
|
Les Boucles
|
|
|
|
Q. Compléter la fonction main afin de faire deviner le nombre nbMyst tiré aléatoirement, selon l’algorithme suivant :
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
#define MIN 1
//======================================================================
int main()
{
int nbMyst = 0, nbSaisi =0;
srand(time(NULL));
int random = rand();
nbMyst = ( random % ( MAX-MIN+1) ) + MIN;
printf( "nombre ? \n");
scanf("%d", &nbSaisi ); // saisie du nombre dans la console, dans la variable nbSaisi
/****************************
* A COMPLETER *
****************************/
}
//======================================================================
REMARQUE : La fonction printf est une fonction de haut niveau permettant d’afficher un message dans la console.
printf("j'afficher un message\n\r");
printf("j'affiche un entier : %d", variable_int);
printf("j'affiche un nombre réel : %f", variable_f);
Plutôt que de tout mettre dans la fonction main(), nous pouvons organiser notre code sous forme de fonctions
Q. Compléter le programme suivant afin de pouvoir calculer le diamètre, le périmètre et l’aire d’un cercle dont on a saisi le rayon.
REMARQUE : nous aurons besoin de la constante M_PI et de la fonction pow() présentes dans la bibliothèque math.
Il est donc nécessaire de modifier le makefile en conséquence.
#include <stdio.h>
//======================================================================
float calc_aire(float rayon)
{
/* A COMPLETER */
}
float calc_perimetre(float rayon)
{
/* A COMPLETER */
}
float calc_diametre(float rayon)
{
/* A COMPLETER */
}
//======================================================================
int main()
{
float r;
printf("rayon =");
scanf("%f", &r);
printf("diametre = %f, perimetre = %f, aire = %f \n", calc_diametre(r), calc_perimetre(r), calc_aire(r));
return 0;
}
//======================================================================
Je veux modifier le contenu d’une case mémoire dans une fonction :
|
BASH TERMINAL
|
Conclusion : Le résultat du calcul a été affecté à un registre, la case mémoire notée ‘a’ n’a pas été modifiée.
Il faut transmettre l’adresse à la fonction, et non la valeur de la variable.
|
BASH TERMINAL
|
Q. Compléter la fonction cutTime permettant de mettre à jour les variables hours, minutes et seconds, de telle sorte que :
REMARQUE : La fonction modulo % permet de calculer le reste de la division entière.
Ex :
45%60=45
62%60=2
Dans une boucle : i=(i+1)%5 –> i vaut successivement 0,1,2,3,4,0,1,2,3,4,…
#include <stdio.h>
#include <stdlib.h>
//======================================================================
void cutTime()
{
/********************
* A COMPLETER *
********************/
}
//======================================================================
int main()
{
int hours = 0;
int minutes = 1000;
int seconds = 50000;
cutTime( /* A COMPLETER */ );
printf("%d:%d:%d \n", hours, minutes,seconds);
}
//======================================================================
Le nom du tableau correspond à l’adresse du premier élément du tableau.
|
BASH TERMINAL
|
Q. Compléter les fonctions calc_min, calc_max et calc_average.
#include <stdio.h>
#define N 10
//======================================================================
int calc_min(int* tableau, int size_tab)
{
/******************
* A COMPLETER *
*****************/
}
//======================================================================
int calc_max(int* tableau, int size_tab)
{
/******************
* A COMPLETER *
*****************/
}
//======================================================================
int calc_average(int* tableau, int size_tab)
{
/******************
* A COMPLETER *
*****************/
}
//======================================================================
int main()
{
int min, max, average = 0;
int tab[N]={1,5,-10,2,3,25,7,8,-2,0};
min = calc_min(tab, N);
max = calc_max(tab, N);
average = calc_average(tab, N);
printf("min=%d, max=%d, average=%d \n", min, max, average);
return 0;
}
Représentation d’une chaine de caractères dans un processeur : le code ASCII
Comme toute donnée dans un système à processeurs, les caractères sont codés avec des 0 et des 1.
EXEMPLES:
Affichage du résultat d’un calcul
Q. Compléter la fonction conv_int_str permettant de transformer un résultat entier ( inférieur à 100) en chaine de 2 caractères.
#include <stdio.h>
#include <stdlib.h>
//======================================================================
int conv_int_str(int data, char* str_res)
{
/************************
* A COMPLETER *
************************/
return 0;
}
//======================================================================
int main()
{
char buffer[50] = "25+22= ";
char str_res[3];
int res=25+22;
buffer[6]=res;
printf("avec printf, ça marche : 25+22= %d \n", res);
//--------------------------------------
printf("problème : le résultat d'un calcul n'est pas une chaine de caractères : \n");
printf("%s \n", buffer);
//--------------------------------------
printf("Resultat de la conversion 'à la main' : \n");
conv_int_str(res, str_res);
buffer[6]=str_res[0];
buffer[7]=str_res[1];
printf("%s \n", buffer);
//--------------------------------------
printf("Utilisation de sprintf : \n");
sprintf(buffer,"%d+%d=%d \n", 85,2,87);
printf("%s \n", buffer);
return 0;
}
//======================================================================
Login / Password
Considérons à titre d’exemple le programme login.c permettant de tester un login et un mot de passe :
REM : la fonction strcmp permet de comparer 2 chaînes de caractère.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char login[40];
char password[40];
printf( "Please, enter your login: " );
scanf( "%s", login );
printf( "Enter your password: " );
scanf( "%s", password );
if ( strcmp( login, "admin" ) == 0 && strcmp( password, "mdp" ) == 0 ) {
printf( "You are connected\n" );
} else {
printf( "Login failed. Retry later.\n" );
}
return 0;
}
Convertisseur de Monnaie
Q. Compléter le programme suivant permettant de convertir un montant d’une monnaie à une autre.
#include <stdio.h>
#include <stdlib.h>
// TAUX DE CHANGE
#define EUR_USD 1.09282
#define EUR_GBP 0.844684
#define USD_EUR 0.915092
#define USD_GBP 0.772992
#define GBP_EUR 1.18383
#define GBP_USD 1.29367
//======================================================================
//======================================================================
int main()
{
char monnaie_source[4];
char monnaie_cible[4];
float montant = 0.0;
int source = 0, cible = 0;
printf( "monnaie_source ( EUR / USD / GBP ) ? \n");
scanf("%s", monnaie_source );
printf( "monnaie_cible ( EUR / USD / GBP ) ? \n");
scanf("%s", monnaie_cible );
printf( "montant ? \n");
scanf("%f", &montant );
/*************************
A COMPLETER
************************/
}
//======================================================================
|
|
|
|
Q. Compléter le fichier main.c permettant de calculer la moyenne de 3 étudiants à partir de 3 notes.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//======================================================================
struct carnet_TypeStruct
{
char nom[20];
float note[3] ;
float moyenne;
};
//======================================================================
int calc_average( float *tab, float N, float *result)
{
float acc=0;
for( int i=0 ; i < N ; i++)
{
acc = acc + tab[i];
}
*result = acc / N;
return 0;
}
//======================================================================
int main()
{
struct carnet_TypeStruct pers_1, pers_2, pers_3;
sprintf(pers_1.nom,"roger");
pers_1.note[0]= 15.5;
pers_1.note[1]= 18.5;
pers_1.note[2]= 5.5;
sprintf(pers_2.nom,"marcel");
pers_2.note[0]= 12.5;
pers_2.note[1]= 13.0;
pers_2.note[2]= 11.5;
sprintf(pers_3.nom,"pierre");
pers_3.note[0]= 2.5;
pers_3.note[1]= 5.5;
pers_3.note[2]= 10.0;
calc_average( /* A COMPLETER */ ) ;
printf( "Moyenne de %s = %f \n", /* A COMPLETER */ );
calc_average( /* A COMPLETER */) ;
printf( "Moyenne de %s = %f \n", /* A COMPLETER */ );
calc_average( /* A COMPLETER */) ;
printf( "Moyenne de %s = %f \n", /* A COMPLETER */ );
}
//======================================================================
PORTEE : Endroit dans le code où une variable peut être utilisée.
DUREE D’EXISTENCE : la valeur de ma variable est-elle conservée si je sors d’une fonction ?
ma_fonction()
{
int a = 0;
}
int a = 0;
ma_fonction()
{
}
Si l’on souhaite retrouver la valeur modifiée de notre variable quand on retourne dans une fonction :
ma_fonction()
{
static int a = 0;
}
Quand une variable globale est déclarée et initialisée dans un fichier, mais qu’on veut l’utiliser dans un autre fichier :
extern int a;