Pointeurs et tableaux
Le pointeur est une variable destinée à contenir une adresse mémoire. Il est reconnu syntaxiquement par l’* lors de sa déclaration. Comme les adresses, le pointeur est associé à un type d’objet. Ce type est celui des objets qui sont manipulés grâce au pointeur. L’objet peut être une variable ou une fonction.
Contrairement à ce que beaucoup d’apprentis espèrent, la déclaration d’un pointeur n’implique pas la déclaration implicite d’une variable associée et l’affectation de l’adresse de la variable au pointeur.
Il faut donc déclarer une variable du type correspondant et initialiser le pointeur avec l’adresse de cette variable. Par convention, l’adresse 0 est invalide et si le programme cherche à y accéder, il obtient une erreur d’exécution du type bus-error sur UNIX. Ce comportement implique que l’utilisation de pointeurs globaux sans initialisation mène à ce résultat, car les pointeurs (comme les autres variables) déclarés en variables globales sont initialisés à 0.
Les pointeurs déclarés en variable locale (comme toutes les variables locales) ont des valeurs initiales dépendantes du contenu de la pile à cet instant, qui dépend de l’exécution précédente du programme mais correspond en général à n’importe quoi. Le comportement du programme qui utilise un pointeur local sans l’avoir affecté convenablement peut donner des comportements tels que violation de l’espace mémoire, mais parfois le pointeur reçoit une adresse valide et le programme se déroule sans erreurs flagrante mais en donnant des résultats faux (ce que d’aucuns appellent un effet de bord indésirable, ce que d’autres appellent un bug difficile à reproduire).
Voici deux exemples de définition de pointeurs :
int *ptint; pointeur sur un entier
char *ptchar; pointeur sur un caractère.
Le compilateur C vérifie le type des adresses qui sont affectées à un pointeur. Le type du pointeur conditionne les opérations arithmétiques sur ce pointeur.
Les opérations possibles sur un pointeur sont les suivantes :
– affectation d’une adresse au pointeur ;
– utilisation du pointeur pour accéder à l’objet dont il contient l’adresse;
– addition d’un entier (n) à un pointeur; la nouvelle adresse est celle du n e objet à partir de l’adresse initiale;
– soustraction de deux pointeurs du même type. Le calcul est réalisé dans les mêmes conditions que la différence entre deux adresses de variables contenues dans un même tableau. La soustraction calcule le nombre de variables entre les adresses contenues dans les pointeurs. Le résultat de type ptrdiff_t n’est valide que si les adresses contenues dans les deux pointeurs sont bien des adresses de variables appartenant à un même tableau, sinon le résultat est indéfini.
Le tableau 10.1 est un exemple de manipulations en relation avec les pointeurs et les tableaux en utilisant les variables : long x[10], *px , y;
L’addition décrite dans la dernière ligne du tableau 10.1 se traduit par les conversions suivantes :
px = (long *) ( (int) px + i * sizeof (long));
Le tableau 10.2 est un exemple de soustraction à partir des définitions de variables suivantes : int tab[20], *pt1, *pt2; ptrdiff_t i;
1 Historique et présentation
1.1 Historique
1.2 Présentation du langage
1.3 Idées fondamentales
1.4 Enchaîneur de passes
1.4.1 Pré-processeur
1.4.2 Compilateur
1.4.3 Optimiseur de code
1.4.4 Assembleur
1.4.5 Éditeur de liens
1.4.6 Quelques options de cc
2 Généralités sur la syntaxe
2.1 Mise en page
2.1.1 Identifiant
2.1.2 Espaces lexicaux
2.2 Mots réservés
2.3 Constantes
2.4 Instructions
3 Types et variables
3.1 Types de base
3.1.1 Types entiers
3.1.2 Types avec parties décimales
3.1.3 Tailles des types
3.2 Constantes associées aux types de base
3.2.1 Constantes de type entier
3.2.2 Constantes avec partie décimale
3.2.3 Constantes de type caractère
3.2.4 Chaînes de caractères
3.3 Qualificatifs
3.4 Taille et normalisation
3.5 Définition de variables
3.6 Types dérivés des types de base
3.6.1 Tableaux et structures
3.6.2 Pointeurs
3.7 Initialisation de variables
3.8 Conversion de type
3.8.1 Conversions implicites
3.9 Déclaration et définition
3.10 Exercices sur les types et variables
3.10.1 Exercice 1
3.10.2 Exercice 2
3.10.3 Exercice 3
3.10.4 Exercice 4
4 Éléments de base
4.1 Bonjour
4.2 Lire et écrire
4.3 Quelques opérations
4.4 Plus sur printf() et scanf()
4.5 Exercices sur printf() et scanf()
4.5.1 Exercice 1
4.5.2 Exercice 2
4.5.3 Exercice 3
4.5.4 Exercice 4
5 Opérateurs et expressions
5.1 Opérateurs un-aires
5.1.1 Opérateur de référencement
5.1.2 Opérateur de déréférencement ou indirection
5.1.3 Utilisation des& et *
5.1.4 Opérateurs d’incrémentation et de décrémentation
5.1.5 Opérateur de taille
5.1.6 Opérateur de négation logique
5.1.7 Plus et moins unaires
5.1.8 Complément à un
5.2 Opérateurs binaires
5.2.1 Opérateurs arithmétiques
Support de cours de langage C (604 KO) (Cours PDF)