typedef struct { int event; /* NONE, KEY ou CLICK */ int key; /* Si KEY -> la touche */ int button; /* Si CLICK -> le bouton (1,2,3) */ int x, y; /* Coordonnées de la souris */ int state; /* Etat de la souris et de SHIFT, etc. */ } WinEvent; #define SHIFT 0x1 /* Bits mis à 1 dans event.state */ #define CONTROL 0x4 #define ALT 0x8 #define BUT1 0x100 #define BUT2 0x200 #define BUT3 0x400
WinEvent ev; do { winEvent(500, &ev); switch (ev.event){ case NONE: printf("No event (mouse=(%d,%d,%x))\n", ev.x, ev.y, ev.state); break; case KEY: printf("Key %d pressed (mouse=(%d,%d,%x))\n", ev.key, ev.x, ev.y, ev.state); break; case CLICK: printf("Button %d pressed (mouse=(%d,%d,%x))\n", ev.button, ev.x, ev.y, ev.state); break; } } while (ev.event!=KEY || ev.key!='q');
Correspondance Pascal / C
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.
2cProgramme principal | |||
---|---|---|---|
(* programme principal *) program p(input,output); begin end. |
/* programme principal */ int main() { } |
||
2c
Noter la différence de syntaxe des commentaires. |
2cIdentificateurs | |||
---|---|---|---|
unIdent z0 |
unIdent un_ident_C z0 |
||
2c
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. |
2cDé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); |
||
2c
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.
|
2cPoint-virgule et instructions | |||
---|---|---|---|
begin p := p - 1; a := x * a end |
{ p = p - 1; a = x * a; } |
||
2c
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. |
2cQuelques 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 |
||
2c
Noter la différence de syntaxe, en particulier celle du test d'égalité. |
2cInstructions 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");
}
|
||
2c
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. |
2cInstructions 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 = xx = 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; } |
||
2c
Noter que l'instruction Pascal repeat until b exécute 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.
|
2cTypage | |||
---|---|---|---|
var b: boolean; x: 1..99; |
int b,x; double a; int gros = INT_MAX; /* coercition */ a = (double)gros+1; |
||
2c
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.
|
2cTableaux | |||
---|---|---|---|
var v: array [1..100][1..2] of real; |
double v[100][2]; |
||
2c
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]. |
2cFonctions et Procédures | |||
---|---|---|---|
var k: integer; procedure raz; begin k := 0 end; function d(x,y: real): real begin d := sqrt(x*x + y*y) end; |
int k; void raz() { k = 0; } double d(double x, double y) { return sqrt(x*x + y*y); } |
||
2c
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.
|
2cAdresses | |||
---|---|---|---|
|
int i, *ptr; ptr = |
||
2c
En C, il est possible de manipuler explicitement les adresses mémoire. On peut les stocker dans des variables de type pointeurs. |
2cPointeurs | |||
---|---|---|---|
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); |
||
2c
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.
|
2cPassage 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( |
||
2c
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.
|
2cStructures | |||
---|---|---|---|
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; } |
||
2c
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.
|
2cUn 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); } |
||
2c
|
2cEntrées/sorties | |||
---|---|---|---|
var x: real; y: integer; readln(x,y) writeln(x,y) |
#include <stdio.h> double x; int a; scanf("printf(" |
||
2c
C ne possède pas d'instructions d'entrées/sorties, il faut utiliser des 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 |
2cFichiers | |||
---|---|---|---|
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 <stdio.h> 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; } |
||
2c
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.
|