TP 1 de programmation avancée en C

Important : Tous les programmes en C des TP seront compilés avec gcc, à l'exclusion de tout compilateur pour C++. Le comportement des programmes pourra varier selon la version du langage (ANSI C, C89, ..., C11).

Exercice 1
1. Créer un type de données nommé Date composée d'une année, d'un mois et d'un jour. De quels types peuvent-être les composantes année, mois, et jour, si on veut minimiser leur place en mémoire ?
2. Créer une procédure nommée creerDate qui place dans une variable de type date les trois valeurs qui la composent.
3. Créer une fonction booléenne nommée estDateValide qui vérifie si une date est valide : mois compris entre 1 et 12, jour compris entre 1 et 29 à 31 selon le mois.
N.B. On ne tiendra pas compte des années bissextiles.
4. Créer une fonction booléenne nommée estavant qui indique si une date est plus ancienne qu'une autre.
5. Créer une fonction nommée distanceDates qui donne le nombre de jour séparant deux dates.
N.B. la valeur obtenue peut être positive ou négative...

Exercice 2
1. Créer un type de donnée nommée Nombre qui peut être soit un entier naturel n codé sur un octet, soit un entier relatif p, soit un réel x.
2. Créer une variable nommée cenombre et lui assigner successivement : la valeur entière naturelle 65, la valeur entière relative -65000, puis la valeur réelle 16.625. Faire afficher la variable après chaque assignation.
3. Que se passe-t-il si, après la dernière assignation, on essaie d'afficher la valeur de l'entier relatif p ?
4. En utilisant la fonction sizeof, déterminer la taille de la variable cenombre. Le résultat vous surprend-il ?

Exercice 3
On rappelle que les arguments en ligne de commande sont accessibles dans un programme C en utilisant : main(int argc, char** argv)argc représente le nombre d'arguments et argv représente la liste des arguments, chaque argument étant de type char*.
N.B. les noms argc et argv sont traditionnels, on pourrait aussi bien utiliser (par exemple) : main(int nombre_arguments, char** liste_arguments)
1. Ecrire un programme qui affiche la liste des arguments en ligne de commande.
2. Modifier ce programme pour qu'il n'affiche que les paramètres, c'est-à-dire les arguments à l'exception du nom de l'exécutable.

Exercice 4
On rappelle qu'une chaine de n caractères occupe un espace en mémoire de n+1 caractères, le dernier caractère étant un '\0' terminal ne faisant pas partie de la chaine.
1. Créer et faire tourner un programme contenant les instructions suivantes :
  s="abcde";
  i=0;
  while (s[i]!='\0') printf("%c\n",s[i]);
Pourquoi ce programme tourne-t-il indéfiniment ?
2. Corriger ce programme pour qu'il affiche un par un les caractères de s.
3. Créer et faire tourner un programme contenant les instructions suivantes :
  char t[6]="abcdef";
  ...
  printf("t=%s",t);
  t[3]='\0';
  printf("t=%s",t);   printf("t[4]=%c\n",t[4])
4. Comment expliquer l'affichage de ce programme ?
5. Réaliser un programme qui transfert les dix premiers caractères d'une chaine de caractère de type char* dans un tableau de dix caractères. Si la chaine est trop courte, que placer dans les cases inutilisées du tableau ?

Exercice 5
1. Créer et compiler le programme suivant :
  #include <stdio.h>
  #include <stdlib.h>
  int i;
  char * s;
  main() {
  scanf("%d",&i);
  printf("%d\n",i);
  scanf("%s",s);
  printf("%s\n",s);
Saisir l'entier 45 puis (après un retour à la ligne) la chaine "abcde". Que se passe-t-il ?
2. Modifier la quatrième ligne en : char s[5];. Recompiler et refaite un essai de saisie. Qu'observez-vous ?
Quel changement y a-t-il si la deuxième saisie est une chaine de plus de cinq caractère ?
Et si on ne fait qu'une seule saisie "45abcdefghj" ?
Que pouvez-vous alors conclure sur les entrée-sorties du langage C ?
© 2016 – A. Sigayret – Université Clermont-Fd II