IFT 1179 : Programmation en C#
A) Les chaînes de caractères (string)
string est un surnom (alias) de la classe System.String string dispose des informations de la classe String.
Notez que
"Bonsoir", "a"sont des chaînes de caractères (string) tandis que ‘a’, ‘7’ sont des caractères (char).
1. Déclaration et initialisation:
string souhait =
"Bonne soiree!";2. Quelques manipulations:
a) concatenation : +
string A = "Bonsoir", B = " tout le monde", C;
C = A + B;
Console.WriteLine("La chaine C : {0} de longueur{1}", C,
C.Length);
Ces instructions affichent :
La chaine C : Bonsoir tout le monde de longueur 21
On utilise souvent l’opérateur de concaténation pour afficher les informations dans les premiers exemples de C#:
Les instructions :
int age = 23;
double taille = 1.75;
Console.WriteLine("La personne a " + age + " ans et mesure "
+ taille + " metre");
affichent :
La personne a 23 ans et mesure 1,75 metre b) accès à un caractère de la chaîne :
Console.WriteLine("A[0] vaut {0} et B[1] vaut {1}",
A[0], B[1]);
Cette instruction affiche :
A[0] vaut B et B[1] vaut t
c) extrait d’une sous-chaîne (substring) : Les instructions :
string souhait = "Bonsoir";
// extrait une sous-chaîne de 3 caractères à partir de // l’indice 0
Console.WriteLine("souhait.Substring(0, 3) vaut {0}", souhait.Substring(0, 3));
// extrait une sous-chaîne de à partir de l’indice 0 // jusqu’à la fin de la chaîne :
Console.WriteLine("souhait.Substring(3) vaut {0}",
souhait.Substring(3));
affichent :
souhait.Substring(0, 3) vaut Bon
souhait.Substring(3) vaut soir
Press any key to continue
d) recherche dans une chaîne ( - 1 pour non trouvée ) :
0123456
string souhait = "Bonsoir";
souhait.IndexOf('o') vaut 1 souhait.LastIndexOf('o') vaut 4
souhait.IndexOf("on") vaut 1
etc . . .
e) conversion :
"Bonsoir".ToUpper() retourne "BONSOIR"
"Bonsoir".ToLower() retourne "bonsoir"
f) suppression des espaces (au début, à la fin) : Trim : au début et à la fin
TrimEnd : à la fin TrimStart : au début
" Bonsoir ".Trim() retourne "Bonsoir"
" Bonsoir ".TrimEnd() retourne " Bonsoir"
g) comparaison de chaînes de caractères
La méthode la plus courante en POO pour comparer deux chaînes de caractères est CompareTo :
public int CompareTo(string);
chaine1. CompareTo(chaine2) retourne un entire :
< 0 quand chaine1 < chaine2
0 quand les deux disposent du même contenu
> 0 quand chaine1 > chaine2
(Attention, en culture « américaine »,
"A" > "a"Cette culture affecte très peu, en pratique, les résultats
de tri concernant des chaînes de caractères).
h) décomposition en mots grâce au séparateurs
public string[] Split(char[] separateurs, int maxMots);
Exemple:
using System;
class Metro {
/* Cette méthode permet d'afficher de la manière sommaire (sans présentation ni de détails des stations)
à partir d'une station et des caractères de séparateurs qui délimitent les informations d'une station
*/
static void Afficher(char[] separateurs, string station) {
// décomposer la chaîne en tableau de 3 chaînes grâce aux // séparateurs
string[] infosMetro = station.Split(separateurs, 3);
Console.WriteLine("Affichage sans presentation ni de details :");
// pour chaque information qui fait partie du tableau foreach( string info in infosMetro)
Console.WriteLine(info);
Console.WriteLine();
}
/* Cette méthode permet d'afficher de la manière détaillée les informations d'une station de métro
*/
static void Afficher(string station, char[] separateurs) {
string[] infosMetro = station.Split(separateurs, 3);
string nomStation = infosMetro[0];
int rang2003 = int.Parse(infosMetro[1]);
// conversion de chaîne en entier
int freq2004 = int.Parse(infosMetro[2]);
Console.WriteLine("Informations de la station de metro :");
Console.WriteLine(" - son nom : " + nomStation);
Console.WriteLine(" - son rang en 2003 : {0, 12:D}", rang2003);
Console.WriteLine(" - frequence en 2004 : {0, 12:D}", freq2004);
}
static void Main(string[] args) {
string station1 = "COTE-DES-NEIGES(26)3509564",
// la station de métro COTE-DES-NEIGES était classée 26 ième rang // en 2003 et elle a été fréquentée par 3 509 564 passagers en 2004 station2 = "UNIVERSITE-DE-MONTREAL(38)2610922";
// la station de métro UNIVERSITE-DE-MONTREAL était classée 38 ième // rang en 2003 et elle a été fréquentée par 2 610 922 passagers en // 2004
char[] separateurs = new char[] {'(', ')'};
Afficher(separateurs, station1); // affichage d'une manière Afficher(station2, separateurs); // affichage d'une autre // manière
} }
/* Exécution:
Affichage sans presentation ni de details : COTE-DES-NEIGES
26 3509564
Informations de la station de metro :
- son nom : UNIVERSITE-DE-MONTREAL - son rang en 2003 : 38
- frequence en 2004 : 2610922 Press any key to continue
*/
Autre exemple de string :
/* Fichier String_1.cs (1er exemple sur le type string) * Comme C# est TOUT objet, le type string dispose aussi * des champs, des methodes comme une classe :
* chaine.Length : retourne la longueur d'une chaine
* chaine[indice] : retourne le caractere a l'indice mentionne * chaine.ToUpper(): retourne la chaine en tous majuscules * chaine.ToLower(): retourne la chaine en tous minuscules * chaine.Substring(indDepart, longueur) :
* retourne une sous-chaine de telle longueur * a partir de tel indice
* chaine.Substring(indDepart) :
* retourne une sous-chaine a partir de tel indice * jusqu'a la fin de la chaine
* chaine.IndexOf(un caractere) :
* retourne l'indice du premier caractere trouve * (-1 si introuvable)
* chaine.LastIndexOf(un caractere) :
* retourne l'indice du dernier caractere trouve * (-1 si introuvable)
* chaine.Split(tableau de caracteres de separation, nb. maximum de * mots decomposes)
* retourne un tableau de string qui contient des mots de la * chaine
* grâce au tableau de separateur(s) des mots.
* La méthode Split est trèss utile (entre autres) pour le TP1 *
*/
using System;
class String1 {
static void Main(string[] args) {
string souhait = "Comment allez-vous? On vous souhaite une bonne session!";
Console.WriteLine("La chaine : {0} \nde longueur {1}", souhait, souhait.Length);
Console.WriteLine("Le caractere a l'indice 2 : {0}", souhait[2]);
Console.WriteLine("En tous majuscules : {0}", souhait.ToUpper());
Console.WriteLine("En tous minuscules : {0}", souhait.ToLower());
Console.WriteLine("Trois premiers caracteres : {0}", souhait.Substring(0, 3));
Console.WriteLine("Indice de la premiere lettre O : {0}", souhait.IndexOf('O'));
Console.WriteLine("Une autre sous-chaine : {0}", souhait.Substring(20));
Console.WriteLine("Indice de la derniere lettre e : {0}", souhait.LastIndexOf('e'));
Console.WriteLine("Indice de la premiere lettre f : {0}(non trouve)", souhait.IndexOf('f'));
char[] separateurs = new char[] {'!', ' ', '-', '?'};
string[] mots = souhait.Split(separateurs, 15); //au max. 15 mots Console.WriteLine("\nLes mots de la chaine :");
foreach(string mot in mots) if (mot.Length > 0)
Console.WriteLine(mot);
Console.WriteLine();
}
}
/* Execution:
La chaine : Comment allez-vous? On vous souhaite une bonne session!
de longueur 55
Le caractere a l'indice 2 : m
En tous majuscules : COMMENT ALLEZ-VOUS? ON VOUS SOUHAITE UNE BONNE SESSION!
En tous minuscules : comment allez-vous? on vous souhaite une bonne session!
Trois premiers caracteres : Com Indice de la premiere lettre O : 20
Une autre sous-chaine : On vous souhaite une bonne session!
Indice de la derniere lettre e : 48
Indice de la premiere lettre f : -1(non trouve) Les mots de la chaine :
Comment allez vous On vous souhaite une bonne session
Press any key to continue
*/
i) Autres informations :
Voir autres exemples sur le site Web et les détails des méthodes au lien : http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/cpref/html/frlrfsystemstringmemberstopic.asp
B) Le type structure
1) Introduction
Le type structure (mot clé struct) est l’ancêtre du concept encapsualation de la POO.
En Pascal ou C, une variable de ce type dispose des champs d’informations seulement. Le C++, Java
permettent d’ajouter aussi des méthodes à l’intérieur d’une structure.
C’est la même chose pour C#.
Dans le cours IFT 1179, on étudie un peu plus sur la POO et on minimise le type structure.
Vous trouverez ci-après deux exemples qui seront expliqués en classe :
Exemple 1 :
/* Fichier Struct1.cs (1er exemple du type structure) * Observez l'accès à un champ d'information :
* variable.champ */
using System;
// structure sans fonctions (style de Pascal et du C)
struct Personne {
public int age;public double taille, poids;
}
class Struct1 {
static void Afficher(Personne unePers, string message)
{ Console.WriteLine("Infos de la personne " + message + ":");
Console.WriteLine(" - son age : " + unePers.age + " ans");
Console.WriteLine(" - sa taille: " + unePers.taille + " metre");
Console.WriteLine(" - son poids: " + unePers.poids + " kgs");
Console.WriteLine();
}
static void Main(string[] args) {
Personne pers1;
pers1.age = 25;
pers1.taille = 1.76;
pers1.poids = 65.1;
Afficher(pers1, "pers1");
Personne pers2 = pers1; // une copie de la 1ère pers.
Afficher(pers2, "numero 2");
}
}
/* Exécution :
Infos de la personne pers1:
- son age : 25 ans - sa taille: 1,76 metre - son poids: 65,1 kgs
Infos de la personne numero 2:
- son age : 25 ans - sa taille: 1,76 metre - son poids: 65,1 kgs Press any key to continue
*/
Exemple 2 :
/* Fichier Structure2.cs (2ième exemple) * Ici, on voit une structure avec méthodes */
using System;
struct Point {
// les champs :
public int x;
public int y;
// les méthodes :
public void Obtenir(int abs, int ord) {
x = abs;
y = ord;
}
// distance d'un point à l'origine public double distance()
{
return Math.Sqrt(x*x + y*y);
}
// afficher les coordonnées d'un point avec message public void Afficher(string message)
{
Console.WriteLine("Point {0} :<{1}, {2}, {3}>", message, x, y, distance());
}
}
class Struct2 {
static void Main(string[] args) {
Point A;
A.x = 12; A.y = 10;
A.Afficher("A");
Point B = new Point();
B.Obtenir(4, 3);
B.Afficher("B");
A = B;
A.Afficher("A (apres avoir affecter : A = B;) ");
}
}
/* Exécution :
Point A :<12, 10, 15,6204993518133>
Point B :<4, 3, 5>
Point A (apres avoir affecter : A = B;) :<4, 3, 5>
Press any key to continue
*/
On reviendra sur le type structure après avoir appris la
notion de classe.
C)Quelques nouveautés du C# vs le C
Voici quelques nouveautés vs le C qu’on voit fréquemment en C#, C++ et Java :
1. Commentaire en ligne :
int nbFem; // compteur du nombre de femmes 2. Flexibilité des déclarations :
a) on peut mélanger les déclarations et les instructions au lieu de grouper d’abord les déclarations et écrire après les instructions : int nbFem;
Console.WriteLine(" . . . ");
double taille = 1.72;
etc . . .
b) le style de la boucle for :
for (int i = 0; i < nbPers; i++) . . .
OU
for (int i = 0, nbPers = age.Length; i < nbPers;
i++) . . .
3. Surcharge des méthodes :
Dans un langage de programmation sans orientée objet (Pascal, C, … ), il est interdit d'utiliser le même nom pour deux sous-programmes différents.
Les langages C#, C++, JAVA, … permettent d'utiliser le
même nom pour plusieurs sous-programmes différents
(nombre de paramètres différents ou même nombre de
paramètres avec de types différents). L'importance est
que ces sous-programmes (méthodes en C#) ont de même
but : construire des objets de manières différentes,
afficher des objets différents : une seule nation, un
tableau des pays, un entier avec format, etc.
D) Concept d’encapsulation de la POO
Quant on a parlé de l’objet "tableau" dans notre vie étudiante
,on a parlé de :
- ses champs d’informations (ses attributs) :
quelle couleur, quel matériel, quelle grandeur, . . . - manières différentes pour construire un tableau
- des méthodes, des actions pour appliquer sur un tableau C’est la même chose en programmation orientée objet. Malgré que C# prétend tout objet, en arrière de chaque type, il y a une classe associée. C’est pourquoi on parle ici des objets d’une classe.
La POO est basée sur trois nouveaux concepts :
1. l’encapsulation (fusion de données et de méthodes) 2. l’héritage (tel père => tel fils et plus)
3. le polymorphisme (utilisation de l’information appropriée)
La plupart des langages traditionnels (Pascal, C, . . .) disposent du type structure où on peut déjà grouper des données et les méthodes pour les gérer. L’encapsulation de la POO a deux buts plus importants :
1
erbut : fusionner les données et les méthodes dans une même unité qui s’appelle classe
2
ièmebut : protéger des données avec la clause private, rendre plublic des informations avec la clause public, indiquer des informations de la classe avec la clause static, etc.
Quant on applique la méthode ToUpper() pour convertir une
chaîne de caractères en majuscules, on ne s’intéresse pas
de savoir comment les concepteurs ont programmé cette
méthode mais surtout de savoir quel est son but, comment l’utiliser.
Clause private (privée) : l’accès est limité à l’intérieur du corps de la classe.
- presque tous les champs d’informations d’une classe sont privés
- une méthode est déclarée privée quand elle n’a aucun intérêt aux usagers d’accéder à cette méthode. Elle est utile seulement pour les développeurs de cette classe.
Clause public : l’accès est permis même à l’extérieur du corps de la classe.
- presque toutes les méthodes d’une classe sont publics.
Clause static : pour désigner un champ ou une méthode est une information de la classe dans l’ensemble, pas
l’information de chacun des objets de la classe :
3.5 est le rayon du cercle cercle1 de la classe Cercle, 9.1 est le rayon du cercle cercle2 de la classe Cercle.
Le rayon est alors l’information de chacun des objets de la classe Cercle. Par contre, le nombre total de cercles
construits, par exemple, est une information de la classe Cercle.
Exemple 1 :
Réalisez un programme en C# qui comporte 2 classes : 1. Personne avec les champs privés :
o nomPre (nom et prénom) de type string
o taille de type réel représentant sa taille en mètre
On écrit quelques constructeurs appropriés, des
méthodes permettant de répondre à certains tests (voir l’exécution).
2. TestPersonne permettant de
a. construire (instancier) 3 personnes :
1ère personne : CHARBONNEAU PIERRE qui mesure 1,78 mètre 2ième personne : informations saisies au clavier
3ième personne : TREMBLAY LISE qui mesure 1,68 mètre
b. afficher leurs informations
c. compter et afficher le nombre total de personnes construites par deux manières différentes
d. comparer la taille des deux premières personnes
Veuillez noter que le niveau de cet exemple est pédogogique» afin de
comprendre la notion d’encapsulation.
L’exemple sera expliqué en détails en classe.
/* Fichier POO1.cs
* Premier exemple sur l'ENCAPSULATION
* Explications : mercredi le 21 septembre 2005 * Voir l'exécution
*/
using System;
class Personne {
// champs (field) d'informations private string nomPre;
private double taille;
// exemple "pédagogique" un champ "static"
public static int nbPers = 0;
// méthodes :
// conversion : système impérial en métrique private double EnMetre(int nbPieds, int nbPouces) {
// 1 pied = 0.3048 mètre
const double PIED_EN_METRE = 0.3048;
return (nbPieds + nbPouces / 12.0) * PIED_EN_METRE;
}
// saisir et retourner un réel tapé au clavier private double SaisirReel(string message) {
Console.Write(message);
return double.Parse(Console.ReadLine());
}
// un constructeur
public Personne(string nP, double t) { nomPre = nP;
taille = t;
nbPers++;
}
// un autre constructeur
public Personne(string nP, int nbPieds, int nbPouces) {
nomPre = nP;
taille = EnMetre(nbPieds, nbPouces);
nbPers++;
}
// encore un autre constructeur public Personne()
{
Console.Write("Quel est son nom et prenom ? ");
nomPre = Console.ReadLine();
taille = SaisirReel("Tapez la taille en metre ");
nbPers++;
}
public void Afficher(string message) {
Console.WriteLine("Informations de " + message + " :");
Console.WriteLine(" - nom et prenom : " + nomPre.ToUpper());
Console.WriteLine(" - taille {0, 5:F2} metre" , taille);
Console.WriteLine();
}
// la personne courante est-elle plus grande qu'une autre ? public bool EstPlusGrande(Personne autre)
{
return taille > autre.taille;
}
// exemple "pédagogique" une méthode "static"
public static void AfficherNbPers() {
Console.WriteLine("\nAu total, on a construit " + nbPers + " personne(s)");
Console.WriteLine();
}
}
class TestPersonne {
static void Main(string[] args) {
Personne pers1 = new Personne("Charbonneau Pierre", 1.78), pers2 = new Personne(),
pers3 = new Personne("Tremblay Lise", 5, 6);
pers1.Afficher("pers1");
pers2.Afficher("la deuxieme personne");
pers3.Afficher("personne numero 3");
Console.WriteLine();
Console.WriteLine("On a : " + Personne.nbPers + " personne(s) (par une maniere)");
Console.WriteLine("\nPar une autre maniere :");
Personne.AfficherNbPers();
Console.WriteLine("\nLa premiere est-elle plus grande "+
" que la deuxieme ? {0}\n", pers1.EstPlusGrande(pers2));
} }
/* Exécution:
Quel est son nom et prenom ? Tremblay Nicole Tapez la taille en metre 1,63
Informations de pers1 :
- nom et prenom : CHARBONNEAU PIERRE
- taille 1,78 metre
Informations de la deuxieme personne : - nom et prenom : TREMBLAY NICOLE - taille 1,63 metre
Informations de personne numero 3 : - nom et prenom : TREMBLAY LISE - taille 1,68 metre
On a : 3 personne(s) (par une maniere) Par une autre maniere :
Au total, on a construit 3 personne(s)
La premiere est-elle plus grande que la deuxieme ? True Press any key to continue
*/
Constructeurs :
Une classe peut disposer d’aucune, une ou de plusieurs constructeurs. Le but d’un constructeur est de construire un objet d’une classe en donnant les valeurs aux champs d’information de la classe.
Comme on construit un objet en dehors de sa classe, c’est une méthode public. Un constructeur n’est pas de type void ni return. C’est une méthode qui porte le même nom de la classe. Si la classe ne dispose aucun constructeur, C#
fournit un constructeur sans paramètre avec les valeurs par défaut pour les champs d’informations.
using System;
class Aucun // constructeur { private int x;
private double y;
public void Afficher() {
Console.WriteLine("Dans la classe Aucun (constructeur) " + " x = {0} et y = {1}", x, y);
} }
class Constructeurs {
static void Main(string[] args) {
Aucun obj = new Aucun();
obj.Afficher();
} }
Exécution :
Dans la classe Aucun (constructeur) x = 0 et y = 0 Press any key to continue
Par contre, si une classe dispose déjà de constructeur(s), C# ne fournit plus de constructeur par défaut :
using System;
class Avec // constructeur {
private int x;
private double y;
public Avec(int a, double b) { x = a; y = b;
}
public void Afficher() {
Console.WriteLine("Dans la classe Avec (constructeur) " +
" x = {0} et y = {1}", x, y);
} }
class Constructeurs {
static void Main(string[] args) {
Avec obj = new Avec(5, 6.7);
obj.Afficher();
} }
Exécution :
Dans la classe Avec (constructeur) x = 5 et y = 6,7 Press any key to continue
Tandis que :
obj = new Avec();
provoque l’erreur :