Le C est un langage de programmation impératif, proche du langage machine, inventé par Dennis Ritchie en 1972. Ce langage révolutionna l'informatique.
Dennis MacAlistair Ritchie (né en 1941 à Bronxville dans l'Etat de NewYork, décédé en 2011 à Berkeley Heights dans le New Jersey) est un des pionniers de l'informatique moderne, inventeur du langage C et co-développeur de Unix. Il est parfois désigné par dmr, son adresse e-mail aux Laboratoires Bell.
Selon la norme ANSI C99 :
Type Taille en octet Intervalle de valeur _Bool 10 et 1 char 1-128 à 127
0 à 255 signed char 1-128 à 127 unsigned char 10 à 255 int 2 ou 4-32 768 à 32 767
-2 147 483 648 à 2 147 483 647 unsigned int 2 ou 40 à 65535
0 à 4 294 967 295 short 2-32 768 à 32 767 unsigned short 20 à 65535 long 4-2 147 483 648 à 2 147 483 647 unsigned long 40 à 4 294 967 295 long long 8-9 223 372 036 854 775 808 à
9 223 372 036 854 775 807 unsigned long long 80 à 18 446 744 073 709 551 615
Bornes déclarées dans limit.h :
Type Minimum
Maximum
_Bool 0 1 char CHAR_MIN CHAR_MAX signed char SCHAR_MIN SCHAR_MAX unsigned char 0 UCHAR_MAX int INT_MIN INT_MAX unsigned int 0 UINT_MAX short SHRT_MIN SHRT_MAX unsigned short 0 USHRT_MAX long LONG_MIN LONG_MAX unsigned long 0 ULONG_MAX long long LLONG_MIN LLONG_MAX unsigned long long 0 ULLONG_MAX
Représentations des constantes entières :
Préfixe Représentation Exemple BaseDécimale 1234 10 0Octale 01234 8 0xHexadécimale 0x1234 16
Constante entières :
Suffixe Exemple Type12 int L 12L long UL 12UL unsigned long LL 12LL long long ULL 12ULL unsigned long long
Selon la norme IEEE 754-1985 :
Type Taille en octet Intervalle de valeur Nombre de chiffres
après la virgule float 41.2E-38 à 3.4E+38 6 double 82.3E-308 à 1.7E+308 15 long double 123.4E-4932 à 1.1E+4932 19
Types déclaré dans complex.h :
Type Taille en octet float complex 8 double complex 16 long double complex 24
Bornes déclarées dans float.h :
float
double
double float
Nombre de chiffres après la virgule FLT_DIG DBL_DIG LDBL_DIG Exposant négatif minimal FLT_MIN_10_EXP DBL_MIN_10_EXP LDBL_MIN_10_EXP Exposant positif maximal FLT_MAX_10_EXP DBL_MAX_10_EXP LDBL_MAX_10_EXP Minimum strictement positif FLT_MIN DBL_MIN LDBL_MIN Maximum FLT_MAX DBL_MAX LDBL_MAX Minimum strictement positif x tel que 1.0+x ≠ 1.0 FLT_EPSILON DBL_EPSILON LDBL_EPSILON
Constantes réelles avec exposant : 1.2E+3, 1.2e+3, 1.2E3, 1.2e3
Constantes réelles et complexes :
Suffixe Exemple Type F1.2F float iF1.2iF float complex 1.2 double i1.2i double complex L1.2L long double iL1.2IL long double complex
Etant donnée une variable x d'un type T élémentaire ou structuré, la variable x contient une valeur de type T. On dira que x est un T.
La variable x contient sa valeur dans un block mémoire contigü dont la taille est égale à sizeof(T), la taille des éléments de type T. L'adresse de ce block mémoire, appelée adresse de la variable x, appelé pointeur sur x, est donné par &x. Le type de cette valeur &x est T*. On dira que c'est un pointeur de T.
On définie plusieurs variables a, b, c contenant des pointeurs de T comme suit :
T *a, *b, *c;
On a ainsi définie 3 pointeurs a,b,c. Ces pointeurs ne sont pas initialisés. Ils peuvent pointer n'importe où, et les blocks mémoires sur lesquels ils pointent ne sont pas alloués.
Les pointeurs ont des propriétés arithmétiques. On peut les incrémenter :
Pour accéder aux valeurs qu'elles pointent on utilise l'opérateur unaire * :
Considérons une variable x de type T et une variable a de type T* que l'on initialise à la valeur &x :
T x;
T *a;
a = &x;
a est un pointeur de T. Après ces instructions a pointe sur x. Délors *a désigne la même valeur que x. Mais plus que cela, il désigne le même emplacement mémoire. Toutes modification de *a se répercute instantanément sur x et inversement car *a représente la même variable que x.
La déclaration d'un tableau x comme suit T x[50] correspond à la déclaration d'un pointeur x comme suit T *x avec une information supplémentaire qui est le nombre de blocks utilisés (ici 50). Mais cette information n'est utilisée que pour l'allocation initiale de mémoire. Aucun teste n'est fait pour vérifier si l'indice d'un appel sort des limites du tableau.
On définie plusieurs variables a, b, c contenant des tableau de T comme suit :
T a[5], b[30], c[10];
La taille d'une addresse mémoire est généralement égale à 4 octects. Tout pointeur quelque soit le type qu'il pointe occupe cette même taille mémoire.
Un type structuré représente un block mémoire contigü découpé en une succession de sous-block, appelés champs, correspondant à différents types élémentaires ou eux-même structurés.
Le tableau T x[50] est un type structuré implicite, un block constitué de 50 sous-blocks ou champs de type T. Pour rendre la structure explicite, on l'enrobe dans une instruction struct comme suit :
struct {T x[50];} m;
Dans cette exemple le type est struct {T x[50];} et la variable est m. Cette instruction déclare un tableau m de 50 éléments de type T. Les indices sont compris entre 0 et 49. Pour accéder à l'élément d'indice 3, il faut écrire le terme m.x[3]. Ce terme semble plus complexe que le terme x[3] d'une structure de tableau implicite, mais il n'en est rien. Le compilateur traduit ces deux instructions exactement de la même façon.
Les champs des structures subissent des contraintes d'alignement dépendant du système sous-jacent, qui engendre des trous anonymes entre les champs. Certain champs doivent commencer à des adresses multiples de leur taille ou de 4. Souvent la taille d'une structure correspond à un nombre d'octets multiple de 4.
On peut nommer les nouveaux types que l'on définie en insérant un nom juste après le mot clef struct.
struct tab {T x[50];}
Dans cette instruction, le type défini se nomme struct tab. Et il est possible de l'utiliser pour définir des variables ainsi que d'autres types, et souvent les deux à la fois :
struct tab m, *a, b[50];
struct toto {struct tab x; int y; char c;};
struct titi {struct tab v[5];} w;
Une variable de type structurée peut être initialisée au moment de sa déclaration par un emboitement d'ensembles. Si on indique moins de valeurs que la structure ne comporte de champs, alors les champs restants sont initialisés par des zéros. Par contre, donner plus de valeurs qu'il n'y a de champs constitue une erreur.
struct { int x[3], struct {int x; long y;} h[2]} m = {{1,2,3}, {{4,5}, {6,7}}};
La variable m est initialisée, et nous avons m.h[1].y = 7.
L'initialisation d'une chaine de caractère peut se faire ainsi :
char *x = {'B', 'o', 'n', 'j', 'o', 'u', 'r', 0}
char *y = "Bonjour"
char z[8] = "Bonjour\0"
Pour les autres types de tableau il est nécessaire d'employer la notation suivante :
int x[ ] = {1,2,3,4,5}
La taille de x sera alors d'exactement 5*sizeof(int). Noter que x est de type int*. c'est un pointeur de int. Nous avons :
*x = x[0]
*(x+1) = x[1]
*(x+2) = x[2]
---- 4 Janvier 2013 ----