IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo

FAQ CConsultez toutes les FAQ

Nombre d'auteurs : 35, nombre de questions : 194, dernière mise à jour : 18 février 2018  Ajouter une question

 

Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums de www.developpez.com et de l'expérience personnelle des auteurs.

Je tiens à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes ; les auteurs font le maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez devenir rédacteur, lisez ceci .

Sur ce, je vous souhaite une bonne lecture.

SommaireLes types et les variablesGénéralités (11)
précédent sommaire suivant
 

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.

Mis à jour le 20 septembre 2004 gl

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 :

Code C : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
+--------------------+-----------------------+----------------------+----------------------+ 
|        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).

Mis à jour le 29 novembre 2004 gl

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). Ils 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.

Mis à jour le 27 juillet 2008 Melem

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.

Mis à jour le 27 juillet 2008 Melem

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.

Mis à jour le 27 juillet 2008 Melem

Il permet de connaître la taille, en bytes, d'une variable ou d'un type.

Mis à jour le 27 juillet 2008 Melem

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 :

Code C : Sélectionner tout
1
2
3
#define BOOL int 
#define TRUE  1 
#define FALSE 0
Ou :

Code C : Sélectionner tout
1
2
3
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 :

Code C : Sélectionner tout
1
2
3
4
5
6
#ifndef    __bool_true_false_are_defined 
#   define   bool   int 
#   define   true    1 
#   define   false   0 
#   define __bool_true_false_are_defined 
#endif

Mis à jour le 31 janvier 2003 David.Schris gege2061 LFE

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.

Mis à jour le 27 juillet 2008 Melem

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. À 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.

Code c : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
#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; 
}

Mis à jour le 23 mars 2009 Melem

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 deuxième nom, ENTIER, à int.

  1. Prenons 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 :

Code c : Sélectionner tout
1
2
3
4
5
6
7
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;  */

Mis à jour le 1er février 2003 gl LFE Melem

L'erreur « undefined reference to xxx » ou « symbol not found » est émise par l'éditeur de liens (linker en anglais) lorsqu'il ne trouve pas la définition d'un symbole déclaré dans une ou plusieurs unités de compilation. Les deux messages dénotent de la même erreur et la formulation employée dépend du compilateur.

Voici un code qui produit une telle erreur :

Code C : Sélectionner tout
1
2
3
4
5
6
7
void f(void); 
  
int main(void) 
{ 
  f(); 
  return 0; 
}
Voici l'erreur émise par MinGW 5.3 sous Windows :

main.c:5: undefined reference to `f'
collect2.exe: error: ld returned 1 exit status
Voici l'erreur émise par gcc 4.8.2 sous Mac OS X :

Undefined symbols for architecture x86_64:
"_f", referenced from:
_main in ccpPQxzc.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
On voit clairement que l'erreur est émise par ld, l'éditeur de liens de la chaîne GCC. Lors de la compilation (au sens propre, c'est-à-dire pour transformer les fichiers source en fichiers objet), il n'y a pas de problème. La fonction f est déclarée et utilisée de manière correcte. Lors de l'édition des liens (c'est-à-dire pour assembler les fichiers objet en un fichier exécutable), il y a un problème. Il n'existe aucune définition de la fonction f. Une erreur est donc générée pour indiquer qu'un symbole (la fonction f) n'est pas trouvé.

Lorsqu'une telle erreur se produit, il faut vérifier :

  • qu'un autre fichier source contient bien la définition du symbole ;
  • que tous les fichiers source sont correctement ajoutés au projet et seront bien utilisés lors de l'édition des liens ;
  • qu'une bibliothèque contient la définition du symbole ;
  • que cette bibliothèque est correctement ajoutée au projet et sera bien utilisée lors l'édition des liens ;
  • que la déclaration du symbole est correcte (par exemple, déclarer void setup(void); au lieu de void Setup(void);.

Mis à jour le 25 novembre 2017

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.