next up previous contents index
Next: Liste des figures Up: Le débogueur gdb Previous: Fonctions avancées : bitmaps

Fonctions avancées : Événements

Exemple 4
  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

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.

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.

 


next up previous contents index
Next: Liste des figures Up: Le débogueur gdb Previous: Fonctions avancées : bitmaps
Jean-Philippe Chancelier
9/29/1998