Eléments de correction pour le TP 3 de Programmation 1
(Des coquilles sont possibles...)

Le thème de ce TP : fonctionnement (particulier) des entrées-sorties en C.

Exercice 1

Procédure Ligner
Donnée : un caractère C de code ASCII supérieur à 32, un entier naturel p.
Résultat : affichage de p fois le caractère C.
Si C>' ' alors
  Pour i de 1 à p faire Afficher C.

Procédure Border
Donnée : un caractère C de code ASCII supérieur à 32, un entier naturel q.
Résultat : affichage de deux caractères C séparés par q espaces.
Si C>' ' alors
  Afficher ' ';
  Pour i de 1 à q faire Afficher C;
  Afficher ' '.

Exemple de traduction en C :

#include <stdio.h>

int i, entier;
char caractere;

void Ligner(char C, int p) {
int i;
if (C>' ')
  for (i=1;i<p;i++)
  printf("%c",C);
}

void Border(char C,int q) {
int i;
if (C>' ') {
  printf("%c",c);
  for (i=0;i<q;i++) printf(" ");
  printf("%c",c);
  }
}

main() {
do {
  printf("caractère puis entier : ");
  scanf("%c %d",&caractere,&entier);
  printf("\n");
  Ligner(c,n);
  printf("\n");
  for (h=0;h<n-2;h++) {
    Border(c,n-2);
    printf("\n");
    }
  Ligner(c,n);
  printf("\n");
  } while (c>' ');
}

N.B.
– Dans la fonction Ligner, si p<1, la boucle ne s'exécutera pas car la condition de poursuite i≤p est fausse dès que i=1.
– On a utilisé la comparaison (C>' ') mais on aurait pu utiliser une comparaison avec le code ASCII de l'espace : (C>32).
– Pour main, on a utilisé des noms de variables adaptés à leur signification.
– La variable i utilisée dans main est une variable globale ; la variable i définies dans chacune des fonctions est une variable locale.
– On a choisi d'effectuer la saisie du caractère avant celle de l'entier, car si on veut afficher différents carrés, il ne faut pas que la touche Entrée soit enregistrée comme un caractère valide(de code ASCII 10 donc inférieur à 32) :
#include <stdio.h>
char C;
main() {
do {
  scanf("%c",C);
  printf("%d",C);
  } while (C!=' ');
}

Essayez ce programme en saisissant sur trois lignes :
a
bc
def gh



Exercice 2

Trace de l'algorithme (et du programme) :
n←4. D←0
i   | i<n ? |S[i] | modifications de D :
----|-------|-----|----------------------|
0   | oui   | '1' | D←2D+1 : D=1
1   | oui   | '0' | D←2D : D=2
2   | oui   | '1' | D←2D+1 : D=5
3   | oui   | '1' | D←2D+1 : D=11
4   | non   |     | retourner 11.
----|-------|-----|----------------------|

N.B. Il y a une difficulté pour déclarer une chaine de caractères destinée à être utilisée par scanf. Des trois possibilité suivantes, seule la dernière semble marcher avec toutes les versions de gcc. Mais de mauvaises surprises sont toujours possibles...
char* S; // problème de pointeur nul (voir Programmation 2)
char* S="textequelconque"; // parfois scanf ne change pas le contenu de S.
char S[10]; // difficulté quand on saisit une chaine de moins de 10 caractères
char S[10]={0};// Si on saisit moins de 10 caractères, la chaine saisie se terminera par '\0' qui est le symbole de fin de chaine. Si on saisit plus de 10 caractères, S sera agrandie automatiquement.

Exercice 3

Exemple de solution en C :

unsigned int n,p,q;
char c;

// Prototype de la fonction Opere
unsigned int Opere(unsigned int n, char c, unsigned int p);

main() {
do {
  printf("\noperation : ");
  // saisie multiple avec l'opérateur au milieu
  scanf("%u%c%u",&n,&c,&p);
  q=Opere(n,c,p);
  printf("=%u\n",q);
  }
  // On s'arrête si l'opérateur n'est pas conforme
  while (c=='+' || c=='-' || c=='*' || c=='/');
}

unsigned int Opere(unsigned int n, char c, unsigned int p) {
// switch doit utiliser une variable entière, ce qui est le cas en C du type char
switch(c) {
  case '+' :
    return (n+p);
    break; // Après un return, ce break inutile est juste une précaution
  case '-' :
    if (n>p) return (n-p); else return 0;
    break;
  case '*' :
    return (n*p);
    break;
  case '/' :
    return (n/p);
    break;
  default : return 0;
  }
}