#include <stdio.h>
int fact(int n)
{
if (n==1) return 1;
else return n*fact(n-1);
}
int main ()
{
int a = 5;
printf("fact(%d)=%d\n",a,fact(a));
return 0;
}
Au moment où la fonction main fait l'appel fact(a) , n reçoit la valeur de a , qui est 5. Plaçons un point d'arrêt sur la fonction fact et lançons le programme avec r, le programme est interrompu à chaque appel à fact au niveau de la ligne << if (n==1) return 1; >>. Avançons avec step dans l'exécution de la fonction fact , après 3 appels récursifs (à elle-même), examinons la pile d'appel avec backtrace :
(gdb) bt
#0 fact (n=3) at fact.c:5
#1 0x10708 in fact (n=4) at fact.c:6
#2 0x10708 in fact (n=5) at fact.c:6
#3 0x10748 in main () at fact.c:12
La pile a 4 niveaux : les 3 appels à fact et l'appel à
main .
Au niveau courant (noté 0), tentons d'imprimer la valeur de la variable a :
(gdb) p a
No symbol "a" in current context.
La variable a n'est pas définie dans ce contexte. Nous pouvons
remonter dans la pile avec la commande up. Si nous allons
jusqu'au niveau 3 (appel à main ) avec 3 << up >> et que
nous tentons à nouveau d'imprimer la valeur de a , nous obtenons :
(gdb) p a
$3 = 5
Dans le contexte d'appel à main , la variable a est bien
définie.
L'analyse au débogueur du contexte (ou environnement) d'exécution d'une fonction permet de mieux comprendre le mode de fonctionnement de C.
Mémento C - shell, Emacs, gdb
1|c|Programme |
---|
int main() |
{ |
... |
return 0; |
} |
1|c|Variables |
---|
int i; |
double x,y; |
char c; |
char s[32]; |
char A[3][3]; |
1|c|Constantes |
---|
const int n=10; |
#define N 10 |
enum {NORD,EST,SUD,OUEST}; |
1|c|Fonctions |
---|
Définition |
double f(int i,int j,double x) |
{ |
int k,l |
double y,z; |
... |
return z; |
} |
void g(int i) |
{ |
if (i==2) { |
return; |
} |
... |
} |
Déclaration |
void g(int i); |
1|c|Types de variables |
---|
/* variable globale */ |
int a; |
/* parametres */ |
void hop(int b,int c) |
{ |
/* variables locales */ |
int i,j; |
/* variable statique (conserve |
sa valeur entre 2 appels) */ |
static int memo; |
} |
1|c|Initialisation des variables |
---|
int globale=3; |
|
void hop() |
{ |
int locale=2; |
static int statique=4; |
complex z={1,2}; |
double tb[2]={3,4}; |
int A[]={2,4}; |
int B[][3]={{1,2,3},{4,5,6}}; |
complex C[]={{1,2},{3,4}}; |
} |
1|c|Passage par variable |
---|
void max(double x,double y, |
double *z) |
{ |
if (x<y) |
*z=y; |
else |
*z=x; |
} |
... |
max(x,y,&z); |
... |
1|c|Conditions |
---|
if ( test ) { |
... |
} |
if ( test ) { |
... |
} else { |
... |
} |
switch (i) { |
case 1: |
... |
break; |
case 2: |
... |
break; |
default: |
... |
} |
2|c|Tests | |
---|---|
égal | == |
différent | != |
supérieur | > et >= |
inférieur | < et <= |
et | && |
ou | || |
non | ! |
1|c|Boucles |
---|
for (i=1;i<=n;i=i+1) { |
... |
} |
while (i<j) { |
... |
} |
do { |
... |
} while (i<j); |
1|c|Structures |
---|
typedef struct { |
double a; |
double b; |
} complex; |
complex z; |
z.a=2; |
z.b=3; |
typedef struct list { |
int val; |
struct list *next; |
} list; |
2|c|Contractions | |
---|---|
i=i+1; | i++; |
(*c).a | c->a |
&(*i) | i |
1|c|Maths |
---|
#include <math.h> |
x=sqrt(y); |
x=pow(y,3); |
LDLIBS=-lm |
1|c|Tableaux |
---|
/* un tableau est toujours |
passé par variable */ |
/* Passage de la dimension |
inutile */ |
void remplit(int t[]) |
{ |
int i; |
for (i=0;i<10;i++) |
t[i]=2*i+1; |
} |
... |
int tb[10]; |
remplit(tb); |
for (i=0;i<10;i++) |
printf("tb[%d]=%d\n", |
i,tb[i]); |
... |
1|c|Tableaux multidim |
---|
/* un tableau est toujours |
passé par variable */ |
/* Déclaration des dimensions |
obligatoire à partir de la |
/* deuxième */ |
void remplit(int t[][5]) |
{ |
int i,j; |
for (i=0;i<10;i++) |
for (j=0;j<5;j++) |
t[i][j]=2*i+j; |
} |
... |
int tb[10][5]; |
remplit(tb); |
for (i=0;i<10;i++) |
for (j=0;j<5;j++) |
printf("tb[%d,%d]=%d\n", |
i,j,tb[i][j]); |
... |
1|c|Abréviations de type |
---|
typedef enum {Nord, Est, Sud, Ouest} direction; |
typedef char[N] string; |
typedef double (*fun)(double); |
1|c|16. Tableaux taille variable |
---|
#include <stdlib.h> |
|
void remplit(int t[],int n) |
{ |
... |
} |
|
int main() |
{ |
int *t; |
int n; |
|
scanf("%d",&n); |
t=malloc(n*sizeof(int)); |
remplit(t,n); |
... |
free(t); |
} |
#include <stdlib.h> |
|
... |
data *rep; |
|
... |
rep=malloc(n*sizeof(data)); |
... |
n=new_n; |
rep=realloc(rep,n*sizeof(data)); |
... |
free(rep); |
1|c|Entrées/Sorties |
---|
#include <stdio.h> |
printf("%d %f %c %s\n",i,x,c,s); |
scanf("%d %lf %c %s",&i,&x,&c,s); |
program < data > out |
#include <stdio.h> |
|
... |
FILE *in,*out; |
|
in=fopen("data","r"); |
if (!in) { |
printf("erreur de lecture\n"); |
exit(1); |
} |
... |
fscanf(in,"%d %lf %c %s",&i,&x,&c,s);, |
... |
fclose(in); |
... |
out=fopen("out","w"); |
if (!out) { |
printf("erreur d'écriture\n"); |
exit(1); |
} |
... |
fprint(out,"Résultats: %d %lf\n",n,y);, |
... |
fclose(out); |
#include <stdlib.h> |
|
int main(int argc, char argv[]) |
{ |
char name[32]; |
int n; |
double x; |
|
if (argc != 4) { |
printf("Syntax: %s name n x\n",argv[0]); |
exit(1); |
} |
strcpy(name,argv[1]); |
n=atoi(argv[2]); |
x=atof(argv[3]); |
... |
} |
2|c|Arithmétique | |
---|---|
Modulo | j=i%n |
(attention -7%5 vaut -2) |
|
Division réelle | x=(double)i/j; |
x=i/2.0; |
1|c|Caractères |
---|
char c; |
scanf("%c",&c); |
c='a'; |
printf("%c\n",c); |
1|c|Chaînes |
---|
char s[32]; |
scanf("%s",s); |
printf("%s\n",s); |
sprintf(s,"%d",i); |
c=s[i]; |
s[i]='a'; |
#include <string.h> |
l=strlen(s); |
strcpy(dest,source); |
strcmp(s1,s2); |
1|c|Makefile |
---|
LDLIBS=... |
2|c|Commandes Emacs (C) | |
---|---|
Compiler | CTRL-c CTRL-c |
Erreur suivante | CTRL-c CTRL-n |
Erreur précédente | CTRL-c CTRL-p |
Tuer la compilation | CTRL-c CTRL-k |
Indenter | TAB |
; sans nouvelle ligne | MéTA-; |
} sans nouvelle ligne |
MéTA-} |
Panique! | CTRL-g |
compléter un nom de fichier | TAB |
Lancer gdb | M-X gdb fichier |
2|c|Souris | |
---|---|
Recopier | |
1- Début | Clic gauche |
2- Fin | Clic droit |
3- Copier | Clic mileu |
2|c|Commandes shell Unix | |
---|---|
Lister | ls |
Créer un répertoire | mkdir Info |
Changer de répertoire | cd Info |
Remonter | cd .. |
Retourner chez soi | cd |
Aller chez quelqu'un | cd ~joe |
Copier un fichier | cp hop.c hip.c |
Copier des fichiers | cp ~joe/*.c . |
Renommer un fichier | mv hop.c hip.c |
Renommer un répertoire | mv info Info |
Déplacer un fichier | mv hop.c Info |
Déplacer des fichiers | mv *.c Info |
Détruire un fichier | rm hop.c |
Détruire des fichiers | rm *.c |
Détruire un répertoire | rmdir Info |
Compléter | TAB |
Imprimer un fichier | lpr hop.c |
Surveiller l'impression | lpq |
Supprimer une impression | lprm joe |
1|c|Graphiques |
---|
#include <win.h> |
winInit(w,h,col); |
winLoop(); |
winLine(a,b,c,d,col,t); |
winRect(a,b,w,h,col,t); |
winFillRect(a,b,w,h,col); |
winCircle(a,b,w,h,col,t); |
winFillCircle(a,b,w,h,col); |
winPoint(a,b,col); |
void winPoly(int n,pixel p[],WinColor col,int w); |
void winFillPoly(int n,pixel p[],WinColor col); |
winString(a,b,s,col); |
winGreyImage(g,w,h,x,y); |
winColorImage(r,g,b,w,h,x,y); |
winGreyPoint(x,y,g); |
winColorPoint(x,y,r,g,b); |
button=winInput(&x,&y); |
key=winKey(); |
key=winEvent(int millisec); |
white,black,blue,red,green,yellow,cyan,magenta |
LDLIBS=-lwin -lXm -lXt -lX11 |
3|c|Commandes gdb | ||
---|---|---|
Aide en ligne | help | générale |
help <sujet> | spécifique | |
Charger un programme | file <fichier> | |
Lancer l'exécution | r(un) | |
Lister | l(ist) | 10 lignes suivantes |
l(ist) <no ligne> | 10 lignes autour | |
l(ist) <fonction> | ||
Interrompre l'exécution | kill | abandonner l'exécution |
b(reak) <no ligne> | placer un point d'arrêt | |
sur une ligne | ||
b(reak) <fonction> | placer un point d'arrêt | |
à l'entrée d'une fonction | ||
info b | lister les points d'arrêt | |
delete <no pt d'arrêt> | supprimer un point d'arrêt | |
CTRL-C | interrompre (dans xterm ) | |
CTRL-C CTRL-C | interrompre (dans Emacs) | |
l'exécution | ||
Afficher une expression | p(rint) <expr> | valeur courante |
display <expr> | valeur à chaque arrêt | |
Relancer l'exécution | c(ont) | jusqu'au prochain point d'arrêt |
s(tep) | d'une instruction | |
n(ext) | d'une instruction (même niveau) | |
finish | pour terminer un niveau | |
until <no ligne> | jusqu'à la ligne | |
Naviguer dans la pile | up | monter d'un niveau |
down | descendre d'un niveau | |
fr(ame) <no niveau> | aller à un niveau donné | |
bt (backtrace) | afficher la pile |
3|c|Emacs (Raccourcis clavier) | ||
---|---|---|
charger/sauver | charger | CTRL-x CTRL-f |
sauvegarder | CTRL-x CTRL-s | |
sauvegarder sous (save as) | CTRL-x CTRL-w | |
quitter | CTRL-x CTRL-c | |
manipuler | changer de tampon | CTRL-x b |
les tampons | détruire un tampon | CTRL-x k |
manipuler | couper la fenêtre en deux | CTRL-x 2 |
les fenêtres | passer à une autre fenêtre | CTRL-x o |
faire occuper tout Emacs à une fenêtre | CTRL-x 1 | |
faire disparaître une fenêtre | CTRL-x 0 | |
se déplacer | un caractère à droite (forward) | CTRL-f ou |
flèche à dr. | ||
un mot à droite | MéTA-f ou | |
SHIFT-fl. à dr. | ||
un caractère à gauche (backward) | CTRL-b ou | |
flèche à g. | ||
un mot à gauche | MéTA-b ou | |
SHIFT-fl. à g. | ||
ligne suivante (next) | CTRL-n ou | |
flèche bas | ||
ligne précédente (previous) | CTRL-p ou | |
flèche haut | ||
début de ligne | CTRL-a ou Home | |
fin de ligne | CTRL-e ou End | |
phrase précédente | MéTA-a | |
phrase suivante | MéTA-e | |
page suivante | CTRL-v ou PgUp | |
page précédente | CTRL-MéTA-v ou PgDown | |
début du tampon | MéTA-< | |
fin du tampon | MéTA-> | |
centrer la ligne courante | CTRL-l |
3|c|Emacs (Raccourcis clavier, suite) | ||
---|---|---|
effacer | un caractère à gauche | BackSpace |
un caractère à droite | CTRL-d ou Delete | |
la fin d'une ligne | CTRL-k | |
une région sélectionnée | CTRL-w | |
mode remplacement | Insert | |
chercher | chercher vers l'avant du texte | CTRL-s |
chercher vers l'arrière du texte | CTRL-r | |
remplacer | remplacer | MéTA-% |
copier/coller | copier | MéTA-w |
détruire et copier | CTRL-w | |
coller | CTRL-y | |
insérer un fichier | CTRL-x i | |
manipuler les | appeler une commande | MéTA-x |
commandes | annuler la dernière commande | CTRL-x u |
répéter une commande | CTRL-u | |
aide | liste des commandes contenant | CTRL-h a |
un mot écrit dans le minibuffer | ||
liste des commandes accessibles | CTRL-h b | |
par une combinaison de touches | ||
consultation du manuel | CTRL-h i | |
description de la commande exécutée | CTRL-h k | |
par une combinaison de touches | ||
description d'une commande | CTRL-h f | |
écrite dans le minibuffer | ||
description du mode majeur | CTRL-h m | |
de la fenêtre courante | ||
tutorial | CTRL-h t | |
liste des options du help | CTRL-h h | |
description des options du help | CTRL-h CTRL-h | |
doc d'une fonction | MéTA-x man |
WIN v1.6
Bibliothèque Graphique de Base