next up previous contents index
Next: Guide pratique Up: No Title Previous: Précédence des opérateurs

Correspondance Pascal / C

Thierry Salset

On trouvera placés en vis à vis des exemples écrits en Pascal (colonne gauche) et en C (colonne droite) suivis d'un commentaire destiné à mettre en évidence les différences entre ces deux langages.

Programme principal
    (* programme principal *)
    program p(input,output);
    begin

    end.
      
    /* programme principal */
    int main() {
    
    }
      
Noter la différence de syntaxe des commentaires.

Identificateurs
    unIdent
    z0
      
    unIdent
    un_ident_C
    z0
      
Un identificateur en C doit commencer par une lettre ; ensuite on a droit aux lettres, aux chiffres et au caractère << souligné >>. La syntaxe du C distingue les lettres majuscules des lettres minuscules.

Déclarations
    const N = 100;
    type Tab = array[1..N,1..N]
      of integer;
    var a: Tab;
        i: integer;
    procedure init(n: integer);
    function
      pred(i: integer): integer;
      
    #define N 100
    int i;
    void init(int n);
    typedef int Tab[N][N];
    Tab a;
    int pred(int i);
      
En C, il n'y a pas d'ordre précis dans les déclarations si ce n'est que la déclaration d'un nom doit toujours précéder son utilisation. La définition des constantes utilise les capacités du pré-processeur.

Point-virgule et instructions
    begin
      p := p - 1;
      a := x * a
    end
      
    {
      p = p - 1;
      a = x * a;
    }
      
En C, Une intruction simple se termine par un point-virgule. Il fait partie de l'instruction alors qu'en Pascal, il est un séparateur d'instructions. En C, il n'y a jamais de point-virgule derrière une accolade fermant un bloc d'instructions.

Quelques opérateurs
    (* égalité *)
    s = 0
    (* inégalité *)
    s <> 0
    (* ET logique *)
    a and b
    (* OU logique *)
    a or b
    (* négation logique *)
    not a
      

    s == 0

    s != 0

    a && b

    a || b

    !a
      
Noter la différence de syntaxe, en particulier celle du test d'égalité.

Instructions non itératives
    (* affectation *)
    x := 1
    (* conditionnelle *)
    if a > b
    then z := a
    else z := b

    (* sélection *)
    case c of
      'a','b' : writeln('bonjour');
      'z' : writeln('au revoir');
      otherwise  writeln('goujat')
    end
      
    
    x = 1;

    if (a > b)
      z = a;
    else
      z = b;

    switch(c) {
      case 'a' :
      case 'b' : printf("bonjour\n");
                 break;
      case 'z' : printf("au revoir\n");
                 break;
      default  : printf("goujat\n");
    }
      
Remarquer l'instruction break dans le switch en C, elle fait sortir du switch. En l'absence de break, les clauses du switch sont exécutées en séquence jusqu'à la fin.

Instructions itératives
    while y > 0 do
      begin
      t := x mod y;
      x := y;
      y := t
      end

    repeat
      j := j-1
    until a[j] <= v

    for i := 0 to N-1 do
      begin a[i] = 0 end

    for i := N-1 downto 0 do
      begin a[i] = 0 end
      
      
    while (y > 0) {
      t = x%y;
      x = y;
      y = t;
    }


    do {
      j = j-1
    } while (a[j] > v)

    for (i=0; i < N; i++) {
      a[i] = 0;
    }

    for (i=N-1; i >= 0; i--) {
      a[i] = 0;
    }
      
Noter que l'instruction Pascal repeat S1;...;Sn until b exécute S1;...;Sn tant que l'expression booléenne est fausse alors que le do S while b de C exécute S tant que l'expression booléenne b est vraie.

L'instruction for du Pascal permet d'avoir un incrément de 1 ou -1 seulement ; le for du C est beaucoup plus général.

Typage
    var b: boolean;
        x: 1..99;
      
    int b,x;
    
    double a;
    int gros = INT_MAX;

    /* coercition */
    a = (double)gros+1;
      
C est un langage typé, toutefois il est possible de convertir une valeur d'un type en une valeur d'un autre type. On appelle ça une coercition.

Le type de base boolean n'existe pas en C. C'est la valeur numérique entière 0 qui représente le faux et n'importe quelle valeur numérique entière différente de 0, le vrai.

Il n'y pas de type << intervalle >> et pas de type << ensemble >> en C.

Tableaux
    var v: array [1..100][1..2]
      of real;
      
    double v[100][2];
      
En C, l'indice d'un tableau de taille N varie obligatoirement de 0 à N-1. La notation A[i,j] autorisée en Pascal si A est un tableau bidimensionnel n'est pas acceptée en C ; il faut écrire A[i][j].

Fonctions et Procédures
    var k: integer;
    procedure raz;
      begin
        k := 0
      end;

    function dist(x,y: real): real
    begin
      dist := sqrt(x*x + y*y)
    end;
      
    int k;
    void raz()
    {
      k = 0;
    }

    double dist(double x, double y)
    {
      return sqrt(x*x + y*y);
    }
      
En Pascal, le nom d'une fonction sans argument n'est pas suivi de ().

La valeur de retour d'une fonction est transmise à l'appelant par une affectation spéciale à une variable ayant le nom de la fonction. En C, c'est par l'instruction return.

Il n'y pas d'objet de type procédure en C. Ce sont simplement des fonctions retournant void.

C n'offre pas la possibilité de définir des fonctions à l'intérieur d'une autre fonction.

Adresses
    
      
    int i, *ptr;
    ptr = &i;
      
En C, il est possible de manipuler explicitement les adresses mémoire. On peut les stocker dans des variables de type pointeurs.

Pointeurs
    var pa: ^integer;
        b: integer;
        
    b := 7;
    new(pa);
    pa^ := b;
    dispose(pa)
      
    int *pa,b=7;


    pa = malloc(sizeof(int));
    *pa = b;
    free(pa);
      
En Pascal, un pointeur désigne nécessairement un objet dynamique. Les pointeurs du langage C n'ont pas cette limitation, ils peuvent mémoriser l'adresse d'un objet quelconque.

L'équivalent C du couple d'instructions Pascal new/dispose est le couple de fonctions de la bibliothèque C standard malloc/free.

Le pointeur nul qui est égal à la valeur de nil en Pascal, est égal à la valeur de la constante NULL en C.

Passage d'arguments
    var a,b: integer;
    procedure swap(var x,y : 
                   integer);
      var z: integer;
      begin
        z:=x; x:=y; y:=z
      end;

   begin 
     swap(a,b);
   end.
      
    void swap(int *px, int *py)
    {
      int z=*px;
      *px=*py;
      *py=z;
    }
    
    main () {
      int a,b;
      swap(&a,&b);
    }
      
En Pascal, les arguments peuvent être passés par valeur ou par variable (référence).

C n'a qu'un seul mode de passage d'argument, par valeur. Pour obtenir un passage par variable (par adresse), il faut passer explicitement l'adresse de la variable.

Structures
    type
      complex = record
        re: real;
        im: real
      end;

    var z: complex;

    begin
     z.re := 1.0;
     z.im := -1.0
    end
    (* ou bien *)
    with z do
      begin
        re := 1.0;
        im := -1.0
      end
      
    typedef struct complex {
      double re;
      double im;
      } complex;

    complex z = {0, 0};

    {
     z.re = 1;
     z.im = -1;
    }

      
L'analogue C d'un enregistrement Pascal est la << structure >> introduite par le mot-clé struct. Une structure C ne peut pas avoir de << variantes >>.

L'instruction with n'existe pas en C.

Un exemple complet : les listes chaînées
    program list();
    type List = ^Cell;
         Cell = record
           val: integer;
           next: List
         end;

    var l: List;
        i: integer;

    function
      cons(n: integer; l: List) : 
      List
      var c: List;
      begin
        new(c);
        c^.val := n;
        c^.next := l;
        cons:=c
      end;

    procedure freeList(l: List);
      if l <> nil
      then
        begin
        freeList(l^.next);
        dispose(l)
        end;
    
    begin
      l:= nil;
      for i:=1 to 100 do
        l := cons(i*i,l);
      ...
      freeList(l)
    end.
      
    typedef struct cell {
      int val;
      struct cell *next;
      } List;

    List *cons(int n, List *l)
    {
      List *c = malloc(sizeof(List));
      c->val = n;
      c->next = l;
      return c;
    }

    void freeList(List *l) {
      if (l) {
        freeList(l->next);
        free(l);
      }
    }

    main ()
    {
      List *l = NULL;
      int i;
    
      for(i=1;i<=100;i++) {
        l = cons(i*i,l);
        }
      ...
      freeList(l);
    }
      

Entrées/sorties
    var x: real;
        y: integer;

    readln(x,y)
    writeln(x,y)
      
    #include 
    
    double x;
    int a;

    scanf("%lf%d",&x,&a);
    printf("%f\t%d\n",x,a);
      
C ne possède pas d'\emph{instructions} d'entrées/sorties, il faut utiliser des \emph{fonctions} définies dans la bibliothèque standard (noter l'inclusion du fichier d'en-têtes stdio.h). À la place des instructions Pascal write et writeln, utiliser en C la fonction d'impression formatée printf. De même, à la place de read et readln, utiliser scanf. Remarquer le \n inséré à la fin du format du printf pour faire un saut de ligne alors qu'il est implicitement réalisé par la fonction writeln

Fichiers
    program copier;
    var in,out: file of char;
        c: char;
    begin
      reset(in,'foo');
      rewrite(out,'bar');
      while not eof(in) do
      begin
        read(in,c);
        write(out,c)
      end;
      close(in);
      close(out)
    end.
      
    #include 
    
    int main() {
      FILE *if,*of;
      int c;
      if=fopen("foo","r");
      of=fopen("bar","w");
      while((c=getc(if)) != EOF)
        putc(c,of);
      fclose(if);
      fclose(of);
      return 0;
    } 
      
Le langage Pascal définit sa propre notion de fichier alors que C se repose sur celle du système et ne propose rien de plus. Un fichier est simplement une suite de caractères ; il n'a donc pas de structure particulière. Pour Pascal, un fichier est une suite d'objets d'un certain type.

La fonction fopen associe à un fichier réel un objet de type FILE. L'association est rompue par fclose. Si la fin d'un fichier est atteinte, la fonction d'entrée getc retourne la valeur de la constante EOF.

Les fonctions d'entrées/sorties formatées qui opèrent sur des fichiers s'appellent fscanf et fprintf. Elles s'emploient comme scanf et printf sauf qu'elles prennent un pointeur sur un objet de type FILE en premier argument.



Rene Lalement
Mon Sep 30 18:22:54 MET 1996