2- Syntaxes de base en C++


1- Types de base - Opérateurs

2- Sructures de controle

3- Les fonctions

4- Les tableaux


1 Types de base - Opérateurs - Structures de contrôle

Fin d'instruction

Une instruction se termine par ";". Les tabulations, espaces, sauts de ligne sont ignorés lors de la compilation. L'instruction :
x=a+b;
est absolument équivalente à :
x=		a
+	b	;


Formes des commentaires

Les commentaires sont incrits sur des lignes en étant précédés de //

Les commentaires sont inscites entre /* et */. éventuellement sur plusieurs lignes

Affichage de texte

Une instruction d'écriture de code :
std::cout << "HelloWorld !\n";

cout : objet défini dans la librairie iostream qui sert à envoyer des choses à écrire à l'elt de sortie par défaut (le command prompt)
<< : pour envoyer la chaine à cout
std : librairie dans laquelle il faut aller chercher cout.

Nom variable



Types primitifs

C++ propose un certain nombre de type primitifs, soit des types qui ne sont pas des types objets. Pour chaque type, en fonction du processeur et du compilateur utilisé, le codage en nombre d'octets peut varier. Dans ce qui suit, on donne le codage standard des valeurs, vous est ensuite proposé une procédure pour tester les tailles respectives en fonction de votre implémentation.
DescriptionNomTaille en octets
Le type d'entier de réference : int4
Un type d'entier courtshort2
Un type d'entier longlong int4
Un réelfloat4
Le réel le plus granddouble8
Un type booléenbool1
Un type charUne variable de ce type contient un caractère ASCII1

Voir la documentation de votre compilateur pour savoir les tailles de stockage et donc les valeurs limites pour chaque type. Une autre solution est d'exécuter le code suivant : VoirTailleTypes.cpp.

Une variable entière peut être signée ou non (signed/unsigned). Sans autre indication, les variables sont signés en l'absence du mot clé unsigned. Les entiers signés sont soit négatifs, soit positifs alors que les entiers non signés sont toujours positifs. Soit par exemple une implémentation telle qu'un entier est codé sur 4 octets. Dans le cas d'un int signé, il est à valeurs dans [-32768:32767]. Dans le cas d'un int non signé, il est à valeurs dans [0:65535].

Une variable de type caractère est codée sur un octet, soit 8 bits. En tout il y a 28=256 caractères numérotées de 0 à 255 qui sont les 256 caractères de la norme ASCII. Des caractères spéciaux sont disponibles :
CaractereSignification
\aAlerte sonore
\bRetour en arrière
\fSaut de page
\nNouvelle ligne
\rRetour chariot
\ttabulation
\vTabulation verticale
\'guillemet simple
\"guillemet double
\?Point d'interrogation
\\Barre oblique inverse
\000Notation octale
\xhhhNotation hexadécimale


TestsCaracteresSpeciaux.cpp

Initialisation et affectation de variables

L'affectation est de la forme : Variable=valeur; ou Variable=expression;. Quelques exemples :
int i=8;/*Declaration et affectation*/
int j;/*Declaration*/
j=7;/*Affectation*/
char c='a';/*Declaration et affectation*/
char d='\n';/*Décalaration et affectation, caractère de saut de ligne*/
char tabulation='\t';/*Décalaration et affectation, caractère de tabulation*/
int n1,n2,n3;/*Declaration multiple*/
double x1=0.1,x2=1002.5,x3=9;/*Decalaration et affectation multiple*/
long int h=89;/*Declaration d'un entier de type long*/
unsigned short x;/*Declaration d'un entier short non signé*/

NB1 : C++ est un langage typé : toutes les variables utilisées ont dues êtres préalablement déclarées.

NB 2 : Attention : en C++, la déclaration ne vaut pas affectation implicite. Dans le cas des langages comme java la délaration sans affectation d'une variable int a conduit à son initialisation à a. En C ou en C++, cela n'est pas vrai.



Opérateurs arithmétiques et transtypage

Ces opérateurs peuvent aussi s'appliquer sur des variables de type char, avec des résultats inattendus parfois avant de faire des tests.
Les opérateurs traditionnels+, -, /, *
Opérateur d'incrémentation, décrementation++
L'opérateur modulo%
Un opérateur équivalent à nb=nb+3nb+=3
Une série d'opérateurs de même genre que +=-=, *=, /=
La priorité des opérateurs respecte les conventions mathématiques.

Attention, le fait de faire l'opération x=5/3 affecte 1 à x. De la même manière :
int y=5;
int n=3;
x=y/n;
affecte 1 à x. La division d'entier renvoie un entier. En revanche : x=5.0/3.0 ou x=5.0/3 affecte 1.666667 à x.

Il n'y a pas ici de transtypage implicite ici : il faut forcer explicitement l'affectation d'une variable d'un type vers un autre type. Voir le cas dans l'exemple :

double x=2.5;
short int u;
u=(short int)x;


Conditions logiques

opérateur de comparaison - égalité==
opérateur de comparaison - inégalités>=, <=, <, >
Opérateur de comparaison - différent!=
Enchainement de conditions ET&&
Enchainement de conditions OU||
Enchainement de conditions NON!
A noter que le ! est prioritaire sur le && lui même prioritaire sur le ||. Quelques exemples :
bool b0=(5<6);
std::cout<<b0;/*Affiche 1 qui correspond à vrai*/
bool b1=(5==1 && 6>5);
std::cout<<"La valeur de b1 "<<(b1);/*Affiche 0 qui correspond à faux*/
bool b2=('\n'=='\n' || 5>6);
std::cout<<(b2);/*Affiche 1*/
bool b3=(7!=5.65 && (3>4 || 6>5));
std::cout<<"\n"<<(b3);/*Affiche vrai*/
A noter que tous les opérateurs sont binaires à l'exception d'un seul : pour tester si x>y>z, on ne peut pas faire : if(x>y>z), on doit faire if(x>y && y>z). Le seul opérateur non binaire est ternaire :
(expression1) ? (expression2) : (expression3), ce qui signifie : si l'expressions1 est vraie, retourner la valeur de expression2, sinon retourner la valeur de expression3. Par exemple :
z=(x>y) ? x : y;
Dans ce cas, la valeur de x sera affectée à z si x est supérieur à y, sinon ce sera la valeur de y qui sera affectée à x. Donc ici z reçoit le max de x,y. Utiliser la réference suivante : affichageCalculateur

Ecrire en sortie sur l'écran

Une instruction utilisée n'a pas été explicitée : std::cout<<"...";.

Pour afficher le contenu des variables dans des chaînes :
int i=6;
std::cout<< "Valeur de i : "<<i<<"\n";
ce code affichera Valeur de i : 6. La concaténation peut être plus complexe :
int i=6;
int j=9;
double x=77.76;
std::cout<<"La valeur de i est : "<<i<<" , la valeur de j est : "<<j<<", enfin, celle de x est : "<<x<<"\n";


Ecriture du contenu d'une variable : x
std::cout << " x : " << x << std::endl;


Récupérer une valeur saisie par l'utilisateur

On utilise un objet du fichier iostream de la librairie std : cin. Pour entrer une valeur dans la variable x :
std::cin >> x;

Le code suivant :
Le programme recuperationVariable
#include

int main()
	{
    	double x;
	std::cout << "Rentrez une valeur entiere" << std::endl;
    	std::cin >> x;
    	std::cout << "La valeur que vous avez saisie " << x << std::endl;
	return 0;
	}


Déclaration de constante et énumération

Pour la déclarer, on donne son type et on utilise le mot clé const. Par convention, on écrit le nom des constantes en majuscules.
const int PI=3.14;

Une énumérations est une liste de constantes de type unsigned int. On utilise le mot clé enum. U
enum categorie {CADRE, OS, COMPABLE, DRH, PRESIDENT};
Par défaut, la première valeur de l'énumération est 0, le second élement est 1 etc... Soit sur l'exemple : CADRE=0, OS=1 etc... Il est possible de déclarer une variable de cette énumération :
categorie myCat=OS;


Libraire Standard

La librairie standard est un ensemble de fichiers que l'on peut inclure dans les fichiers de programme et qui fournissent les principales fonctions.

Génération de valeurs aléatoires

Les fonctions nécessaires à la génération aléatoire sont contenues dans la librairie <cstdlib>. La génération de nombres aléatoires implique d'abord d'initialiser la racine (seed) par l'instruction :

srand(time(0));
Par suite, on utilise la fonction rand() qui renvoie (selon un tirage uniforme) un nombre entier entre 0 et un entier maximal susceptible de varier. Ce nombre est enregistré dans la constante RAND_MAX.
En disposant de la fonction rand, il est ensuite possible de créer diverses fonctions de génération aléatoire :
int test=rand()%7;
tire une valeur dans [0:6]. L'instruction suivante :
double x=rand()/(double)RAND_MAX;
Tire un réel dans [0;1]. L'explication de (double) sera donnée plus tard : voir le transtypage. Un exemple complet de tirage et d'affichage : ExTirage.cpp

Utilisation de fonctions

Il est possible de définir directement des fonctions à l'instar de ce qui se fait dans le procédural :
#include 

void testAffichage()
	{
	std::cout << "Ceci vient de testAffichage()\n";
	}

int main()
	{
	std::cout << "Ceci vient de main()\n\n";
	testAffichage();
	return 0;
	}

	
Il est à noter que la fonction main() est particulière : c'est la seule à partir de laquelle il est possible de lancer l'éxéction du programme. Ie pour tout autre fonction, elle doit être appellée depuis la fonction main() ou depuis une fonction appellée par la fonction main() ou depuis une fonction appellée par une fonction appellée par la fonction main() etc...

2 Structures de controles



Structures de contrôle

Toutes les structures de contrôle ne sont pas évoquées ici : on donne 2 structures de boucles et une structure conditionnelle, les autres structures de contrôle n'apportent pas d'autres possibilités. Ces structures recevront des exemples dans la suite. La structure for :

	for(instruction d'initialisation;instruction de poursuite / arrêt de la boucle;instruction à chaque tour de boucle)
	{
	/*Les instructions qui sont répétées dans la boucle*/
	}
Par exemple :
int somme=0;	
	for(int i=0;i<5;i++)
	{
	somme=somme+i;
	std::cout<<i<<"\t"<<somme<<"\n";
	}


La structure while :
	while(Condition(s) Logique(s))
	{
	/*Les instructions qui sont répétées dans la boucle*/
	}
Par exemple :
int somme=0,i=0;	
	while(i<5)
	{
	somme=somme+i;
	std::cout<<i<<"\t"<<(sommme)<<"\n";
	}


La structure if...else if... else if...else..., elle peut être implémentée de différentes manières :
	if(Conditons 1)
	{
	/*Instructions sous les conditions 1*/
	}
	else if(conditions 2)
	{
	/*Instructions sous les conditions 2*/
	}
	else
	{
	/*Instructions si ni les conditions 1, ni les conditions 2 ne sont vérifiées*/
	}
Le else if n'est pas obligatoire, le else non plus :
	if(Conditions 1)
	{
	/*Instructions sous les conditions 1*/
	}
Des niveaux intermédiaires sont envisageables :
	if(Conditons 1)
	{
	/*Instructions sous les conditions 1*/
	}
	else if(conditions 2)
	{
	/*Instructions sous les conditions 2*/
	}
	else if(conditions 3)
	{
	/*Instructions sous les conditions 3*/
	}
Note : il existe des syntaxes un peu différentes, des raccourcis dans certains cas, la présentation proposée ici est la plus générale possible et mieux vaut s'y tenir dans un premier temps. Quand il y a une unique instruction qui dépend de l'instruction conditionnelle, il n'est pas nécessaire de mettre les accolades :
	if(condition1)
	L'instruction qui dépend de la condition 1;

	for(i=0;i<100;i++)
	L'instruction unique de la boucle;

3 Les fonctions

Declarer une fonction

Il n'y a pas de distinction fonction/procédure ici en C ou en C++, on distingue entre des fonctions qui renvoient des valeurs et des fonctions qui n'en renvoie pas. Pour spécifier qu'une fonction renvoie un entier :
int maFonction();
Pour indiquer qu'une fonction de renvoie pas de valeur, on déclare void maFonction(). Dans ce cas là, on ne met pas d'instruction return dans le corps de la fonction. Il est également possible de passer des paramètres en entée :
int maFonction(int a,float x);
Pour être utilisable une fonction doit être déclarée et définie. La déclaration se compose du nom de la fonction, du type de la valeur renvoyée et des paramètres passés à la fonction. La définition de la fonction fournit au compilateur des informations relatives au conenu de la fonction. On ne peut appeler qu'une fonction qui a été préalablement déclarée. La déclaration d'une fonction est désignée sous le nom de prototype. Par exemple
double calculAire(double longueur,double largeur);
Noter qu'un prototype est terminé par un ;. Le prototype se compose du type de retour de la fonction renvoyée (int ici) et de la signature de la fonction : le nom de la fonction et les paramètres de la fonction. Le prototype d'une fonction et sa définition doivent correspondre, seul les noms des paramètres peuvent changer. Il existe notamment deux manières de déclarer une fontion : Pour les fonctions déjà disponibles (spécifiées par la norme), elles sont déclarées au début des programme, à travers les directvies #include. Par exemple, #include <iostream> donne accès à un ensemble de fonctions, de même pour #include <cmath> qui donne accès à un grand nombre de fonctions : std::abs(double x); par exemple. Pour éviter d'avoir à répter à chaque fois le nom de domaine std, on met en après les déclaration include : using namespace std;. Dans ce cas, l'espace de nom std ne sera plus à repréciser. Ainsi, le code :
 
#include <iostream>
#include <cmath>

int main
	{
	std::cout << "La valeur absolue de 0.5 : << std::abs(0.5) << "\n";
	std::cout << "La valeur absolue de -0.5 : << std::abs(-0.5) << "\n";
	std::cout << "Le carre de 2 : << std::sqrt(2) << "\n";
	return 0;
	}

devient en utilisant using namespace std; :
#include <iostream>
#include <cmath>

using namespace std;

int main
	{
	cout << "La valeur absolue de 0.5 : << abs(0.5) << "\n";
	cout << "La valeur absolue de -0.5 : << abs(-0.5) << "\n";
	cout << "Le carre de 2 : << sqrt(2) << "\n";
	return 0;
	}
Attention, cout n'est pas une fonction, mais un objet.

Définir une fonction

La définition d'une fonction est consituée du corps et de l'en tête de la fonction. L'en tête est similaire au prototype aux noms des paramètres près et à ceci près qu'il n'y a pas de ; final. La définition de la fonction :
double calculAire(double longueur,double largeur)
	{
	return longueur*largeur;
	}
La fonction ne contient qu'une instruction, mais elle pourrait en contenir plus. Pour voir un exemple de définition et d'utilisation de cette fonction :
calcAire_sol1.cpp. Le prototype est ici défini dans le fichier source, une alternativve est de le définir dans la fonction : calcAire_sol2.cpp.

Passage de paramètres à une fonction

Il est possible de déclarer des variables au sein d'une fonction. Ces variables sont dites locales. Elles n'existent que dans le cadre de la fonction. Lorsque la fonction rend la main au programme, elles disparaissent. Les paramètres passés à la fonction sont également considérés comme des variables locales. Par opposition, il est possible de définir des variables globales, par exemple :
#include 
void myFunction();	//prototype

int x=5,y=7;	//variables globales

using namespace std;

int main()
	{
	cout << "x dans la fonction main : " << x << "\n";
	cout << "y dans la fonction main : " << y << "\n";
	myFunction();
	cout << "\nDe retour de myFunction. \n\n";
	cout << "x dans la fonction main : " << x << "\n";
	cout << "y dans la fonction main : " << y << "\n";
	}

void myFunction()
	{
	int y=10;
	cout << "\nx provenant de myFunction : " << x << "\n";
	cout << "y provenant de myFunction : " << y << "\n\n";
	}
Ce programme affiche le résultat suivant :
x dans la fonction main : 5
y dans la fonction main : 7

x provenant de myFunction : 5
y provenant de myFunction : 10

De retour de myFunction

x dans la fonction main : 5
y dans la fonction main : 7

Renvoi de valeur

Pour indiquer la valeur à renvoyer par une fonction dans le cas où le type de retour de la fonction n'est pas void, plusieurs possiblilités :
return 77.8;
return x;
return MyFunction();
return (x>y);

Surcharge de fonction / polymorphisme

Il est possible de définir plusieurs fonctions de même nom :
int maFonction(int,int);
int maFonction(long,long);
int maFonction(long);
Des fonctions surchargées peuvent renvoyer différents types de valeurs. La machine sélectionnera celles des fonctions qu'il convient d'utiliser en fonction de l'appel.

Une fonction de la librairie standard : system

System prend en argument une chaine de caractères qui est une instructions MSDOS. On peut tester system("ping www.google.fr"); ou system("dir");

Le tirage de valeurs aléatoires

Faire un include sur iostream pour avoir les fonctions de génération aléatoire. Pour initialiser le générateur aléatoire, une instruction à placer en début de main : srand(time(0));. Ensuite, on utilise la fonction rand() qui génère un nombre aléatoire entier entre [0;RAND_MAX].


4 Les tableaux

Des éléments plus précis sur les tableaux seront évoqués au chapitre sur les pointeurs, notamment pour voir ce à quoi correspond la déclaration de tableaux en mémoire. En attendant, on peut noter que la syntaxe pour la déclaration d'un tableau est :

double per[19];

Dans ce cas, per est un tableau de 19 élements d'indices 0 à 18. Il est par suite possible de manipuler les 19 variables du tableau, soit en leur affectant une valeur, soit en utilisant leur valeur dans des calculs :

per[7]=6.78;
double w=per[7]*0.112;