cours c/c++

Approche du C++

Quelques bases avant les bases, pour bien commencer avec C++. Avant même d'écrire du code, il y a certaines choses à savoir, à respecter... Petit tout d'horizon

1. Les commentaires en C++

Les commentaires sont nécessaires et très simples à faire. Tout programme doit être commenté. Attention cependant, trop de commentaires tue le commentaire, parce que les choses importantes sont noyées dans les banalités. Il existe deux types de commentaires en C++ : les commentaires de type C et les commentaires de fin de ligne (qui ne sont disponibles qu'en C++). Les commentaires C commencent avec la séquence barre oblique - étoile. Les commentaires se terminent avec la séquence inverse : une étoile suivie d'une barre oblique.

Exemple, Commentaire C

/* Ceci est un commentaire C */

Ces commentaires peuvent s'étendre sur plusieurs lignes. En revanche, les commentaires de fin de lignes s'arrêtent à la fin de la ligne courante, et pas avant. Ils permettent de commenter plus facilement les actions effectuées sur la ligne courante, avant le commentaire. Les commentaires de fin de ligne commencent par la séquence constituée de deux barres obliques (ils n'ont pas de séquence de terminaison, puisqu'ils ne se terminent qu'à la fin de la ligne courante). Par exemple :

Exemple, Commentaire C++

action quelconque // Ceci est un commentaire C++
action suivante

2. Les types prédéfinis du C++

Le C++, est un langage typé. Cela signifie que chaque entité manipulée dans les programmes doit disposer d'un type de donnée grâce auquel le compilateur pourra vérifier la validité des opérations qu'on lui appliquera. La prise en compte du type des données peut apparaître comme une contrainte pour le programmeur, mais en réalité il s'agit surtout d'une aide à la détection des erreurs. Il existe plusieurs types prédéfinis. Ce sont :

  • le type vide : void. Ce type est utilisé pour spécifier le fait qu'il n'y a pas de type. Cela a une utilité pour faire des procédures (fonctions ne renvoyant rien) et les pointeurs sur des données non typées
  • les booléens : bool, qui peuvent prendre les valeurs true et false (en C++ uniquement, ils n'existent pas en C)
  • les caractères : char
  • les caractères longs : wchar_t (ce n'est un type de base que pour le langage C++, mais il est également défini dans la bibliothèque standard C et est donc utilisable malgré tout en C)
  • les entiers : int
  • les réels : float
  • les réels en double précision : double
  • les tableaux à une dimension, dont les indices sont spécifiés par des crochets ('[' et ']')

Pour les tableaux de dimension supérieure ou égale à 2, on utilisera des tableaux de tableaux

  • les structures, unions et énumérations.

Les types entiers (int) peuvent être caractérisés d'un des mots clés long ou short. Ces mots clés permettent de modifier la taille du type, c'est-à-dire la plage de valeurs qu'ils peuvent couvrir. De même, les réels en double précision peuvent être qualifiés du mot clé long, ce qui augmente leur plage de valeurs. On ne peut pas utiliser le mot clé short avec les double. On dispose donc de types additionnels :

  • les entiers longs : long int, ou long (int est facultatif)
  • les entiers courts : short int, ou short
  • les réels en quadruple précision : long double

Note : Attention ! Il n'y a pas de type de base permettant de manipuler les chaînes de caractères. En C++, les chaînes de caractères sont en réalité des tableaux de caractères. La taille des types n'est spécifiée dans aucune norme. La seule chose qui est indiquée dans la norme C++, c'est que le plus petit type est le type char. Les tailles des autres types sont donc des multiples de celle du type char. De plus, les inégalités suivantes sont toujours vérifiées :

char = short int = int = long int
float = double = long double

Les tailles des types sont généralement les mêmes pour tous les environnements de développement. Le type char est généralement codé sur un octet (8 bits), le type short int sur deux octets et le type long int sur quatre octets. Le type int est celui qui permet de stocker les entiers au format natif du processeur utilisé. Il est donc codé sur deux octets sur les machines 16 bits et sur quatre octets sur les machines 32 bits. Enfin, la taille des caractères de type wchar_t n'est pas spécifiée et dépend de l'environnement de développement utilisé. Ils sont généralement codés sur deux ou sur quatre octets suivant la représentation utilisée pour les caractères larges. Note : Remarquez que, d'après ce qui précède, le type int devrait être codé sur 64 bits sur les machines 64 bits. Le type long int devant lui être supérieur, il doit également être codé sur 64 bits ou plus. Le type short int peut alors être sur 16 ou sur 32 bits. Il n'existe donc pas, selon la norme, de type permettant de manipuler les valeurs 16 bits sur les machines 64 bits si le type short int est codé sur 32 bits, ou, inversement, de type permettant de manipuler les valeurs 32 bits si le type short int est codé sur 16 bits.

Afin de résoudre ces problèmes, la plupart des compilateurs brisent la règle selon laquelle le type int est le type des entiers natifs du processeur, et fixent sa taille à 32 bits quelle que soit l'architecture utilisée. Ainsi, le type short est toujours codé sur 16 bits, le type int sur 32 bits et le type long sur 32 ou 64 bits selon que l'architecture de la machine est 32 ou 64 bits. Autrement dit, le type qui représente les entiers nativement n'est plus le type int, mais le type long. Cela ne change pas les programmes 32 bits, puisque ces deux types sont identiques dans ce cas. Les programmes destinés aux machines 64 bits pourront quant à eux être optimisés en utilisant le type long à chaque fois que l'on voudra utiliser le type de données natif de la machine cible. Les programmes 16 bits en revanchent ne sont en revanche plus compatibles avec ces règles, mais la plupart des compilateurs actuels ne permettent plus de compiler des programmes 16 bits de toutes manières.

Les types char, wchar_t et int peuvent être signés ou non. Un nombre signé peut être négatif, pas un nombre non signé. Par défaut, les nombres entiers sont signés. Le signe des types char et wchar_t dépend du compilateur utilisé, il est donc préférable de spécifier systématiquement si ces types sont signés ou non lorsqu'on les utilise en tant que type entier. Pour préciser qu'un nombre n'est pas signé, il faut utiliser le mot clé unsigned. Pour préciser qu'un nombre est signé, on peut utiliser le mot clé signed. Ces mots clés peuvent être intervertis librement avec les mots clés long et short pour les types entiers.

Exemple, Types signés et non signés:

  • unsigned char
  • signed char
  • unsigned wchar_t
  • signed wchar_t
  • unsigned int
  • signed int
  • unsigned long int
  • long unsigned int

Note : Le C++ (et le C++ uniquement) considère les types char et wchar_t comme les types de base des caractères. Le langage C++ distingue donc les versions signées et non signées de ces types de la version dont le signe n'est pas spécifié, puisque les caractères n'ont pas de notion de signe associée. Cela signifie que les compilateurs C++ traitent les types char, unsigned char et signed char comme des types différents, et il en est de même pour les types wchar_t, signed wchar_t et unsigned wchar_t. Cette distinction n'a pas lieu d'être au niveau des plages de valeurs si l'on connaît le signe du type utilisé en interne pour représenter les types char et wchar_t, mais elle est très importante dans la détermination de la signature des fonctions, en particulier au niveau du mécanisme de surcharge des fonctions.

Les valeurs accessibles avec les nombres signés ne sont pas les mêmes que celles accessibles avec les nombres non signés. En effet, un bit est utilisé pour le signe dans les nombres signés. Par exemple, si le type char est codé sur 8 bits, on peut coder les nombres allant de 0 à 255 avec ce type en non signé (il y a 8 chiffres binaires, chacun peut valoir 0 ou 1, on a donc 2 puissance 8 combinaisons possibles, ce qui fait 256). En signé, les valeurs s'étendent de -128 à 127 (un des chiffres binaires est utilisé pour le signe, il en reste 7 pour coder le nombre, donc il reste 128 possibilités dans les positifs comme dans les négatifs. 0 est considéré comme positif. En tout, il y a autant de possibilités.).

De même, si le type int est codé sur 16 bits (cas des machines 16 bits), les valeurs accessibles vont de -32768 à 32767 ou de 0 à 65535 si l'entier n'est pas signé. C'est le cas sur les PC en mode réel (c'est-à-dire sous DOS) et sous Windows 3.x. Sur les machines fonctionnant en 32 bits, le type int est stocké sur 32 bits : l'espace des valeurs disponibles est donc 65536 fois plus large. C'est le cas sur les PC en mode protégé 32 bits (Windows 9x ou NT, DOS Extender, Linux) et sur les Macintosh. Sur les machines 64 bits, le type int devrait être 64 bits (DEC Alpha et la plupart des machines UNIX par exemple).

Enfin, le type float est généralement codé sur 4 octets, et les types double et long double sont souvent identiques et codés sur 8 octets.

Note : On constate donc que la portabilité des types de base est très aléatoire. Cela signifie qu'il faut faire extrêmement attention dans le choix des types si l'on veut faire du code portable (c'est-à-dire qui compilera et fonctionnera sans modification du programme sur tous les ordinateurs). Il est dans ce cas nécessaire d'utiliser des types de données qui donnent les mêmes intervalles de valeurs sur tous les ordinateurs. La norme ISO C99 impose de définir des types portables afin de régler ces problèmes sur toutes les architectures existantes. Ces types sont définis dans le fichier d'en-tête stdint.h. Il s'agit des types int8_t, int16_t, int32_t et int64_t, et de leurs versions non signées uint8_t, uint16_t, uint32_t et uint64_t. La taille de ces types en bits est indiquée dans leur nom et leur utilisation ne devrait pas poser de problème.

De la même manière, deux représentations d'un même type peuvent être différentes en mémoire sur deux machines d'architectures différentes, même à taille égale en nombre de bits. Le problème le plus courant est l'ordre de stockage des octets en mémoire pour les types qui sont stockés sur plus d'un octet (c'est-à-dire quasiment tous). Cela a une importance capitale lorsque des données doivent être échangées entre des machines d'architectures a priori différentes, par exemple dans le cadre d'une communication réseau, ou lors de la définition des formats de fichiers. Une solution simple est de toujours d'échanger les données au format texte, ou de choisir un mode de représentation de référence. Les bibliothèques réseau disposent généralement des méthodes permettant de convertir les données vers un format commun d'échange de données par un réseau et pourront par exemple être utilisées.

3. Notation des valeurs

Les entiers se notent de la manière suivante :

base 10 (décimale) : avec les chiffres de '0' à '9', et les signes '+' (facultatif) et '-'.

Exemple, notation des entiers en base 10

12354, -2564

base 16 (hexadécimale) : avec les chiffres '0' à '9' et 'A' à 'F' ou 'a' à 'f' (A=a=10, B=b=11, F=f=15).

Les entiers notés en hexadécimal devront toujours être précédés de « 0x » (qui indique la base). On ne peut pas utiliser le signe '-' avec les nombres hexadécimaux.

Exemple, notation des entiers en base 16

0x1AE

Base 8 (octale) : avec les chiffres de '0' à '7'. Les nombres octaux doivent être précédés d'un 0 (qui indique la base). Le signe '-' ne peut pas être utilisé.

Exemple, notation des entiers en base 8

01, 0154

Les flottants (pseudo réels) se notent de la manière suivante :

[signe] chiffres [.[chiffres]][e|E [signe] exposant][f]

où signe indique le signe. On emploie les signes '+' (facultatif) et '-' aussi bien pour la mantisse que pour l'exposant. 'e' ou 'E' permet de donner l'exposant du nombre flottant. L'exposant est facultatif. Si on ne donne pas d'exposant, on doit donner des chiffres derrière la virgule avec un point et ces chiffres. Le suffixe 'f' permet de préciser si le nombre est de type float ou non (auquel cas il s'agit d'un double).

Les chiffres après la virgule sont facultatifs, mais pas le point. Si on ne met ni le point, ni la mantisse, le nombre est un entier décimal.

Exemple, notation des réels

-123.56f, 12e-12, 2

« 2 » est entier, « 2.f » est réel.

Les caractères se notent entre guillemets simples :

'A', 'c', '('

On peut donner un caractère non accessible au clavier en donnant son code en octal, précédé du caractère '\'. Par exemple, le caractère 'A' peut aussi être noté '\101'. Remarquez que cette notation est semblable à la notation des nombres entiers en octal, et que le '0' initial est simplement remplacé par un '\'. Il est aussi possible de noter les caractères avec leur code en hexadécimal, à l'aide de la notation « \xNN », où NN est le code hexadécimal du caractère. Enfin, il existe des séquences d'échappement particulières qui permettent de coder certains caractères spéciaux plus facilement. Les principales séquences d'échappement sont les suivantes :

  • '\a' Bip sonore
  • '\b' Backspace
  • '\f' Début de page suivante
  • ' ' Retour à la ligne (sans saut de ligne)
  • ' ' Passage à la ligne
  • '\t' Tabulation
  • '\v' Tabulation verticale

D'autres séquences d'échappement sont disponibles, afin de pouvoir représenter les caractères ayant une signification particulière en C :

  • '\\' Le caractère \
  • '\"' Le caractère "
  • '\'' Le caractère '

Bien qu'il n'existe pas à proprement parler de chaînes de caractères en C++, il est possible de définir des tableaux de caractères constants utilisables en tant que chaînes de caractères en donnant leur contenu entre doubles guillemets :

"Exemple de chaîne de caractères..."

Les caractères spéciaux peuvent être utilisés directement dans les chaînes de caractères constantes :

"Ceci est un saut de ligne : Ceci est à la ligne suivante."

Si une chaîne de caractères constante est trop longue pour tenir sur une seule ligne, on peut concaténer plusieurs chaînes en les juxtaposant :

"Ceci est la première chaîne " "ceci est la deuxième."

produit la chaîne de caractères complète suivante :

 

"Ceci est la première chaîne ceci est la deuxième."

Note : Attention : il ne faut pas mettre de caractère nul dans une chaîne de caractères. Ce caractère est en effet le caractère de terminaison de toute chaîne de caractères. Enfin, les versions longues des différents types cités précédemment (wchar_t, long int et long double) peuvent être notées en faisant précéder ou suivre la valeur de la lettre 'L'. Cette lettre doit précéder la valeur dans le cas des caractères et des chaînes de caractères et la suivre quand il s'agit des entiers et des flottants. Par exemple :

L"Ceci est une chaîne de wchar_t."
2.3e5L

4. La définition des variables

Les variables simples peuvent être définies avec la syntaxe suivante :

type identificateur;

où type est le type de la variable et identificateur est son nom. Il est possible de créer et d'initialiser une série de variables dès leur création avec la syntaxe suivante :

type identificateur[=valeur][, identificateur[=valeur][...]];

Exemple, définition de variables

int i=0, j=0; // Définit et initialise deux entiers à 0
double somme; // Déclare une variable réelle

Les variables peuvent être définies quasiment n'importe où dans le programme. Cela permet de ne définir une variable temporaire que là où l'on en a besoin.

Note : Cela n'est vrai qu'en C++. En C pur, on est obligé de définir les variables au début des fonctions ou des instructions composées (voir plus loin). Il faut donc connaître les variables temporaires nécessaires à l'écriture du morceau de code qui suit leur définition. La définition d'une variable ne suffit pas, en général, à l'initialiser. Les variables non initialisées contenant des valeurs aléatoires, il faut éviter de les utiliser avant une initialisation correcte. Initialiser les variables que l'on déclare à leur valeur par défaut est donc une bonne habitude à prendre. Cela est d'ailleurs obligatoire pour les variables « constantes » que l'on peut déclarer avec le mot clé const, car ces variables ne peuvent pas être modifiées après leur définition. Ce mot clé sera présenté ultérieurement.

Note : Si les variables utilisant les types simples ne sont pas initialisées lors de leur définition de manière générale, ce n'est pas le cas pour les objets dont le type est une classe définie par l'utilisateur. En effet, pour ces objets, le compilateur appelle automatiquement une fonction d'initialisation appelée le « constructeur » lors de leur définition.

5. Instructions et opérations

Les instructions sont généralement identifiées par le point virgule. C'est ce caractère qui marque la fin d'une instruction.

Il existe plusieurs types d'instructions, qui permettent de réaliser des opérations variées. Les instructions les plus courantes sont sans doute les instructions qui effectuent des opérations, c'est-àdire les instructions qui contiennent des expressions utilisant des opérateurs. Les principales opérations utilisables en C/C++ sont les suivantes :

Les affectations :

variable = valeur ;

Note : Les affectations ne sont pas des instructions. Ce sont bien des opérations qui renvoient la valeur affectée. On peut donc effectuer des affectations multiples :

i=j=k=m=0; // Annule les variables i, j, k et m.

Les opérations de base du langage :

valeur op valeur ;

où op est l'un des opérateurs suivants : +, -, *, /, %, &, |, ^, ~, <<, >>.

Note : '/' représente la division euclidienne pour les entiers et la division classique pour les flottants.

'%' représente la congruence (c'est-à-dire le reste de la division euclidienne). '|' et '&' représentent respectivement le ou et le et binaire (c'est-à-dire bit à bit : 1 et 1 = 1, 0 et x = 0, 1 ou x = 1 et 0 ou 0 = 0). '^' représente le ou exclusif (1 xor 1 = 0, 0 xor 0 = 0 et 1 xor 0 = 1). '~' représente la négation binaire (1 devient 0 et vice versa). '<<' et '>>' effectuent un décalage binaire vers la gauche et la droite respectivement, d'un nombre de bits égal à la valeur du second opérande.

Les opérations des autres opérateurs du langage. Le C et le C++ disposent d'opérateurs un peu plus évolués que les opérateurs permettant de réaliser les opérations de base du langage. Ces opérateurs sont les opérateurs d'incrémentation et de décrémentation ++ et --, l'opérateur ternaire d'évaluation conditionnelle d'une expression (opérateur ?smile et l'opérateur virgule (opérateur ,). La syntaxe de ces opérateurs est décrite ci-dessous.

Bien entendu, la plupart des instructions contiendront des affectations. Ce sont donc sans doute les affectations qui sont les plus utilisées parmi les diverses opérations réalisables, aussi le C et le C++ permettent-ils l'utilisation d'affectations composées. Une affectation composée est une opération permettant de réaliser en une seule étape une opération normale et l'affectation de son résultat dans la variable servant de premier opérande. Les affectations composées utilisent la syntaxe suivante :

variable op_aff valeur ;

où op_aff est l'un des opérateurs suivants : '+=', '-=', '*=', etc. Cette syntaxe est strictement équivalente à :

variable = variable op valeur ;

et permet donc de modifier la valeur de variable en lui appliquant l'opérateur op.

Exemple, affectation composée

i*=2; // Multiplie i par 2 : i = i * 2.

Les opérateurs d'incrémentation et de décrémentation ++ et -- s'appliquent comme des préfixes ou des suffixes sur les variables. Lorsqu'ils sont en préfixe, la variable est incrémentée ou décrémentée, puis sa valeur est renvoyée. S'ils sont en suffixe, la valeur de la variable est renvoyée, puis la variable est incrémentée ou décrémentée. Par exemple :

int i=2,j,k;
j=++i; // A la fin de cette instruction, i et j valent 3.
k=j++; // A la fin de cette ligne, k vaut 3 et j vaut 4.

Note : On prendra garde à n'utiliser les opérateurs d'incrémentation et de décrémentation postfixés que lorsque cela est réellement nécessaire. En effet, ces opérateurs doivent contruire un objet temporaire pour renvoyer la valeur de la variable avant incrémentation ou décrémentation.

Si cet objet temporaire n'est pas utilisé, il est préférable d'utiliser les versions préfixées de ces opérateurs. L'opérateur ternaire d'évaluation conditionnelle ?: est le seul opérateur qui demande 3 paramètres (à part l'opérateur fonctionnel () des fonctions, qui admet n paramètres, et que l'on décrira plus tard). Cet opérateur permet de réaliser un test sur une condition et de calculer une expression ou une autre selon le résultat de ce test. La syntaxe de cet opérateur est la suivante :

valeur = (test) ? expression1 : expression2 ;

Dans cette syntaxe, test est évalué en premier. Son résultat doit être booléen ou entier. Si test est vrai (ou si sa valeur est non nulle), expression1 est calculée et sa valeur est renvoyée. Sinon, c'est la valeur de expression2 qui est renvoyée. Par exemple, l'expression :

Min=(i < j) ? i : j;

calcule le minimum de i et de j.

L'opérateur virgule, quant à lui, permet d'évaluer plusieurs expressions successivement et de renvoyer la valeur de la dernière expression. La syntaxe de cet opérateur est la suivante :

expression1,expression2[,expression3[...]]

où expression1, expression2, etc. sont les expressions à évaluer.

Les expressions sont évaluées de gauche à droite, puis le type et la valeur de la dernière expression sont utilisés pour renvoyer le résultat. Par exemple, à l'issue des deux lignes suivantes :

double r = 5;
int i = r*3,1;

r vaut 5 et i vaut 1. r*3 est calculé pour rien.

Note : Ces deux derniers opérateurs peuvent nuire gravement à la lisibilité des programmes. Il est toujours possible de réécrire les lignes utilisant l'opérateur ternaire avec un test (voir la Section 2.1 pour la syntaxe des tests en C/C++). De même, on peut toujours décomposer une expression utilisant l'opérateur virgule en deux instructions distinctes. Ce dernier opérateur ne devra donc jamais être utilisé.

Il est possible de créer des instructions composées, constituées d'instructions plus simples. Les instructions composées se présentent sous la forme de bloc d'instructions où les instructions contenues sont encadrées d'accolades ouvrantes et fermantes (caractères '{ et '}').

Exemple, instruction composée

{
i=1;
j=i+3*g;
}

Note : Un bloc d'instructions est considéré comme une instruction unique. Il est donc inutile de mettre un point virgule pour marquer l'instruction, puisque le bloc lui-même est une instruction.

 

 

voila pas si compliquer que sa le c++.

Noter cette page

5/10 sur 1 vote

Sélectionnez une note dans le menu déroulant.
Dernière mise à jour de cette page le 11/06/2008

Créer un site internet gratuit avec E-monsite.com - Signaler un contenu illicite - Voir d'autres sites dans la catégorie Aide / Tutoriaux
Comment créer un site - Videos Droles - Clips musique - Cours création de site web