TP 1a d'initiation à la programmation en C

Présentation
Ce TP a pour but de vérifier que les bases de la programmation en C ont été acquises avant d'aborder les TP d'architecture des systèmes en L2 informatique et en option des autres L2. Les étudiants d'informatique passeront directement au TP 1b.
   Le langage C est un langage de programmation impératif de bas niveau car très proche dans son esprit et dans sa syntaxe de la programmation en assembleur : faible contrôle, entrées-sorties rudimentaires, syntaxe absconse parfois hasardeuse, etc. Sa connaissance est cependant essentielle car il permet une programmation proche de la machine et donc d'éxécution rapide et sa syntaxe a été réinvestie pour d'autres langages (Java, ...).
   Il existe de nombreux sites en ligne d'apprentissage ou d'aide à la programmation en C (par exemple le Site du Zéro), il n'est pas inutile de les consulter...


Exercice 1
1. Enregistrer le programme ci-dessous dans un fichier exc1.c, puis le compiler en tappant dans un terminal Unix la commande  gcc -o exec1 exc1.c  puis lancer le programme en tappant  ./exec1
#include <stdio.h>
void main()
  {
  printf("Bonjour chez vous !\n");
  }
N.B. -o exec1 signifie que le fichier exécutable créé sera nommé exec1 (à défaut, le nom de l'exécutable serait a.out), l'utilisation de "./" indique à la machine que le programme lancé se trouve dans le répertoire courant.
2. Modifier la commande printf avec : "Bonjour \nchez vous !", enregistrer le fichier et recompiler avec gcc, que se passe-t-il à l'éxécution ? Quel est le rôle de "\n" ?
3. Que se passe-t-il si on supprime du programme l'instruction initiale #include <stdio.h> ? Rechercher sur le web l'utilité de cette instruction et la notion de "bibliothèque" (library). A quoi servirait par exemple l'instruction #include <stdlib.h> ?
3. Qu'y a-t-il de nouveau dans le programme suivant ? A quoi peut servir la différence ?
#include <stdio.h>
int main()
  {
  printf("Bonjour chez vous !\n");
  return 0;
  }

Exercice 2
1. Exécuter le programme suivant et saisir un nombre entier (un élément de Z). Que se passe-il si on fournit une lettre (par exemple 'A') au lieu d'un nombre ?
// une saisie
#include <stdio.h>
  int n;
void main()
  {
  printf("Un entier SVP : ");
  scanf("%d",&n);
  printf("\n");
  }
N.B. Remarquer la ligne de commentaire (facultative) commençant par //. On prendra l'habitude d'ajouter des commentaires selon les besoins.
2. Exécuter le programme suivant.
// deux saisies
#include <stdio.h>
    int n;
  char k='A';
void main()
  {
  printf("Un entier SVP : ");
  scanf("%d",&n);
  printf("Un caractère SVP : ");
  scanf("%c",&k);
  printf("\n");
  printf("n=%d",n);   printf("k=%c",k);   }
N.B. vous pouvez constater l'aspect primitif du C : il faut préciser aux instructions printf et scanf le type de la variable à afficher ou saisir : un entier (%d), un caractère (%c). Pour scanf, le nom de la variable doit être précédé du symbole &.
N.B. il se peut que la saisie du caractère ne se fasse pas correctement. Vérifier sur Internet la raison du problème (liée à la primitivité du langage C).
3. Ajouter à ce programme une troisième saisie pour une chaine de dix caractères s, suivie de son affichage. Il faudra auparavant définir une chaîne de dix caractères initialement vide : char s[10]="";.
Que se passe-t-il si on saisit une chaîne de moins de dix caractères ? une chaîne de plus de dix caractères ?

Exercice 3
1. Que se passe-t-il dans le programme ci-dessous si on choisit un entier strictement négatif ? Pourquoi ?
// et si ?
#include <stdio.h>
void main()
  {
  int n;
  printf("Un entier SVP : ");
  scanf("%d",&n);
  printf("\n");
  if (n<0) return;
  printf("OK\n");
  }
2. Que fait ce programme ?
// alternative
#include <stdio.h>
void main()
  {
  int n;
  printf("Un entier SVP : ");
  scanf("%d",&n);
  printf("\n");
  if (n<0) printf("positif SVP !\n"); else printf("OK\n");
  }
3. Ecrire un programme qui teste si un caractère saisi k est une majuscule : k≥'A' ET k≤'Z'.
N.B. En C, le "ET logique" s'écrit && et le "OU logique" ||.
4. Ecrire un programme qui teste si un caractère saisi k est une majuscule, mais SANS utiliser le "et logique" (utiliser une double alternative).
5. Ecrire un programme qui teste si un caractère saisi k est une lettre non accentuée : 'A'≤k≤'Z' OU 'a'≤k≤'z'.
Comment écrire le même programme sans utiliser aucun connecteur logique ?

Exercice 4
1. Exécuter le programme suivant, après avoir corrigé les éventuelles erreurs de programmation...
// on boucle!
#include <stdio.h>
  int i; char k='@';
void main()
  {
  for (i=0;i<3;i++)
      printf(k);
  }
2. Modifier le programme ci-dessus pour que le nombre de # affichés soit déterminé par un entier n saisi par l'utilisateur. Que se passera-t-il si l'entier n saisi est négatif ?
3. Ecrire un programme qui affiche un rectangle de # d'une largeur de n et d'une hauteur de p, n et p étant des valeurs saisies par l'utilisateur.
4. Modifier le programme pour tenir compte des contraintes supplémentaires : 1<n<31 et 0<p<7.

Exercice 5
1. En C, on peut définir des fonctions, une procédure en C correspondand à une fonction qui retourne "rien" (void). Dans le programme ci-dessous, quelles sont les procédures ? Préciser le type de chaque fonction (paramètres d'entrée et paramètres de sortie) et indiquer ce qu'elle fait.
// f(x)=?
#include <stdio.h>
int carre(float x)
  { return x*x; }
int pi()
  { return 3.1416; }
int delta(float a; float b,float c)
  { return b*b-4*a*c; }
int facto(int n)
  { if (n<=1) return 1; else return (facto(n-1)); }
void afficher(char ceci)
  { printf("%c\n",ceci) }
void afficher(int cela)
  { printf("%d\n",cela) }
void main()
  {
  int i=5; char k='A'+i;
  afficher(i); afficher(k);
  float f=carre(i)*pi;
  afficher(facto(i));
  afficher(delta(1.2;1.5;6.5));
  printf("fin\n");
  }
2. Faire tourner ce programme après avoir rectifié les éventuelles erreurs.
3. Créer un programme qui définit une fonction fibo(n) correspondant à la suite de Fibonacci : F(0)=F(1)=1 et F(n)=F(n-1)+F(n-2). Le programme (convivial!) devra saisir un entier n et afficher F(n) si c'est possible ou indiquer dans un message quel est le problème.
3. Créer un programme qui définit les fonctions combinatoires C(n,p) et A(n,p) et laisse le choix à l'utiliser d'utiliser l'une ou l'autre fonction sur une valeur n à saisir. Que se passe-t-il si la valeur de n est trop grande ? Un test adapté sur la valeur de n évitera de dépasser les capacités de la machine.

Exercice 6
1. Créer un programme qui défini un tableau T[r][c] d'entiers de r lignes et c colonnes, r et c étant des entiers courts (unsigned short) dont la valeur sera donnée dans le début du programme. Dans chaque case T[i][j] du tableau, sera placé la valeur i*j.
2. Modifier ce programme pour que les valeurs de r et c soient saisies par l'utilisateur.

© 2015 A. Sigayret & al.