Champ Valeur
Auteur·e Élise
Édition 2024-01-11
Durée 1 session
Taille des équipes 1 personne
Rendu N/A

Préambule

La session à commencé par des explications et de démonstrations au tableau sur les notions suivantes :

  • Le terminal, le shell et les commandes de base sur Linux
  • Qu’est-ce qu’un langage de programmation, la différence entre le haut et le bas niveau
  • L’éditeur de code emacs
    • Création ou ouverture de fichier avec emacs nom_fichier
    • sauvegarde C-x C-s
    • quitter C-x C-c
    • ne pas essayer de C-z car ça ne permet pas d’annuler
  • Un programme minimum viable en C, la fonction main, l’appel d’une fonction, l’utilisation d’un literal
#include <stdio.h>

int main(void)
{
	puts("hey there");
}

Compilation et exécution du programme :

$ gcc main.c
$ ./a.out
hey there

I. Premiers programmes et caractères

I.1. Ressource: afficher un caractère

La fonction putchar prend un argument, un caractère. Elle est capable d’afficher une seule lettre ou caractère à la fois. Un caractère littéral s’exprime entre apostrophes: exemple 'a'. On parle de single quotes. Les guillemets, double quotes sont réservés aux chaînes de caractères. putchar ne fonctionne pas avec des chaînes de caractères. Seulement avec des caractères seuls.

Pour se servir de putchar, il faut include stdio.h.

Exemple d’utilisation de putchar, avec seulement des littéraux. Notez que l’on peut afficher un retour à la ligne avec le caractère '\n'.

#include <stdio.h>

int main(void)
{
	putchar('a');
	putchar('b');
	putchar('c');
	putchar('\n');
}

Nous ne sommes pas obligés de passer des littéraux en argument à putchar. On peut tout aussi bien lui passer une variable de type char.

#include <stdio.h>

int main(void)
{
	char letter;

	letter = 'd';
	putchar(letter);
	putchar(letter + 1);
	putchar(letter + 2);
	putchar('\n');
}

I.2. Exercice: print_b

Fichier à rendre : print_b.c

Fonction·s autorisée·s : putchar de stdio.h

Écrivez un programme qui écrit la lettre b suivi d’un retour à la ligne sur la sortie standard. Dans votre fonction main utilisez putchar pour afficher la lettre et le retour à la ligne.

Base pour voir fichier :

#include <stdio.h>

int main(void)
{
	// votre code ici
	return (0);
}

I.3. Exercice: print_digits

Fichier à rendre : print_digits.c

Fonction·s autorisée·s : putchar de stdio.h

Écrivez un programme qui écrit tous les chiffres de 0 à 9 sur la sortie standard suivi d’un retour à la ligne.

Exemple de test :

$ gcc print_digits.c
$ ./a.out
0123456789
$ 

II. Conditions et fonctions

II.1. Resource: conditions

II.1.a. Le mot clé if

Lorsque l’on souhaite que du code ne s’exécute que dans certains cas, on utilise une condition. La syntaxe d’un if n’est pas très compliquée :

  • le mot clé “if
  • une expression entre parenthèses
    • quand l’expression vaut 0 la condition ne passe pas
    • quand l’expression vaut autre chose que 0, la condition passe
  • le corps entre accolades (il s’agit du code à exécuter dans le cas où la condition passe)
int is_mult_of_5(int num)
{
	if (num % 5 == 0) {
		return (1);
	} else {
		return (0);
	}
}

II.1.b. Opérateurs de comparaison

Dans vos conditions, les opérateurs suivants peuvent vous aider.

Notez bien que l’opérateur d’assignation = et l’opérateur d’égalité == sont différents et ont un comportement différent. = permet de mettre une valeur dans une variable, pas de vérifier une égalité.

Opérateur Description
== est égal à
!= est différent de
< inférieur à
<= inférieur ou égal à
> supérieur à
>= supérieur ou égal à

II.2. Resource: fonctions

Une fonction c’est un morceau de code auquel on donne un nom, qui peut admettre des paramètres et qui peut renvoyer une valeur. Un paramètre, c’est une sorte de variable dont la valeur est injectée à chaque fois qu’on appelle une fonction.

Appeler une fonction permet d’exécuter le morceau de code qu’elle contient, tout en précisant les valeurs qu’elle doit prendre en paramètre, on dit qu’on argumente l’appel de fonction.

Vous avez déjà vu un appel de fonction avec un argument avec :

putchar('a');
putchar('\n');

Dans cet extrait, on exécute deux fois le code de putchar avec à chaque fois un argument différent. Un caractère différent à afficher.

Si on veut pouvoir appeler une fonction de notre propre création, on doit la déclarer. La syntaxe de déclaration d’une fonction est la suivante :

  • le type de la valeur que renvoie la fonction (ou void si elle ne renvoie rien) ,
  • la nom de la fonction ; et
  • les paramètres qu’admet la fonction entre parenthèses.

Exemple de fonction et son appel :

int double_it(int to_double)
{
	return to_double * 2;
}

int main(void)
{
	int nb;

	nb = double_it(4);
	if (nb != 8) {
		puts("that's not okay! Should be 8.");
		return (1);
	}
	nb = double_it(nb);
	if (nb != 16) {
		puts("that's not okay! Should be 16.");
		return (1);
	}
	return (0);
}

Pour renvoyer une valeur et/ou pour arrêter l’exécution d’une fonction on utilise le mot clé return. La valeur renvoyée dans double_it peut être récupérée dans la fonction appelante – celle qui fait l’appel.

Ainsi, lorsque dans le main on arrive sur la ligne nb = double_it(4):

  • on entre dans la fonction double_it avec to_double qui vaut 44:
    • elle fait to_double * 2,
    • ce qui revient à faire 424*2 qui donnent 88,
    • elle renvoie cette valeur ;
  • la ligne dans le main et maintenant équivalente à nb = 8.

Lorsque dans le main on arrive sur nb = double_it(nb) :

  • nb est remplacée par sa valeur 88 et on entre dans double_it avec to_double qui vaut 88 :
    • elle fait to_double * 2,
    • ce qui revient à faire 828*2 qui donnent 1616,
    • elle renvoie cette valeur ;
  • la ligne dans le main et maintenant équivalente à nb = 16.

II.3. Exercice: nombres pairs

Fichier·s à rendre : is_even.c Fonction·s autorisée·s : aucune

Écrivez la fonction is_even qui prend un paramètre de type int et qui renvoie une valeur de type int.

is_even doit renvoyer 1 lorsque le nombre reçu en paramètre est pair et 0 lorsqu’il ne l’est pas.

Base pour le fichier is_even.c avec un main qui appelle votre fonction et la teste sur un seul cas :

#include <stdio.h>

int is_even(int nb)
{
	// votre code ici
}

int main(void)
{
	if (is_even(2) == 1) {
		puts("2 is even!");
	} else {
		puts("this should be impossible! 2 can't be odd");
	}
}

Exécution du test :

$ gcc is_even.c
$ ./a.out
2 is even!

II.4. Exercice: majuscule

Fichier·s à rendre : capitalise.c Fonction·s autorisée·s : aucune

Écrivez la fonction stu_capitalise qui prend en paramètre une lettre minuscule et renvoie la majuscule correspondante. Si le caractère reçu en paramètre n’est pas une lettre minuscule, renvoyez-le sans transformation.

Exemple de base de fichier et de test pour votre fonction :

char stu_capitalise(char letter)
{
	// votre code ici
	return letter;
}

int main(void)
{
	if (stu_capitalise('a') != 'A') {
		return (1);
	}
	if (stu_capitalise('z') != 'Z') {
		return (1);
	}
	if (stu_capitalise('/') != '/') {
		return (1);
	}
	return (0);
}

Exécution du test :

$ gcc capitalise.c
$ ./a.out
$ echo $?
0

III. Boucles

III.1. Resource: boucles

Une boucle permet à un morceau de code d’être appelé plusieurs fois tant qu’une condition est vraie. Une boucle while c’est comme un if (sans possibilité de else derrière) sauf qu’après avoir exécuté le code du corps, on revérifie la condition et si elle passe encore, on exécute le corps à nouveau. Et cela jusqu’à ce que la condition ne passe plus.

void print_mult_of_5_between(int start, int end)
{
	int current;

	current = start;
	while (current < end) {
		if (is_mult_of_5(current) == 1) {
			printf("%d is a multiple of 5\n", current);
		}
		current += 1;
	}
}

III.2. Exercice: write_alpha

Fichier·s à rendre : write_alphabet.c Fonction·s autorisée·s : putchar

Écrivez un programme (votre fichier doit donc contenir un main) qui affiche l’alphabet de A à Z suivi par un retour à la ligne.

III.3. Exercice: halfabet

Fichier·s à rendre : write_halfabet.c Fonction·s autorisée·s : putchar

Écrivez un programme qui écrit sur la sortie standard l’alphabet en lettres minuscules, en parant de A et en sautant une lettre sur deux, le tout suivi d’un retour à la ligne.

Les contraintes sont les mêmes que pour l’exercice d’avant.

III.4. Exercice: la holà de l’alphbet

Fichier·s à rendre : write_waving_alphabet.c Fonction·s autorisée·s : putchar

Écrivez un programme qui écrit sur la sortie standard l’alphabet en capitalisant une lettre sur deux et en commençant par une majuscule, le tout suivi d’un retour à la ligne.

III.5. Exercice: répéter un caractère

Fichier·s à rendre : repeat_char.c Fonction·s autorisée·s : putchar

Écrivez une fonction qui affiche un caractère passé en paramètre autant de fois que demandé par le second paramètre.

void stu_repeat_char(char c, int n);

III.6. Exercice: jet de dés

Fichier·s à rendre : roll_2d6.c Fonction·s autorisée·s : putchar

Écrivez un programme qui écrit toutes les combinaisons qu’il est possible d’obtenir en jetant 2d6 (deux dés à six faces). Aucune combinaison ne doit être répétée. Les combinaisons doivent être séparées par un espace. La dernière combinaison doit être immédiatement suivie d’un retour à la ligne.

Les combinaisons doivent apparaître par ordre croissant. Le plus petit nombre de chaque paire doit être affiché en premier de sorte que quelque chose comme “2-1” ne soit jamais affiché.

1-1 1-2 1-3 1-4 1-5 1-6 2-2 [exemple tronqué] 6-6

III.7. Exercice: puissance

Fichier·s à rendre : pow.c Fonction·s autorisée·s : aucune

Écrivez une fonction qui prend un nombre de départ et une valeur d’exposant en paramètre. Renvoyez le nombre à la puissance de l’exposant donné.

int stu_pow(int nb, int power);

Exemples de puissances :

  • 22=42^2=4
  • 216=655362^{16}=65536
  • 53=1255^3=125
int main(void)
{
	int res;

	res = stu_pow(2, 16);
	if (res == 65536)
		puts("ok");
	else
		puts("nok");	
}

III.8. Exercice: quantité de chiffres dans un nombre

Fichier·s à rendre : nb_len.c Fonction·s autorisée·s : aucune

Écrivez une fonction qui renvoie le nombre de chiffre que comporte un nombre.

int nb_len(int nb);

Exemple : le nombre 1525015250 a 5 chiffres. Le nombre 00 en a 1. Le nombre 124-124 en a 3.

III.9. Exercice: extraire un chiffre d’un nombre

Fichier·s à rendre : get_digit.c Fonction·s autorisée·s : aucune

Écrivez une fonction qui extrait un chiffre à un nombre en prenant sa position dans le nombre. Pour cet exercice, la position 0 correspond au chiffre le moins fort (le plus à droite).

int get_digit(int nb, int index);

Dans le nombre 2561325613, les nombres aux différentes positions sont :

  • 0 → 3
  • 1 → 1
  • 2 → 6
  • 3 → 5
  • 4 → 2

III.10. Exercice: imprimer un nombre en base 10

Fichier·s à rendre : print_base10.c Fonction·s autorisée·s : putchar

Vous devez implémenter la fonction suivante :

int print_base10(int nb);

Elle prend en paramètre le nombre à imprimer et elle renvoie le nombre de caractères écrits, y compris le signe du nombre s’il était négatif.

Pensez à comment afficher les nombres positifs, négatifs ou nuls.

III.11. Exercice: imprimer un nombre en base 16

Fichier·s à rendre : print_base16.c Fonction·s autorisée·s : putchar

Si vous êtes arrivés jusque là : cet exercice sera votre ultime épreuve de la journée.

Vous devez implémenter la fonction suivante :

int print_base16(int nb);

Elle prend en paramètre le nombre à imprimer et elle renvoie le nombre de caractères écrits, y compris le signe du nombre s’il était négatif.

Pensez à comment afficher les nombres positifs, négatifs ou nuls.