C++ est un langage de programmation compilé.
C'est la référence de bases de beaucoup de langages de programmation.
La synthaxe de java, javascript et plusieurs autres langages
est calquée sur celle du langage C.
Le C++ est une évolution du langage C, permettant la programmation objet.
Il fonctionne sur toutes les platformes, Linux, Windows et Mac.
Sous Linux, pour compiler, il faut avoir installé gcc et build-essential.
Il existe plusieurs environnements de développement.
Plus d'information concernant Geany.
J'ai également fait des essais avec
Code::Blocks est un environnement simple.
Qt est un autre environnement.
Quelques informations, aux formats :
.odt et
.pdf
n pour indiquer un int v pour indiquer un double (nombre à virgule) c pour indiquer un char str pour indiquer une chaîne de caractères a pour indiquer un array an sera donc l'indication d'un array d'entiers p pour indiquer un pointeurprintf les "specifiers" ; data types de wikipedia".
/*
ex0010_hello_world.cpp
Pour le compiler, tapez dans un Terminal :
g++ -Wall -o ex0010_hello_world ex0010_hello_world.cpp
Remarque :
-Wall indique que l'on veut afficher tous les warnings.
*/
#include <iostream>
using namespace std;
int main() {
//==========
cout << "Hello world!" << endl;
cout << "Un texte avec des accents : été être à Loïc ça !" << endl;
return 0;
} // main
/*
ex0020_sommes.cpp
Pour le compiler, tapez dans un Terminal :
g++ -Wall -o ex0020_sommes ex0020_sommes.cpp
*/
// Editeur code::Blocks : http://wiki.codeblocks.org/index.php?title=Keyboard_Shortcuts
#include <iostream> // pour les entrées - sorties (In & Out)
#include <cmath> // pour les fonctions mathématiques, sqrt = racine carrée.
using namespace std;
int main() {
//==========
int nCount = 0; // indice qui va parcourir les entiers de 1 à nMax
int nMax = 1; // valeur maximum de l'indice de la somme
double vSum = 0; // résultat de la somme
// Demande à l'utilisateur la valeur de nMax
cout << "nombre de termes à sommer (0 = fin) : ";
cin >> nMax; // attend la saisie d'un nombre entier positif.
if (nMax <= 0) return 0;
vSum = 0;
// Boucle effectuant la somme
for (nCount = 1; nCount <= nMax; nCount++) {
// tenez compte de l'indentation !
vSum = vSum + 1.0 / (1.0*nCount * nCount);
// sans le "1.0*nCount", le programme est très limité, car
// on dépasse rapidement la capacité de codage des nombres entiers.
}
// Ce premier résultat ne permet pas de deviner ce que cette somme vaut
cout << "La somme des inverses des carrés de 1 à " << nMax
<< " vaut : " << vSum << endl;
// Autre affichage, qui donne plus d'espoir de deviner la valeur de la somme
// lorsque nMax tend vers l'infini.
cout << "Racine carré de 6 fois la somme ci-dessus : "
<< sqrt(6*vSum) << endl << endl;
return 0;
} // main
/*
ex0030_cout_cin.cpp
Pour le compiler, tapez dans un Terminal :
g++ -Wall -o ex0030_cout_cin ex0030_cout_cin.cpp
C.f : http://fr.openclassrooms.com/informatique/cours/programmez-avec-le-langage-c/une-vraie-calculatrice
*/
#include <iostream>
#include <string>
using namespace std;
//char cc;
int main() {
//========
string nomUtilisateur("sans nom"); // on crée une variable "nom" pour contenir une chaine de caractères
double piUtilisateur = -1;
cout << "Quelle est votre nom ? ";
cin >> nomUtilisateur;
cout << "Combien vaut pi à votre avis : ";
cin >> piUtilisateur;
cout << "Votre nom est : " << nomUtilisateur
<< " et vous pensez que pi vaut : " << piUtilisateur << endl;
return 0;
} // main
/*
ex0035_sommes.cpp
Pour le compiler, tapez dans un Terminal :
g++ -Wall -o ex0035_sommes ex0035_sommes.cpp
// Editeur code::Blocks : http://wiki.codeblocks.org/index.php?title=Keyboard_Shortcuts
*/
#include iostream> // pour les entrées - sorties (In & Out)
#include iomanip> // pour le formattage, tel que setprecision, setw, setfill('-'), setbase
#include cmath> // pour les fonctions mathématiques, sqrt = racine carrée.
// # include limits> // pour des valeurs maximales et minimales
#include stdio.h> // pour printf et sprintf
using namespace std;
int main() {
//==========
int nCount = 0; // indice qui va parcourir les entiers de 1 à nMax
int nMax = 1; // valeur maximum de l'indice de la somme
double vSum = 0; // résultat de la somme
while (nMax > 0) {
// Demande à l'utilisateur la valeur de nMax
cout << "nombre de termes à sommer (0 = fin) : ";
cin >> nMax; // attend la saisie d'un nombre entier positif.
if (nMax = 0) return 0;
vSum = 0;
// Boucle effectuant la somme
for (nCount = 1; nCount = nMax; nCount++) {
// tenez compte de l'indentation !
vSum = vSum + 1.0 / (1.0*nCount * nCount);
// sans le "1.0*nCount", le programme est très limité, car
// on dépasse rapidement la capacité de codage des nombres entiers.
}
// Ce premier résultat ne permet pas de deviner ce que cette somme vaut
cout << "La somme des inverses des carrés de 1 à " << nMax
<< " vaut : " << vSum << endl;
// Autre affichage, qui donne plus d'espoir de deviner la valeur de la somme
// lorsque nMax tend vers l'infini.
cout << "Racine carré de 6 fois la somme ci-dessus : "
<< setprecision(15) << sqrt(6*vSum) << endl << endl;
printf("Résultat = %3.9f\n", sqrt(6*vSum)); // autre affichage, ancien style
}
return 0;
} // main
/*
ex0040_getline.cpp
Pour le compiler, tapez dans un Terminal :
g++ -Wall -o ex0040_getline ex0040_getline.cpp
// c.f : http://fr.openclassrooms.com/informatique/cours/programmez-avec-le-langage-c/une-vraie-calculatrice
*/
#include iostream>
#include string>
using namespace std;
int main() {
//========
string nomUtilisateur("sans nom"); // on crée une variable "nom" pour contenir une chaine de caractères
double piUtilisateur = -1;
cout << "Quelle est votre nom ? ";
getline(cin, nomUtilisateur);
// cin.ignore();
// permet de vider le buffer d'entrée de caractères.
cout << "Combien vaut pi à votre avis : ";
cin >> piUtilisateur;
cout << "Votre nom est : " << nomUtilisateur
<< " et vous pensez que pi vaut : " << piUtilisateur << endl;
return 0;
} // main
/*
ex0050_devine_nombre.cpp
Pour le compiler, tapez dans un Terminal :
g++ -Wall -o ex0050_devine_nombre ex0050_devine_nombre.cpp
C.f. http://fr.openclassrooms.com/informatique/cours/programmez-avec-le-langage-c/les-structures-de-controle-4
*/
#include iostream>
#include cmath>
// c.f. http://www.cplusplus.com/reference/cmath/
#include stdlib.h> // pour random : rand(...)
// c.f. http://www.cplusplus.com/reference/cstdlib/rand/
// rand() retourn un nombre entier entre 1 et RAND_MAX
// RAND_MAX vaut : 2'147'483'647 = 2^31 - 1 habituellement.
// Opérateurs : c.f. http://www.cplusplus.com/doc/tutorial/operators/
// + - * / % = modulo
#include time.h>
using namespace std;
int main() {
//========
// Le but est qu'un utilisateur devine le nombre caché par l'ordinateur.
int nCache = 33;
int nUtilisateur = 0;
int nCount = 0;
/* initialize random seed: */
srand (time(NULL));
nCache = rand() % 100 + 1;
// cout << RAND_MAX << endl; // pour voir la valeur de RAND_MAX
cout << "A vous de deviner le nombre que j'ai choisi, entre 1 et 100." << endl;
while (nUtilisateur != nCache) {
nCount++;
cout << "Tapez le nombre que vous pensez : ";
cin >> nUtilisateur;
if (nUtilisateur nCache) cout << "Votre nombre est trop petit." << endl;
if (nUtilisateur > nCache) cout << "Votre nombre est trop grand." << endl;
}
cout << "Vous avez trouvé mon nombre en " << nCount << " essais." << endl;
return 0;
} // main
/*
ex0060_conversion_nombre_entier.cpp
Conversion de nombres en différentes bases.
Pour le compiler, tapez dans un Terminal :
g++ -Wall -o ex0060_conversion_nombre_entier ex0060_conversion_nombre_entier.cpp
C.f. : https://www.cplusplus.com/reference/
C.f. : http://fr.openclassrooms.com/informatique/cours/programmez-avec-le-langage-c/les-structures-de-controle-4
Opérateurs : c.f. http://www.cplusplus.com/doc/tutorial/operators/
+ - * / % = modulo
#include cmath> // c.f. http://www.cplusplus.com/reference/cmath/
#include iomanip> // setbase(..) std::setiosflags, std::resetiosflags
*/
#include iostream>
using namespace std;
int version_1() {
//===============
// Le but est de convertir des nombres entiers de binaire en base 10.
// Traite plusieurs nombres et
// traites les espaces dans les données.
string strNb2 = "0"; // nombre en binaire, sous forme de chaine de caractères
char acNb2[256];
int nNb10 = 0; // le nombre en base 10
int nPow2 = 1; // les puissances de 2.
int nInd = 0; // pour parcourir les chiffres binaires
cout << "Conversion de binaire en base 10." << endl;
cout << "Les caractères autres que '0' et '1' seront ignorés." << endl;
cin.ignore(); // permet de vider le buffer d'entrée de caractères.
while (true) {
cout << "Tapez le nombre en binaire : ";
cin.getline(acNb2, 256); // met toute la ligne dans acNb2
strNb2 = acNb2; // convertir en string
if (strNb2.length() = 1) return 0;
nInd = strNb2.length();
nPow2 = 1; // les puissances de 2 suivant la position dans le nombre
nNb10 = 0;
while (nInd >= 0 ) {
if (strNb2[nInd] == '1') {
nNb10 += nPow2;
nPow2 = nPow2 * 2;
}
if (strNb2[nInd] == '0') nPow2 = nPow2 * 2;
// Si le chiffre binaire est différent de '0' et de '1', il est ignoré
nInd--;
}
cout << "Le nombre vaut en décimale : " << nNb10 << endl << endl;
}
return 0;
} // version_1
int version_2() {
//===============
// Le but est de convertir des nombres entiers de binaire en base 10.
// Traite plusieurs nombres et
// traites les espaces dans les données.
string strNb2; // nombre en binaire, sous forme de chaine de caractères
int nNb10 = 0; // le nombre en base 10
int nInd = 0; // pour parcourir les chiffres binaires
cout << "Conversion de binaire en base 10." << endl;
cout << "Les caractères autres que '0' et '1' seront ignorés." << endl;
cin.ignore(); // permet de vider le buffer d'entrée de caractères.
while (true) {
cout << "Tapez le nombre en binaire : ";
getline(cin, strNb2); // met toute la ligne dans acNb2
if (strNb2 == "0") return 0; // car rien de tapé.
nInd = 0;
nNb10 = 0;
while (strNb2[nInd] > 0 ) {
if (strNb2[nInd] == '1') nNb10 = nNb10 * 2 + 1;
if (strNb2[nInd] == '0') nNb10 = nNb10 * 2;
// Si le chiffre binaire est différent de '0' et de '1', il est ignoré
nInd++;
}
cout << "Le nombre vaut en base 10 : " << nNb10 << endl << endl;
}
} // version_2
int version_3() {
//===============
// Le but est de convertir des nombres entiers de base 10 en binaire.
// Traite plusieurs nombres et
// traites les espaces dans les données.
string strNb2 = ""; // nombre en binaire, sous forme de chaine de caractères
int nNb10 = 0; // le nombre en base 10
cout << "Conversion de nombres entiers en binaire." << endl;
while (true) {
cout << "Tapez l'entier en base 10 (0=fin) : ";
cin >> nNb10;
if (nNb10 = 0) return 0; // fin
// cout << setbase(16) << nNb10 << endl; // bases permises : 8, 10, 16
strNb2 = "";
while (nNb10 > 0 ) {
if (nNb10 % 2 == 1) strNb2 = '1' + strNb2;
else strNb2 = '0' + strNb2;
nNb10 = nNb10 / 2;
}
cout << "Le nombre vaut en binaire : " << strNb2 << endl << endl;
}
} // version_3
int version_4() {
//===============
// Le but est de convertir des nombres entiers de base b1 en en base b2.
// Traite plusieurs nombres et
// traites les espaces dans les données.
string strNb_b1; // nombre en base b1, sous forme de chaine de caractères, base entre 2 et 16
int nBase_b1 = 2; // La base de départ du nombre
int nNb10 = 0; // le nombre en base 10
int nInd = 0; // pour parcourir les chiffres binaires
char cChmax1 = '9'; // chiffre maximale permi dans la base donnée
char cChmax2 = 'F'; // chiffre maximale permi dans la base donnée, si elle est > 10
int nBase_b2 = 2; // La base d'arrivée du nombre
int nChiffre = 0; // Les chiffres du nombre en la base d'arrivée nBase_b2
string strNb_b2 = ""; // nombre dans la base d'arrivée, sous forme de chaine de caractères
cout << "Conversion de base b1 en base b2." << endl;
cin.ignore(); // permet de vider le buffer d'entrée de caractères.
cout << "Tapez la base b1 de départ du nombre, entre 2 et 36 : ";
cin >> nBase_b1;
cout << "Tapez la base b2 d'arrivée du nombre, entre 2 et 36 : ";
cin >> nBase_b2;
if ( (nBase_b1 2) || (nBase_b1 > 36) ) return 0;
if ( (nBase_b2 2) || (nBase_b2 > 36) ) return 0;
if (nBase_b1 = 10) {
cChmax1 = char(int('0') + nBase_b1 - 1);
cChmax2 = ' '; // Pas de lettre acceptée
}
else {
// Cas d'une base > 10
cChmax1 = '9';
cChmax2 = char(int('A') + nBase_b1 - 11);
}
while (true) {
cout << "Tapez le nombre en base b1 : ";
cin >> strNb_b1;
//getline(cin, strNb1);
if (strNb_b1 == "0") return 0;
// Conversion de la base de départ dans un nombre. nNb10 n'a pas de base, c'est juste un nombre.
nInd = 0;
nNb10 = 0;
while (nInd (int)strNb_b1.length()) {
// Si le chiffre est incompatible avec la base, il est ignoré
if ( (strNb_b1[nInd] >= '0') && (strNb_b1[nInd] = cChmax1) ) nNb10 = nNb10 * nBase_b1 + (int(strNb_b1[nInd]) - int('0'));
strNb_b1[nInd] = char(int(strNb_b1[nInd]) & 0xDF); // Conversion d'un ASCII en majuscule.
if ( (strNb_b1[nInd] >= 'A') && (strNb_b1[nInd] = cChmax2) ) nNb10 = nNb10 * nBase_b1 + (10 + int(strNb_b1[nInd]) - int('A'));
nInd++;
}
cout << "Le nombre vaut en base 10 : " << nNb10 << endl;
// Conversion du nombre nNb10 en un nombre en base nBase_b2
strNb_b2 = "";
while (nNb10 > 0 ) {
nChiffre = nNb10 % nBase_b2; // Reste de la division par nBase_b2
if (nChiffre 10) strNb_b2 = char(int('0') + nChiffre ) + strNb_b2;
else strNb_b2 = char(int('A') + nChiffre-10) + strNb_b2;
nNb10 = nNb10 / nBase_b2;
}
cout << "Le nombre vaut en base " << nBase_b2 << " vaut : " << strNb_b2 << endl << endl;
}
} // version_4
int main() {
//========
// Le but est de convertir des nombres entiers relatifs
// de binaire en décimal et de décimal en binaire.
int nVersion = 0;
do {
cout << "Quelle version voulez-vous tester, entre 1 et 4 (0=fin) : ";
cin >> nVersion;
if (nVersion == 0) return 0;
else if (nVersion == 1) version_1(); // la version qui effectue le plus de traitements
else if (nVersion == 2) version_2();
else if (nVersion == 3) version_3();
else version_4();
} while (nVersion != 0);
} // main
/*
ex0070_conversion_nombre_virgule.cpp
Codage de nombres en virgule flottante sur 32 bits.
Pour le compiler, tapez dans un Terminal :
g++ -Wall -o ex0070_conversion_nombre_virgule ex0070_conversion_nombre_virgule.cpp
C.f. : http://www.cplusplus.com/reference/cmath/
*/
#include <iostream>
#include <iomanip> // std::setprecision
#include <cmath>
#include <string.h>
#include <stdlib.h> // pour random : rand(...)
// Juste pour la fonction kbhit(), ci-dessous
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
using namespace std;
int kbhit(int nOption=0) {
//========================
// c.f. : https://cboard.cprogramming.com/c-programming/63166-kbhit-linux.html
// Retourne 0 s'il n'y a pas de caractères dans le buffer s'entrée stdin.
// Retourne le code du caractère s'il y en a un.
// Si nOption == 0, retourne le code du buffer d'entrée, s'il y en a un et l'enlève du buffer d'entrée.
// Si nOption == 1, laisse inchangé le buffer d'entrée (stdin).
// Si nOption == 2, vide le buffer d'entrée (stdin) et retourne le nombre de caractères enlevés du buffer d'entrée.
// Les lignes avec //BG sont inutiles, mais peuvent avoir leur intérêt dans d'autres situations.
//BG struct termios oldt, newt;
int ch;
int oldf;
int nCompte = 0; // Compte le nombre de caractères qu'il y avait dans le buffer si nOption == 2
//BG tcgetattr(STDIN_FILENO, &oldt);
//BG newt = oldt;
//BG newt.c_lflag &= ~(ICANON | ECHO);
//BG tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0); // Mémorise l'état des conditions d'exécution de la fonction "getch()"
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); // Pour ne pas arrêter l'exécution au : "ch = getchar()"
ch = getchar(); // Lit un code (ou caractère) du buffer s'entrée (stdio), sans arrêter le programme s'il n'y en a pas.
if (nOption == 2) {
// Vide le buffer d'entrée
while (ch != EOF) { ch = getchar(); nCompte++; }
}
//BG tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf & ~O_NONBLOCK); // Remet l'état des conditions d'exécution de la fonction "getch()" à sa valeur mémorisée.
if (nOption == 2) return nCompte;
if (ch != EOF) {
if (nOption == 1) ungetc(ch, stdin); // Remet le caractère dans le buffer d'entrée
return int(ch);
}
return 0;
} // kbhit
int version_1()
//=============
// Le but est de convertir des nombres à virgule flottante
// codé en de binaire 32 bits en nombre à virugle
// Traite plusieurs nombres et
// traites les espaces dans les données.
{
char acNb2[255]; // nombre en binaire, sous forme de chaine de caractères
float vNb10 = 0; // le nombre en base 10
float nSign = 1; // le signe
char cSign = '+';
float nExposant = 0;
float vMantisse = 1.0;
float vPow2 = 1.0; // puissance de 2, exposants négatifs
int nInd = 0; // pour parcourir les chiffres binaires
int nn = 0; // pour des boucles
string astrNb2[20];
astrNb2[ 1] = "0 01111111 00000000000000000000000"; // a = 1
astrNb2[ 2] = "0 10000010 10100000000000000000000"; // b = 13
astrNb2[ 3] = "0 01111110 01000000000000000000000"; // c = 0.625
astrNb2[ 4] = "0 01111011 10011001100110011001100"; // d = 0.1
astrNb2[ 5] = "0 10000011 00010000000000000000000"; // e = 17
astrNb2[ 6] = "0 01111101 01000000000000000000000"; // f = 0.3125
astrNb2[ 7] = "0 01111111 10011001100110011001100"; // g = 1.6
astrNb2[ 8] = "0 01111101 00110011001100110011001"; // h = 0.3
astrNb2[ 9] = "0 10000000 10010010000111111011010"; // i = 3.14159
astrNb2[10] = "0 10000000 01011011111100001010100"; // j = 2.71828
astrNb2[11] = "0 01111111 01101010000010011110011"; // k = 1.41421
astrNb2[12] = "0 01111111 10011110001101110111100"; // l = 1.61803
astrNb2[13] = "1 01111111 10000000000000000000000"; // m =-1.5
cout << "Conversion de nombres à virgule en binaire 32 bits." << endl;
cout << "Les caractères autres que '0' et '1' seront ignorés." << endl;
//nInd = cin.peek(); // Lit le code du caractère, sans l'extraire du buffer d'entrée // C.f. : https://www.cplusplus.com/reference/istream/istream/ignore/
//cout << "nn=" << nInd << endl;
// fflush(stdin); // N'est pas suffisant
//cin.ignore(); // permet de vider le buffer d'entrée de caractères. Est une manière qui fonctionne ici, mais moins générale.
//cout << kbhit(2) << endl;; // Vide le buffer d'entrée. Avec affichage du nombre de caractères du buffer, pour des tests
kbhit(2); // Vide le buffer d'entrée.
// C'est nécessaire, car un "cin.getline(acNb2, 256);" suit un "cin >> nVersion;" du main().
while (true) {
cout << "Tapez le code 32 bits du nombre (a à m pour des exemples) : ";
cin.getline(acNb2, 256); // met toute la ligne dans acNb2
if (acNb2[0] == 0) return 0; // car rien de tapé.
// si on a tapé une lettre, utilise la chaine prédéfinie
if ((acNb2[0] >= 'a') && (acNb2[0] <= 'm')) {
strcpy(acNb2, astrNb2[acNb2[0] - 'a' + 1].c_str());
cout << acNb2 << endl;
}
nInd = 0;
vNb10 = 0;
// Cherche le signe du nombre
while ((acNb2[nInd] > 0) && (acNb2[nInd] != '0' ) &&
(acNb2[nInd] != '1' )) nInd++;
if (acNb2[nInd] == 0) return 0; // car nombre mal tapé
if (acNb2[nInd] == '0') { nSign = 1; cSign = '+'; }
else { nSign =-1; cSign = '-'; }
nInd++;
// Définition de l'exposant
nn = 0; // Compte le nombre de bits de l'exposant
nExposant = 0;
while (nn < 8) {
// saute les espaces et autres caractères non significatifs
while ((acNb2[nInd] > 0) && (acNb2[nInd] != '0' ) &&
(acNb2[nInd] != '1' )) nInd++;
if (acNb2[nInd] == 0) return 0; // car nombre mal tapé
if (acNb2[nInd] == '1') nExposant = nExposant * 2 + 1;
if (acNb2[nInd] == '0') nExposant = nExposant * 2;
nInd++;
nn++;
}
nInd++;
nExposant = nExposant - 127;
// Définition de la mantisse
nn = 0; // Compte le nombre de bits de l'exposant
vMantisse = 1.0;
vPow2 = 1.0;
while ((nn < 23) && (acNb2[nInd] > 0 )) {
// saute les espaces et autres caractères non significatifs
while ((acNb2[nInd] > 0) && (acNb2[nInd] != '0' ) &&
(acNb2[nInd] != '1' )) nInd++;
vPow2 = vPow2 / 2;
if (acNb2[nInd] == '1') vMantisse = vMantisse + vPow2;
nInd++;
nn++;
}
vNb10 = nSign * vMantisse * exp2(nExposant);
cout << "Signe, exposant, mantisse = " << cSign << " " << nExposant << " " << vMantisse << endl;
cout << setprecision(9); // défini la précision d'affichage des nombres
cout << "Le nombre vaut : " << vNb10 << endl;
cout << setprecision(6); // défini la précision d'affichage des nombres
cout << "Le nombre vaut : " << vNb10 << endl << endl;
// c.f. http://www.cplusplus.com/reference/iomanip/setprecision/
}
} // version_1
int version_2() {
//===============
// Le but est de convertir des nombres à virgule flottante
// de nombre à virgule en nombre codé en de binaire 32 bits
// Traite plusieurs nombres et
// traites les espaces dans les données.
string strNb2 = "";
float vNb10 = 0; // le nombre en base 10
float nExposant = 0;
int nn = 0; // pour des boucles
cout << "Conversion de nombres à virgule en binaire 32 bits." << endl;
cout << "Les caractères autres que '0' et '1' seront ignorés." << endl;
while (true) {
cout << "Tapez le nombre à virgule : ";
cin >> vNb10;
if (vNb10 == 0) {
cout << "Le code binaire vaut : " << "0 00000000 00000000000000000000000" << endl;
return 0; // termine
}
if (vNb10 < 0) {
strNb2 = "1 ";
vNb10 = -vNb10;
}
else { strNb2 = "0 "; }
// défini l'exposant
nExposant = 127;
while (vNb10 < 1) {
nExposant = nExposant - 1;
vNb10 *= 2;
}
while (vNb10 >= 2) {
nExposant = nExposant + 1;
vNb10 /= 2;
}
// Convertit l'exposant en binaire
for (nn=1; nn<=8; nn++) {
if (nExposant > 127) { strNb2 = strNb2 + "1"; nExposant -= 128; }
else { strNb2 = strNb2 + "0"; }
nExposant *= 2;
}
// convertit la mantisse
strNb2 = strNb2 + " "; // le premier chiffre de la mantisse est implicitement égale à 1
vNb10 = (vNb10 - 1) * 2;
for (nn=1; nn<=23; nn++) {
if (vNb10 >= 1) { strNb2 = strNb2 + "1"; vNb10 -= 1; }
else { strNb2 = strNb2 + "0"; }
vNb10 *= 2;
}
cout << "Le code binaire vaut : " << strNb2 << endl << endl;
}
} // version_2
int main() {
//==========
int nVersion = 0;
while (1) { // Boucle sans fin. La fin est dans la boucle
cout << "Binaire->float, tapez 1, Float->binaire, tapez 2, (0=fin) : ";
cin >> nVersion;
if (nVersion == 0) return 0;
else if (nVersion == 1) version_1(); // la version qui effectue le plus de traitements
else if (nVersion == 2) version_2();
} // while
} // main
/*
ex0080_conio_console_in_out.cpp
Pour le compiler, tapez dans un Terminal :
g++ -Wall -o ex0080_conio_console_in_out ex0080_conio_console_in_out.cpp
Séquences escape pour déplacer le curseur dans un Terminal et changer les couleurs.
===================================================================================
C.f : http://ispltd.org/mini_howto:ansi_terminal_codes
Donne la liste des codes "escapes" à écrire dans un Terminal,
pour déplacer le curseur et changer de couleurs.
Chez moi, voir le fichier : VT100_Terminal_Control_Escape_Sequences_-_ISP_How-To.pdf
Attribut foreground background
0 Reset all attributes 30 Black 40 Black
1 Bright 31 Red 41 Red
2 Dim 32 Green 42 Green
4 Underscore 33 Yellow 43 Yellow
5 Blink 34 Blue 44 Blue
7 Reverse 35 Magenta 45 Magenta
8 Hidden 36 Cyan 46 Cyan
37 White 47 White
Exemples :
printf("\e[7A"); // remonte de 7 lignes
printf("\e[7B"); // descend de 7 lignes
printf("\e[7C"); // avance de 7 colonnes
printf("\e[7D"); // recule de 7 colonnes
printf("\e[7;9H"); // va en ligne 7 colonne 9
printf("\e[7;9f"); // va en ligne 7 colonne 9
printf("\e[s"); // sauve la position courante du curseur
printf("\e[u); // restore la position du curseur
printf("\e[); // sauve la position courante du curseur
printf("\e[8); // restore la position du curseur
printf("\e[r"); // permet le "scrolling" de tout l'affichage
printf("\e[7;9r"); // permet le "scrolling" de la ligne 7 à la 9
printf("\e[D"); // "scroll down one line"
printf("\e[M"); // "scroll up one line"
printf("\e[7h"); // Text wraps to next line if longer than the length of the display area.
printf("\e[7l"); // Disables line wrapping.
printf("\e("); // Set default font.
printf("\e[)"); // Set alternate font.
printf("\ec"); // Reset terminal settings to default and clear the Terminal
printf("\e[0m"); // !!! Remise des couleurs par défaut (blanc sur noir).
Pour la lecture d'un caractère du clavier, sans que le programme ne s'arrête.
=============================================================================
Sous Windows :
il existe les fonctions :
dans : #include <conio.h>
Sous Mac OSX :
system("stty raw");
Sous Linux :
rien de standard, la fonction getch() ci-dessous permet de lire le clavier sans arrêter le programme.
Voir aussi : curses et ncurses pour un interface utilisateur en mode texte, dans un Terminal.
C.f. : https://fr.wikipedia.org/wiki/Ncurses
C.f. http://pubs.opengroup.org/onlinepubs/7908799/xcurses/curses.h.html
Réf. générales :
http://www.cplusplus.com/reference/
http://www.cplusplus.com/reference/cmath/
*/
#include <stdio.h> // http://www.cplusplus.com/reference/cstdio/
#include <iostream> // pour cout et cin http://www.cplusplus.com/reference/iostream/
// Juste pour la fonction kbhit(), ci-dessous
#include <termios.h> // Pour : tcgetattr(STDIN_FILENO, &old_tio); // c.f. http://man7.org/linux/man-pages/man3/termios.3.html
#include <unistd.h> // Pour STDIN_FILENO qui vaut 0
#include <fcntl.h> // Pour F_GETFL, O_NONBLOCK
using namespace std;
void kbhit_echo(int nOption, struct termios *pOld_tio) {
//======================================================
// C.f. : https://cboard.cprogramming.com/c-programming/63166-kbhit-linux.html
// C.f. : http://stackoverflow.com/questions/9547868/is-there-a-way-to-get-user-input-without-pressing-the-enter-key
// C.f. : http://shtrom.ssji.net/skb/getc.html
// Si pOld_tio == NULL utilise l'état par défaut d'entrée.
// Si nOption == 0, lit l'état par défaut d'entrée, met un état d'entrée sans ECHO et sans nécessité d'entrer ENTER pour lire un caractère
// et retourne la valeur par défaut d'entrée.
// Si nOption == 1, remet l'état par défaut d'entrée, pOld_tio étant celui retourné lors de l'appelle avec nOption == 0
// force l'ECHO et le ICANON
// Si nOption == 2, remet l'état par défaut d'entrée, pOld_tio étant celui retourné lors de l'appelle avec nOption == 0
// ne force pas l'ECHO et le ICANON, laisse pOld_tio telle qu'il est transmis.
// ICANON = canonical mode, allow input without having to type the Enter key.
// ICANON = mode cannonique, permet l'entrée de caractères sans devoir presser sur le touche Enter.
// ECHO = enable/disable local echo
// ECHO = active/désactive l'affichage des caractères que l'on tape au clavier
if ( (nOption == 0) || (pOld_tio == NULL) ) {
// Lit et mémorise les paramètres actuels de l'entrée stdin
tcgetattr(STDIN_FILENO, pOld_tio); // STDIN_FILENO == 0 par convention
}
if (nOption != 0) {
// Remet l'ancien état d'entrée, pour afficher à l'écran les caractères tapés et qu'une entrée doive se terminer par ENTER.
if (nOption == 1) pOld_tio->c_lflag |= ICANON | ECHO;// pour assurer d'avoir un Echo et que l'on doive presser la touche enter pour terminer une entrée.
tcsetattr(STDIN_FILENO, TCSANOW, pOld_tio); // Remet l'état des paramètres stdin à sa valeur par défaut
return;
}
struct termios new_tio; // Pour les paramètres d'entrée de stdin
// Copie les paramètres
new_tio = *pOld_tio; // *pOld_tio.c_lflag == 0x8a3b
new_tio.c_lflag &= (~ICANON & ~ECHO);
// new_tio.c_lflag = 0x8a31 ICANON == 2 ECHO == 8
// Définit de nouveau paramètres d'entrée stdin
// C.f. : https://man7.org/linux/man-pages/man2/fcntl.2.html
tcsetattr(STDIN_FILENO, TCSANOW, &new_tio);
} // kbhit_echo
int kbhit(int nOption=0) {
//========================
// C.f. : https://cboard.cprogramming.com/c-programming/63166-kbhit-linux.html
// C.f. : http://stackoverflow.com/questions/9547868/is-there-a-way-to-get-user-input-without-pressing-the-enter-key
// C.f. : http://shtrom.ssji.net/skb/getc.html
// Retourne 0 s'il n'y a pas de caractères dans le buffer s'entrée stdin
// retourne le code du caractère s'il y en a un.
// Si nOption == 0, retourne le code du buffer d'entrée, s'il y en a un et l'enlève du buffer d'entrée.
// Si nOption == 1, laisse inchangé le buffer d'entrée (stdin).
// Si nOption == 2, vide le buffer d'entrée (stdin) et retourne le nombre de caractères enlevés du buffer d'entrée.
// _kbhit() _getch() et sous Windows // system("stty raw"); sous OSX
int ch;
int oldf;
int nCompte = 0; // Compte le nombre de caractères qu'il y avait dans le buffer si nOption == 2
oldf = fcntl(STDIN_FILENO, F_GETFL, 0); // Mémorise l'état des conditions d'exécution de la fonction "getch()"
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); // Pour ne pas arrêter l'exécution au : "ch = getchar()"
ch = getchar(); // Lit un code (ou caractère) du buffer s'entrée (stdio), sans arrêter le programme s'il n'y en a pas.
if (nOption == 2) {
// Vide le buffer d'entrée
while (ch != EOF) { ch = getchar(); nCompte++; }
}
fcntl(STDIN_FILENO, F_SETFL, oldf & ~O_NONBLOCK); // Remet l'état des conditions d'exécution de la fonction "getch()" à sa valeur mémorisée.
if (nOption == 2) return nCompte;
if(ch != EOF) {
if (nOption == 1) ungetc(ch, stdin); // Remet le caractère dans le buffer d'entrée
return int(ch);
}
return 0;
} // kbhit
int test01() {
//==========
// Affiche tous les codes de couleurs.
int nX = 1; // lignes
int nY = 1; // colonnes
printf("\ec"); // Efface le contenu du Terminal
// Numérotation des colonnes
nY = 0;
for (nX=0; nX<=7; nX++) {
printf("\e[%i;%iH", 1+2*nY, 4+2*nX);
printf("%2d", nX);
printf("\e[%i;%iH", 1+2*nY, 21+2*nX);
printf("%2d", nX);
printf("\e[%i;%iH", 1+2*nY, 41+2*nX);
printf("%2d", nX);
}
// Numérotation des lignes
nX = 0;
for (nY=0; nY<=7; nY++) {
printf("\e[%i;%iH", 3+2*nY, 2+2*nX);
printf("%2d", nY);
}
// Couleurs normales
for (nY=0; nY<=7; nY++) {
for (nX=0; nX<=7; nX++) {
printf("\e[%i;%iH", 3+2*nY, 5+2*nX);
printf("\e[0;%i;%im", 30+nX, 40+nY); // couleur
printf("*");
}
}
// Couleurs inversées
for (nY=0; nY<=7; nY++) {
for (nX=0; nX<=7; nX++) {
printf("\e[%i;%iH", 3+2*nY, 22+2*nX);
printf("\e[7;%i;%im", 30+nX, 40+nY); // couleur
printf("*");
}
}
// Couleurs plus clairs (Bright)
for (nY=0; nY<=7; nY++) {
for (nX=0; nX<=7; nX++) {
printf("\e[%i;%iH", 3+2*nY, 42+2*nX);
printf("\e[1;%i;%im", 30+nX, 40+nY); // couleur
printf("*");
}
}
// Couleurs assombri (Dim)
for (nY=0; nY<=7; nY++) {
for (nX=0; nX<=7; nX++) {
printf("\e[%i;%iH", 3+2*nY, 62+2*nX);
printf("\e[2;%i;%im", 30+nX, 40+nY); // couleur
printf("*");
}
}
// Couleurs soulignées (Underscore)
for (nY=0; nY<=7; nY++) {
for (nX=0; nX<=7; nX++) {
printf("\e[%i;%iH", 3+2*nY, 82+2*nX);
printf("\e[4;%i;%im", 30+nX, 40+nY); // couleur
printf("*");
}
}
// Couleurs clignotantes (Blink)
for (nY=0; nY<=7; nY++) {
for (nX=0; nX<=7; nX++) {
printf("\e[%i;%iH", 3+2*nY, 102+2*nX);
printf("\e[5;%i;%im", 30+nX, 40+nY); // couleur
printf("*");
}
}
printf("\e[20;1H"); // Va en-dessous de ce qui a été affiché.
printf("\e[0m"); // Remise des couleurs par défaut (blanc sur noir).
printf("Terminé\n");
return 0;
} // test01
int test02() {
//============
// Quelques exemples
printf("\ec"); // Efface le contenu du Terminal
printf(" line 1\n");
printf(" line 2");
printf("\xd line 3"); // \xd revient en début de ligne.
printf("\e[0;33;44m"); // jaune sur fond bleu
// c.f. c
printf("\e[A"); // remonte d'une ligne
printf("line 4\n\n\n");
printf("\e[7C"); // avance le curseur de 7 caractères.
printf("*");
printf("\e[2D"); // recule le curseur de 2 caractères.
printf("#");
printf("\e[7;9f");
printf("7;9");
printf("\e[12;23H"); // positionne le curseur en ligne 12 et col. 23
printf("ligne 12, colone 23");
printf("\e[0;37;40m"); // jaune sur fond bleu
printf("\e[8;1H"); // positionne le curseur en ligne 12 et col. 23
printf("ligne 8, colone 1");
printf("\e[5B"); // descent le curseur de 5 lignes
printf("\e[0;30;47m"); // jaune sur fond blanc
printf("\e[20;1H"); // positionne le curseur
printf("\e[0m"); // Remise des couleurs par défaut (blanc sur noir).
printf("Terminé\n");
return 0;
} // test02
void Affiche(int nX, int nY, char cDisp) {
//========================================
// Affiche le caractère cDisp en grand à la position nX, nY
string astrS[12];
printf("\e[%i;%iH", nY, nX);
for (int nn=0; nn<=10; nn++) {
astrS[nn] = "";
}
if (cDisp == '0') {
astrS[ 1] = " ****** ";
astrS[ 2] = "* *";
astrS[ 3] = "* *";
astrS[ 4] = "* *";
astrS[ 5] = "* *";
astrS[ 6] = "* *";
astrS[ 7] = "* *";
astrS[ 8] = "* *";
astrS[ 9] = "* *";
astrS[10] = " ****** ";
}
if (cDisp == '1') {
astrS[ 1] = " ** ";
astrS[ 2] = " ** * ";
astrS[ 3] = "** * ";
astrS[ 4] = " * ";
astrS[ 5] = " * ";
astrS[ 6] = " * ";
astrS[ 7] = " * ";
astrS[ 8] = " * ";
astrS[ 9] = " * ";
astrS[10] = " *******";
}
if (cDisp == '2') {
astrS[ 1] = " ** ";
astrS[ 2] = " * * ";
astrS[ 3] = " * * ";
astrS[ 4] = " * * ";
astrS[ 5] = " * ";
astrS[ 6] = " * ";
astrS[ 7] = " * ";
astrS[ 8] = " * ";
astrS[ 9] = "* ";
astrS[10] = "********";
}
if (cDisp == '3') {
astrS[ 1] = " *** ";
astrS[ 2] = " * **";
astrS[ 3] = " ** ";
astrS[ 4] = " ** ";
astrS[ 5] = " ** ";
astrS[ 6] = " ** ";
astrS[ 7] = " ** ";
astrS[ 8] = " ** ";
astrS[ 9] = " * **";
astrS[10] = " *** ";
}
if (cDisp == '4') {
astrS[ 1] = " * ";
astrS[ 2] = " ** ";
astrS[ 3] = " * * ";
astrS[ 4] = " * * ";
astrS[ 5] = " * * ";
astrS[ 6] = " * * ";
astrS[ 7] = "********";
astrS[ 8] = " * ";
astrS[ 9] = " * ";
astrS[10] = " * ";
}
if (cDisp == '5') {
astrS[ 1] = "******* ";
astrS[ 2] = "* ";
astrS[ 3] = "* ";
astrS[ 4] = "* ";
astrS[ 5] = "****** ";
astrS[ 6] = " * ";
astrS[ 7] = " *";
astrS[ 8] = "* *";
astrS[ 9] = " * * ";
astrS[10] = " **** ";
}
// À compléter pour les autres chiffres
for (int nn=0; nn<=9; nn++) {
printf("\e[%i;%iH", nY+nn, nX);
cout << astrS[nn+1];
}
} // Affiche
int test03() {
//============
char cDisp; // le caractère à afficher
int nXPos = 1; // position du caractère
int nYPos = 1;
printf("\ec"); // Reset des attributs
kbhit_echo(0, &Old_tio); // Mémorise l'état d'entrée du clavier et permet l'entrée sans ECHO, ni devoir presser sur ENTER.
while (true) {
cDisp = kbhit(0); // Lecture de l'état du clavier
if ( (cDisp >= '0') && (cDisp <= '5') ) {
Affiche(nXPos, nYPos, cDisp);
nXPos += 10;
if (nXPos > 70) { nXPos = 1; nYPos +=11; }
}
if (cDisp == 27) break; // ESC a été pressé.
}
kbhit_echo(1, &Old_tio); // Remet l'état d'entrée du clavier normal, avec ECHO et en devant presser sur ENTER.
printf("\e[20;2H"); // Positionnement sous le texte affiché.
printf("\e[0m"); // Remise des couleurs par défaut (blanc sur noir).
printf("Terminé\n");
return 0;
} // test03
int main() {
//==========
int nVersion = 0;
while (1) { // Boucle sans fin. La fin est dans la boucle
cout << "Quel test voulez-vous effectuer ? Entre 1 et 3 (0=fin) : ";
cin >> nVersion;
kbhit(2); // Vide le buffer d'entrée
if (nVersion == 0) return 0;
else if (nVersion == 1) test01();
else if (nVersion == 2) test02();
else if (nVersion == 3) test03();
} // while
} // main
/*
ex0090_imprecisions_numeriques.cpp
Imprécision numériques qui mène à des erreurs.
Pour le compiler, tapez dans un Terminal :
g++ -Wall -o ex0090_imprecisions_numeriques ex0090_imprecisions_numeriques.cpp
C.f. : http://www.cplusplus.com/reference/cmath/
*/
#include <iostream>
#include <cmath> // pour les fonctions mathématiques, sqrt = racine carrée.
#include <stdio.h>
using namespace std;
int test01() {
//============
float vX0, vX1, vX2;
int nCpt;
// x^2 = x + 1, donc x^(n+1) = x^n + x^(n-1), converge vers 0 théoriquement
// pour x = vX1;
vX0 = 1.0;
vX1 = (1 - sqrt(5)) / 2;
printf("x^0 = 1\nx = %9.5f\n", vX1);
for (nCpt = 2; nCpt <= 45; nCpt++) {
vX2 = vX1 + vX0;
// cout << 10000+nCpt << " " << vX2 << endl;
printf("x^%2d = %9.5f\n", nCpt, vX2);
vX0 = vX1;
vX1 = vX2;
}
printf("La suite converge théoriquement vers 0\n");
return 0;
} // test01
int test02() {
//==========
// Erreur de ((x+1)^3 - 3*x*(x+1) - 1) / x^3
float vX, vX1, vFX;
int nCpt;
for (nCpt = 1; nCpt >= -10; nCpt--) {
vX = pow(10, nCpt);
vX1 = vX + 1;
vFX = (vX1*vX1*vX1 - 3*vX*(vX+1) - 1) / (vX*vX*vX);
printf("x = %8.0e F(x) = %15.8f\n", vX, vFX);
}
printf("Le résultat est théoriquement toujours égale à 1\n");
return 0;
} // test02
int test03() {
//============
// Erreur de ((x+1)^2 - 1) / x
float vX, vX1, vFX;
int nCpt;
vX=10;
for (nCpt = 1; nCpt <= 45; nCpt++) {
vX = vX*10;
cout << vX << endl;
}
for (nCpt = -1; nCpt >= -25; nCpt--) {
vX = pow(10, nCpt);
vX1 = vX + 1;
// vFX = (vX1*vX1 - 1) / vX;
vFX = (vX1*vX1 - 1);
vFX = vFX / vX;
printf("x = %8.0e F(x) = %15.8f\n", vX, vFX);
}
printf("Le résultat est théoriquement toujours égale à 2 + x\n");
return 0;
} // test03
int test04() {
//============
// Précision des calculs, nombre tel que 1+e != 1
float vE, vE1;
//double vE, vE1;
int nCpt = 0;
vE = 1;
vE1 = 1 + vE;
do {
printf("n, e = %4d %12.6e\n", nCpt, vE);
nCpt++;
vE = vE / 2.0;
vE1 = 1 + vE;
} while (vE1 != 1);
printf("Détermination du plus petit nombre positif e, tel que (1 + e) == 1\n");
return 0;
} // test04
int main() {
//==========
int nVersion = 0;
while (1) { // Boucle sans fin. La fin est dans la boucle
cout << "Quel test voulez-vous effectuer ? Entre 1 et 4 (0=fin) : ";
cin >> nVersion;
if (nVersion == 0) return 0;
else if (nVersion == 1) test01();
else if (nVersion == 2) test02();
else if (nVersion == 3) test03();
else if (nVersion == 4) test04();
} // while
}
/*
ex0100_Fonction_Reference_Tableau.cpp
Exemples :
// Les fonctions.
// Passage de paramètres par valeur et par référence
// Les tableaux
// Algorithmes de tris.
// Une définition récursive de fonction.
Pour le compiler, tapez dans un Terminal :
g++ -Wall -o ex0100_Fonction_Reference_Tableau ex0100_Fonction_Reference_Tableau.cpp
C.f. : http://www.cplusplus.com/reference/cmath/
*/
#include <iostream>
#include <iomanip> // std::setprecision
#include <stdio.h> // pour printf et sprintf
#include <math.h> // utile ??
// c.f. http://www.cplusplus.com/reference/limits/numeric_limits/
#include <limits>
#include <stdlib.h> // pour random : rand(...)
// c.f. http://www.cplusplus.com/reference/cstdlib/rand/
// rand() retourn un nombre entier entre 1 et RAND_MAX
// RAND_MAX vaut : 2'147'483'647 = 2^31 - 1 habituellement.
//##########################################################
using namespace std;
// 1.
// Un simple exemple de fonction.
int FoisDeux(int nVal) {
//======================
// Retourn la valeur nVal multipliée par deux.
return nVal*2;
} // FoisDeux
void test01() {
//============
// test01 est un exemple de fonction.
// "void" signifie qu'elle ne retourne aucune valeur
int nVal = 7;
cout << "nVal=" << nVal << " son double vaut " << FoisDeux(nVal) << endl;
} // test01
//#############################################################
// 2.
// Comment faire pour retourner deux valeurs ?
// Par exemple, retourner la valeur fois 2 et la valeur plus 2.
// Dans l'exemple précédent, on transmettait "nVal" par VALEUR.
// Ici, on va transmettre une variable par REFERENCE.
void FoisPlusDeux(int nVal, int& rnFois, int& rnPlus) {
//=====================================================
// Retourn dans rnFois la valeur nVal multipliée par deux.
// Retourn dans rnPlus la valeur nVal additionnée de deux.
// "void" signifie qu'elle ne retourne aucune valeur
rnFois = nVal * 2;
rnPlus = nVal + 2;
} // FoisPlusDeux
void test02() {
//============
// Test la transmission par VALEUR et par REFERENCE
int nVal = 7;
int nFois = 0, nPlus = 0;
FoisPlusDeux(nVal, nFois, nPlus);
cout << "nVal=" << nVal << " son double vaut " << nFois
<< " additionné de deux donne " << nPlus << endl;
} // test02
//#############################################################
// 3.
// Utilisation de transmission par REFERENCE pour échanger
// la valeur de deux variables.
void Echange(double& rvA, double& rvB) {
//======================================
// Echange les contenus des deux variables, rVa et rvB
double vTemp = rvA;
rvA = rvB;
rvB = vTemp;
} // Echange
void test03() {
//============
// Test l'exemple d'échange de deux valeurs.
double vA = 1.1, vB = 2.2;
cout << "A=" << vA << " et B=" << vB << endl;
Echange(vA, vB);
cout << "Après échange :" << endl;
cout << "A=" << vA << " et B=" << vB << endl;
} // test03
//#############################################################
// 4.
// Exemple de :
// i) Déclaration de constante
// ii) Utilisation de tableaux de valeurs
// iii) Transfert de tableaux comme paramètres.
void MinMax1( unsigned int nIndMax, double avVals[],
double& rvMin, double& rvMax) {
//===========================================
// Retourn dans rvMin la valeur min. de avVals[nIndMax].
// Retourn dans rvMax la valeur max. de avVals[nIndMax].
// La règle est qu'un tableau est toujours transmis par référence
// Le défaut est que le programmeur peut se tromper et modifier
// une valeur du tableau, ce qui serai une erreur désagrable.
// C.f. l'amélioration MinMax2.
unsigned int nn=0;
rvMin = avVals[0];
rvMax = rvMin;
for (nn=0; nn<=nIndMax; nn++) {
if (rvMin > avVals[nn]) rvMin = avVals[nn];
if (rvMax < avVals[nn]) rvMax = avVals[nn];
}
// Le compilateur accepte que l'on modifie une valeur du tableau.
// Cela est parfois désiré, parfois mène à des erreurs.
avVals[0]=rvMin;
} // MinMax1
void MinMax2( unsigned int nIndMax, double const avVals[],
double& rvMin, double& rvMax) {
//===========================================
// Retourn dans rvMin la valeur min. de avVals[nIndMax].
// Retourn dans rvMax la valeur max. de avVals[nIndMax].
// L'avantage de cette manière est que le compilateure vérifie
// que le tableau avVals n'est pas modifié, malgré qu'il est aussi
// transmis par référence.
unsigned int nn=0;
rvMin = avVals[0];
rvMax = rvMin;
for (nn=0; nn<=nIndMax; nn++) {
if (rvMin > avVals[nn]) rvMin = avVals[nn];
if (rvMax < avVals[nn]) rvMax = avVals[nn];
}
// Le compilateur Refuse que l'on modifie une valeur du tableau.
// C'est une sécurité à la compilation, pour éliminer des erreurs potentiels.
// avVals[0]=rvMin;
} // MinMax2
void test04() {
//============
// Teste les exemples de recherche de min et de max
// déclaration d'une constante qui sera la dimension du tableau avNb
unsigned int const nDim = 100;
// décalaration du tableau. L'indice ira de 0 à nDim-1
// Attention au "-1"
double avNb[nDim];
unsigned int nIndMax = 50; // Indice maximum utilisé du tableau.
double vX, vMin, vMax;
double vMin2, vMax2;
for (unsigned int nn=0; nn<=nIndMax; nn++) {
// rempli le tableau avec des valeurs du polynome y = x^3 - x + 0.1
vX = -1.0 + 2.0 * nn / nIndMax; // varie de -1 à 1
avNb[nn] = vX*vX*vX - vX + 0.1;
// pour des vérifications
// cout << "X=" << vX << " Y=" << avNb[nn] << endl;
printf("X=%9.3f, Y=%9.5f\n", vX, avNb[nn]);
}
MinMax1(nIndMax, avNb, vMin, vMax);
cout << "Min=" << vMin << " Max=" << vMax << endl;
// Cette fonction et avantageuse sur la précédente.
MinMax2(nIndMax, avNb, vMin2, vMax2);
cout << "Min=" << vMin2 << " Max=" << vMax2 << endl;
} // test04
//#############################################################
// 5.
// Exercice.
// Ecrivez une fonction qui trie les valeurs d'un tableau
// de la plus petite valeur à la plus grande.
// Il existe de nombreuses méthodes, certaines sont
// beaucoup plus efficaces que d'autres.
void Sort1( unsigned int const nIndMax, double avVals[]) {
//========================================================
// Trie les valeurs de avVals[nIndMax] du plus petit au plus grand.
// Le tableau est donc modifié.
// Non optimal, avec allocation dynamique de mémoire
unsigned int nn=0, nInd=0, nIndMin=0;
double vMin;
// alloue de la mémoire temporairement, pour le traitement.
double *pavT = NULL; // NULL = 0, utile pour des pointeurs.
pavT = new double [nIndMax+1];
// double *pavT = new double [nIndMax+1]; // est aussi possible
// Recopie le tableau dans pavT[0..nIndMax]
for (nn=0; nn<=nIndMax; nn++) pavT[nn] = avVals[nn];
// le plus grand entier signé sur 32 bits
//cout << numeric_limits<int>::max() << endl;
// le plus grand double
//cout << std::numeric_limits<double>::max() << endl;
// c.f. http://www.cplusplus.com/reference/limits/numeric_limits/
// Tri
for (nInd=0; nInd<nIndMax; nInd++) {
// recherche la plus petite valeur dans pavVals[nInd..nIndMax]
vMin = pavT[nInd];
nIndMin = nInd; // Mémorise l'indice de la plus petite valeur
for (nn=1; nn<=nIndMax; nn++) {
if (vMin > pavT[nn]) { vMin = pavT[nn]; nIndMin = nn; }
}
// Place la plus petite valeur trouvée dans le tableau d'origine
avVals[nInd] = pavT[nIndMin];
pavT[nIndMin] = std::numeric_limits<double>::max(); // détruit la valeur pour qu'elle ne réapparaisse pas
}
// Libère la mémoire allouée temporairement
delete[] pavT;
pavT = NULL; // inutile ici, mais c'est une bonne habitude à prendre.
} // Sort1
void Sort2( unsigned int const nIndMax, double avVals[]) {
//========================================================
// Trie les valeurs de avVals[nIndMax] du plus petit au plus grand.
// Le tableau est donc modifié.
unsigned int nn=0, nInd=0, nIndMin=0;
double vMin;
for (nInd=0; nInd<nIndMax; nInd++) {
// recherche la plus petite valeur dans avVals[nInd..nIndMax]
vMin = avVals[nInd];
nIndMin = nInd; // Mémorise l'indice de la plus petite valeur
for (nn=nInd+1; nn<=nIndMax; nn++) {
if (vMin > avVals[nn]) { vMin = avVals[nn]; nIndMin = nn; }
}
// Utilise la fonction Echange vue précédemment, pour
// placer la plus petite valeur en position nInd.
Echange(avVals[nInd], avVals[nIndMin]);
}
} // Sort2
void test05() {
//=============
// Teste la fonction Sort1() de tri par ordre croissant.
// déclaration d'une constante qui sera la dimension du tableau avNb
unsigned int const nDim = 100;
// décalaration du tableau. L'indice ira de 0 à nDim-1
// Attention au "-1"
double avNb[nDim];
unsigned int nIndMax = 30; // Indice maximum utilisé du tableau.
double vX;
// initialize random seed:
srand (time(NULL));
for (unsigned int nn=0; nn<=nIndMax; nn++) {
// rempli le tableau avec des valeurs du polynome y = x^3 - x + 0.1
vX = -1.0 + 2.0 * nn / nIndMax; // varie de -1 à 1
avNb[nn] = vX*vX*vX - vX + 0.1;
// Autre manière, remplissage au hasard
// avNb[nn] = 1.0 * rand() / RAND_MAX; // nombres entre 0 et 1.
// pour des vérifications
printf("X=%9.3f, Y=%9.5f\n", vX, avNb[nn]);
}
// Trie les valeurs du tableau par ordre croissant.
Sort1(nIndMax, avNb);
// Affiche les valeurs triées du tableau
cout << "Du plus petit au plus grand, avec Sort1 :" << endl;
for (unsigned int nn=0; nn<=nIndMax; nn++) {
printf("%9.5f\n", avNb[nn]);
}
} // test05
//#############################################################
// 6.
// Exercice.
// Ecrivez une fonction qui trie les valeurs d'un tableau
// de la plus petite valeur à la plus grande.
// Méthode quicksort, récursive, très rapide.
void QuickSort( int const nIndMin,
int const nIndMax,
double avVals[]) {
//==========================================================
// Trie les valeurs de avVals[nIndMin..nIndMax] du plus petit au plus grand.
// Le tableau est donc modifié.
// Place au début de tableau toutes les valeurs inférieurs à vRef
// ensuite place les valeurs égales à vRef
// place ensuite toutes les valeurs plus grandes que vRef.
int nL=0, nR=0; // Indices Left et Right
double vPivot;
nL=nIndMin; nR=nIndMax;
vPivot=avVals[(nL+nR)/2];
// servira à séparer les éléments en plaçant à gauche les plus petit que vPivot
// et à droite les plus grand que vPivot.
do {
// Cherche depuis la gauche un élément plus grand que vPivot
while (avVals[nL] < vPivot) nL++; // s'arrête forcément !
// Cherche depuis la droite un élément plus petit que vPivot
while (avVals[nR] > vPivot) nR--; // s'arrête forcément !
// Utilise la fonction Echange vue précédemment, pour
// placer la plus petite valeur à gauche et la plus grande à droite.
if (nL < nR) Echange(avVals[nL], avVals[nR]);
if (nL <= nR) {nL++; nR--; } // pour passer aux éléments suivants.
} while (nL <= nR);
// Ici, les élèments "<=vPivot" sont à gauche (nIndMin..nR)
// et ceux plus ">=vPivot" sont à droite (nL..nIndMax)
// On refait le même placement sur les sous-tableaux, gauche et droit.
// Pour cela on fait appelle à de la récursivité, c'est-à-dire
// qu'une fonction s'appelle elle-même.
if (nIndMin < nR ) QuickSort(nIndMin, nR, avVals);
if (nL < nIndMax) QuickSort(nL, nIndMax, avVals);
} // QuickSort
// Trois améliorations possibles.
// 1) Meilleur choix du pivot
// 2) Tri différent si moins de 6 éléments à trier
// 3) L'odre des appels récursifs à tester pour minimiser
// la profondeur de récursivité.
void test06() {
//=============
// Teste la fonction Quicksort() de tri par ordre croissant.
// déclaration d'une constante qui sera la dimension du tableau avNb
unsigned int const nDim = 100;
// décalaration du tableau. L'indice ira de 0 à nDim-1
// Attention au "-1"
double avNb[nDim];
int nIndMax = 30; // Indice maximum utilisé du tableau.
double vX;
// initialize random seed:
srand (time(NULL));
for (int nn=0; nn<=nIndMax; nn++) {
// rempli le tableau avec des valeurs du polynome y = x^3 - x + 0.1
vX = -1.0 + 2.0 * nn / nIndMax; // varie de -1 à 1
avNb[nn] = vX*vX*vX - vX + 0.1;
// Autre manière, remplissage au hasard
// avNb[nn] = 1.0 * rand() / RAND_MAX; // nombres entre 0 et 1.
// pour des vérifications
printf("nn=%3d, X=%9.3f, Y=%9.5f\n", nn, vX, avNb[nn]);
}
// Trie les valeurs du tableau par ordre croissant.
QuickSort(0, nIndMax, avNb);
// Affiche les valeurs triées du tableau
cout << "Du plus petit au plus grand, avec Quicksort :" << endl;
for (int nn=0; nn<=nIndMax; nn++) {
printf("%9.0f\n", 10000*avNb[nn]);
}
} // test06
//#############################################################
// 7.
// Exemple plus simple d'appel récursif.
// Calcul de la fonction factorielle.
// Par définition, n! = n * (n-1)! et 0! = 1.
int64_t Factoriel(int const nNb) {
//================================
// Calcul la factoriel de nNb
// Fonctionne pour nNb compris entre 0 et 20,
// ensuite on dépasse les capacités de l'ordinateur.
if (nNb <= 0) return 1;
return nNb * Factoriel(nNb-1);
} // Factoriel
void test07() {
//============
// Teste la fonction Factorielle, définie récursivement.
int64_t nNb;
do {
cout << "Entrez un nombre entier entre 0 et 20 : ";
cin >> nNb;
cout << nNb << "! = " << Factoriel(nNb) << endl;
} while (nNb > 0);
} // test07
//#############################################################
int main() {
//==========
int nVersion = 0;
while (1) { // Boucle sans fin. La fin est dans la boucle
cout << "Quel test voulez-vous effectuer ? Entre 1 et 7 (0=fin) : ";
cin >> nVersion;
if (nVersion == 0) return 0;
else if (nVersion == 1) test01();
else if (nVersion == 2) test02();
else if (nVersion == 3) test03();
else if (nVersion == 4) test04();
else if (nVersion == 5) test05();
else if (nVersion == 6) test06();
else if (nVersion == 7) test07();
} // while
return 0;
}
/*
ex0110_jour_de_semaine.cpp
Calcul du jour de la semaine d'une date donnée.
L'algorithme est très simple et peut être fait de tête.
c.f. http://www.juggling.ch/zgisin/a2015_oc3/index.html pour une version en javascript.
Pour le compiler, tapez dans un Terminal :
g++ -Wall -o ex0110_jour_de_semaine ex0110_jour_de_semaine.cpp
C.f. : http://www.cplusplus.com/reference/cmath/
*/
#include <iostream>
#include <iomanip>
#include <cmath>
#include <stdlib.h>
// Opérateurs :
// + - * / % = modulo
using namespace std;
void test01() {
//=============
// Calcul du jour de la semaine d'une date donnée.
int nJour = 1; // le jour
int nMois = 1; // le mois
int nAnnee = 2000; // l'année
string strJour = "???"; // le jour de la semaine correspondant
cout << "Indique le jour de la semaine d'une date donnée." << endl;
cout << "Entrez la date sous la forme jour mois année, avec des espaces entre deux." << endl;
cout << "Exemple : 25 11 2014." << endl;
cout << "Date = ";
cin >> nJour >> nMois >> nAnnee;
cout << nJour << " " << nMois << " " << nAnnee << endl; // Tests
// Calcule le nombre correspondant au mois.
int nNumMois = 0; // pour mémoriser le nombre correspondant au mois
if (nMois == 2) nNumMois = 3; // pour février
if (nMois == 3) nNumMois = 3; // pour mars
if (nMois == 4) nNumMois = 6; // pour avril
if (nMois == 5) nNumMois = 1; // pour mai
if (nMois == 6) nNumMois = 4; // pour juin
if (nMois == 7) nNumMois = 6; // pour juillet
if (nMois == 8) nNumMois = 2; // pour aout
if (nMois == 9) nNumMois = 5; // pour septembre
if (nMois == 10) nNumMois = 0; // pour octobre
if (nMois == 11) nNumMois = 3; // pour novembre
if (nMois == 12) nNumMois = 5; // pour décembre
cout << nMois << " " << nNumMois << endl; // Pour des tests.
// Calcule le nombre correspondant à l'année.
int nAn = nAnnee % 100; // nAn = reste de la division par 100 de nAnnee
int nNumAn = nAn + (nAn / 4); // pour mémoriser le nombre correspondant à l'année
cout << nAn << " " << nNumAn << endl; // Pour des tests.
// Traite le siècle.
if ((nAnnee >= 2000) && (nAnnee <= 2099)) nNumAn = nNumAn - 1;
// Traite le cas des années bissectiles.
if ( ((nAnnee % 4 == 0) && (nAnnee % 100 != 0)) || (nAnnee % 400 == 0) ) {
if (nMois <= 2) nNumAn = nNumAn - 1;
}
// Calcule finale du jour de la semaine cherché.
int nNumJour = (7 + nJour + nNumMois + nNumAn) % 7; // nJour = reste de la division par 7 de ...
cout << nJour << " " << nNumMois << " " << nNumAn << " " << nNumJour << endl; // pour des tests
if (nNumJour == 0) strJour = "dimanche";
if (nNumJour == 1) strJour = "lundi";
if (nNumJour == 2) strJour = "mardi";
if (nNumJour == 3) strJour = "mercredi";
if (nNumJour == 4) strJour = "jeudi";
if (nNumJour == 5) strJour = "vendredi";
if (nNumJour == 6) strJour = "samedi";
cout << "Le jour correspondant est un " << strJour << endl;
} // test01
int main() {
//==========
test01();
} // main
Plan du Site :
Home
Langages
cpp.html
( = http://www.juggling.ch/gisin/cpp/cpp.html )
Page mise à jour le 28 mai 2021 par Bernard Gisin
( Envoyer un e-mail )
Hébergement par : www.infomaniak.ch