
FAQ CConsultez toutes les FAQ
Nombre d'auteurs : 28, nombre de questions : 175, création le 11 janvier 2013
Sommaire→Les types et les variables→Généralités- Quelle est la taille d'un char ?
- Quelle est la taille des différents types ?
- Que signifient signed et unsigned ?
- Quelle est la différence entre char, signed char et unsigned char ?
- Pourquoi mon compilateur ne connaît pas le type long long ?
- Quel est le rôle de l'opérateur sizeof ?
- Existe-t-il un type booléen en C ?
- Qu'est-ce que le type size_t ?
- Qu'est-ce que le type wchar_t ?
- Comment créer un synonyme d'un type existant ?
Par définition, sizeof(char) vaut 1, c'est-à-dire qu'un char représente un byte. Toutefois, contrairement à une idée répandue, en langage C un byte (multiplet et non octet) ne fait pas forcément 8 bits. La norme requiert néanmoins qu'un byte doit faire au moins 8 bits et la taille exacte d'un char, en bits, est donnée par la macro CHAR_BIT définie dans le fichier limits.h.
La norme n'impose pas la taille d'un type, cette taille dépend donc de l'implémentation. Toutefois la norme impose des plages minimales pour chaque type :
+--------------------+-----------------------+----------------------+----------------------+
| Type | min minimum imposé | max minimum imposé | => Taille min : |
+--------------------+-----------------------+----------------------+----------------------+
| signed char | -127 | 127 | |
+--------------------+-----------------------+----------------------+ 8 bits |
| unsigned char | 0 | 255 | |
+--------------------+-----------------------+----------------------+----------------------+
| short | -32767 | 32767 | |
+--------------------+-----------------------+----------------------+ 16 bits |
| unsigned short | 0 | 65535 | |
+--------------------+-----------------------+----------------------+----------------------+
| int | -32767 | 32767 | |
+--------------------+-----------------------+----------------------+ 16 bits |
| unsigned int | 0 | 65535 | |
+--------------------+-----------------------+----------------------+----------------------+
| long | -2147483647 | 2147483647 | |
+--------------------+-----------------------+----------------------+ 32 bits |
| unsigned long | 0 | 4294967295 | |
+--------------------+-----------------------+----------------------+----------------------+
| long long | -9223372036854775807 | 9223372036854775807 | |
+--------------------+-----------------------+----------------------+ 64 bits |
| unsigned long long | 0 | 18446744073709551615 | |
+--------------------+-----------------------+----------------------+----------------------+
De plus la relation 'sizeof(short) <= sizeof(int) <= sizeof(long)' doit toujours être vérifiée.
Les valeurs effectives des limites pour chaque type sont définies par l'implémentation et se trouvent dans les fichiers limits.h (pour les entiers) et float.h (pour les flottants).
Ces mot-clés ne peuvent s'utiliser qu'avec les types entiers c'est-à-dire char, short (short int), int, long (long int) et long long (long long int). Il permettent d'indiquer si le type supporte des valeurs négatives (signed) ou non (unsigned). Sur un type autre que char, signed est toujours facultatif.
Le type char désigne, selon l'implémentation, signed char ou unsigned char. Le type réel du type char doit être indiqué dans la documentation du compilateur.
Parce que ce type n'a été introduit qu'avec la norme C99. Vous utilisez probablement un compilateur non conforme à cette norme ou peut-être que les réglages de votre compilateur sont tels que seules les fonctionnalités C90 sont activées.
Il permet de connaître la taille, en bytes, d'une variable ou d'un type.
Avant la norme C99, il n'existait pas en C de type booléen à proprement parler, mais il est très simple à 'créer' si le compilateur utilisé ne le propose pas déjà en utilisant :
#define BOOL int
#define TRUE 1
#define FALSE 0
Ou :
typedef enum {
FALSE, TRUE
} BOOL;
En effet, en C, toute valeur nulle (0, 0.0, etc.) désigne un 'faux' tandis que toute valeur non nulle (1, -1, 2.0, etc.) désigne un 'vrai'.
La norme C99 introduit le type _Bool et l'en-tête stdbool.h définit les macros bool (_Bool), true (1) et false (0) ainsi que
__bool_true_false_are_defined qui permet de savoir si les booléens sont nativement supportés.
Une solution permettant d'écrire du code compatible C99 consiste à utiliser les types natifs sur un compilateur conforme C99 et définir un
type booléen maison dans le contraire. Par exemple :
#ifndef __bool_true_false_are_defined
# define bool int
# define true 1
# define false 0
# define __bool_true_false_are_defined
#endif
Ce type défini dans stddef.h (qui est inclus par de nombreux fichiers d'en-tête ...) correspond au type de la valeur retournée par l'opérateur sizeof. La norme requiert que size_t soit un entier non signé mais le type exact auquel il correspond dépend de l'implémentation.
wchar_t (wide character) est le type qui permet de représenter n'importe quel élément du jeu de caractères courant de l'environnement. Il peut être défini à l'aide d'un typedef ou être nativement supporté par le compilateur.
A noter que char et wchar_t étant des types différents, un caractère "large" (un caractère de type wchar_t) ne s'écrit pas de la même façon qu'un simple caractère. Les caractères larges doivent toujours être précédés d'un L. Par exemple L'A',
L'*' et L'1' sont des caractères larges. C'est valable également pour les chaînes de caractères larges, par exemple : L"Bonjour" au lieu de "Bonjour". De même, les fonctions de manipulation des caractères et/ou chaînes de caractères larges ne
sont pas les mêmes que celles qui sont dédiées aux caractères et/ou chaînes de caractères simples bien que l'on puisse noter une certaine similitude au niveau des noms et des paramètres requis. Par exemple, pour les caractères et chaînes de caractères
larges, on utilise wprintf à la place de printf, wcscpy à la place de strcpy, iswalpha à la place de isalpha, etc. Selon les fonctions que vous utilisez, vous devez inclure wchar.h et/ou wctype.h.
Le programme suivant montre un exemple d'utilisation des caractères larges.
#include <stdio.h>
#include <wchar.h>
int main()
{
wchar_t ws[256];
wcscpy(ws, L"Hello");
wcscat(ws, L", world !");
wprintf(L"%s\n", ws);
return 0;
}
Dans certains cas très simples, un #define peut déjà faire l'affaire (par exemple : #define ENTIER int). Dans des cas un peu plus complexes,
il faudra définir le synonyme à l'aide du mot-clé typedef. Pour ce faire, il suffit, dans une déclaration valide d'une variable du type voulu,
remplacer l'identifiant de la variable par le nom qu'on veut donner à son type puis de commencer la ligne par "typedef".
Supposons par exemple que nous souhaitons définir un synonyme pour le type int en utilisant cette méthode. Nous allons donc donner un dexuième nom, ENTIER, à int.
1. Prennons donc une déclaration valide d'une variable de type int : int x;
2. Remplaçons l'identifiant de la variable (x) par le nom qu'on veut donner au type (ENTIER) : int ENTIER;
3. Ajoutons enfin le mot-clé typedef : typedef int ENTIER;
Voici quelques exemples supplémentaires :
typedef int VECTEUR[3];
typedef void * POINTEUR;
typedef struct { int value; } INTVALUE;
VECTEUR u, v; /* int u[3], int v[3]; */
POINTEUR p1, p2; /* void * p1, * p2; */
INTVALUE n; /* struct { int value; } n; */



