#include <iostream>
int fact(int n)
{
if (n==1) return 1;
else return n*fact(n-1);
}
int main ()
{
int a = 5;
cout << "fact(" << a << ") = " << fact(a) << endl;
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:12La 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 = 5Dans 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
| Programme |
int main() |
{ |
... |
return 0; |
} |
| Objets |
int i; |
double x, y; |
char c; |
char s[32]; |
char a[3][3]; |
| Constantes |
const int N=10; |
| 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); |
| Passage par référence |
void max(double x, double y, |
double& z) |
{ |
if (x<y) |
z = y; |
else |
z = x; |
} |
... |
max(x, y, z); |
... |
| Portées |
// variable globale |
int a; |
// paramètres |
void hop(int b, int c) |
{ |
// variables locales |
int i, j; |
// variable statique |
static int memo; |
} |
| Initialisations |
int globale=3; |
|
void hop() |
{ |
int locale=2; |
static int statique=4; |
complexe z={1,2}; |
double tb[2]={3,4}; |
int a[]={2,4}; |
int b[][3]={{1,2,3},{4,5,6}}; |
complexe c[]={{1,2},{3,4}}; |
} |
| Conditions |
if (test) { |
... |
} |
if (test) { |
... |
} else { |
... |
} |
switch (i) { |
case 1: |
... |
break; |
case 2: |
... |
break; |
default: |
... |
} |
| Tests | |
| égal | == |
| différent | != |
| supérieur | > et >= |
| inférieur | < et <= |
| et | && |
| ou | || |
| non | ! |
| Boucles |
for (i=1;i<=n;i=i+1) { |
... |
} |
while (i<j) { |
... |
} |
do { |
... |
} while (i<j); |
| Structures |
| struct complexe{ |
| double re; |
| double im; |
| }; |
| complexe z; |
| z.re=2; |
| z.im=3; |
| struct list { |
| int val; |
| list *next; |
| }; |
enum direction { |
Nord, Est, Sud, Ouest}; |
| Contractions | |
| i=i+1; | i++; |
| (*c).a | c->a |
| &(*i) | i |
| Maths |
| #include <cmath> |
| Tableaux |
| 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++) |
cout << "tb[" << i << "]=" << i << endl; |
| ... |
| Tableaux multidim |
| // 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++) |
cout<<"tb["<<i<<"]["<<j<<"]="<<tb[i][j]<<endl; |
| ... |
| Tableaux dynamiques |
void remplit(int n, int t[]) |
{ |
... |
} |
|
int main() |
{ |
int *t; |
int n; |
|
cin >> n; |
t=new int[n]; |
remplit(n, t); |
... |
delete[] t; |
} |
| Abréviations de type |
typedef int data; |
typedef double vecteur[N]; |
typedef tree_cell *tree; |
typedef double (*fun)(double); |
| Entrées/Sorties |
#include <iostream> |
cout << i << x << c << s; |
cin >> i >> x >> c >> s; |
program < data > out |
#include <fstream> |
|
ifstream in("data"); |
if (!in) { |
cerr << "erreur de lecture\n"; |
exit(1); |
} |
in >> i >> x >> c >> s; |
in.close(); |
ofstream out("out"); |
if (!out) { |
cerr << "erreur d'écriture\n"; |
exit(1); |
} |
... |
out << "Résultats: " << n << '\t' << y << endl; |
... |
out.close(); |
#include <cstdlib> |
|
int main(int argc, char argv[]) |
{ |
string name; |
int n; |
double x; |
|
if (argc != 4) { |
cout << "Syntax: " << argv[0] << " name n x\n"; |
exit(1); |
} |
name = argv[1]; |
n=atoi(argv[2]); |
x=atof(argv[3]); |
... |
} |
| Arithmétique | |
| Modulo | j=i%n |
(attention -7%5 vaut -2) |
|
| Division réelle | x=double(i)/j; |
| x=i/2.0; | |
| Caractères |
| char c; |
cin >> c; |
| c='a'; |
cout << c; |
| Chaînes |
| #include <string> |
| string s; |
cin >> s; |
cout << s; |
| c=s[i]; |
| s[i]='a'; |
| l=s.length(); |
| dest = source; |
| if(s1 == s2) ... |
| Makefile |
| LDLIBS=... |
| 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 |
| Souris | |
| Recopier | |
| 1- Début | Clic gauche |
| 2- Fin | Clic droit |
| 3- Copier | Clic mileu |
| 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 |
| Graphiques |
| #include <win> |
| 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(millisec, ev); |
| white,black,blue,red,green,yellow,cyan,magenta |
| LDLIBS=-lwin -lXm -lXt -lX11 |
| 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) <n |
10 lignes autour | |
| l(ist) <fonction> | ||
| Interrompre l'exécution | kill | abandonner l'exécution |
| b(reak) <n |
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 <n |
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 <n |
jusqu'à la ligne | |
| Naviguer dans la pile | up | monter d'un niveau |
| down | descendre d'un niveau | |
| fr(ame) <n |
aller à un niveau donné | |
| bt (backtrace) | afficher la pile | |
| 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 | |
| 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 | |