Chapitre 3: Notre premier programme
Nous y voila, enfin, comme vous l'aurez compris cette fois-ci on s'attaque à la programmation.
Je pensais au départ présenter directement la structure d'une application S60 mais cela necessitait d'aborder beaucoup de connaissances en un seul chapitre.
On va donc, dans ce chapitre, plutot programmer, non pas une application mais un fichier éxécutable.
En S60 un application est défini par pas mal de chose comme l'UID, que l'on a vu au chapitre précédent, mais aussi par un document, un container ...et un tas d'autres "choses" qui rentrent en jeu directement dans le source et que l'on abordera plus tard. Ces fichiers se terminent par un .app
Un éxécutable se termine par un .exe, mais comme ce n'est pas une application, une fois installé sur certains mobiles, il ne sera pas affiché dans le menu. Il devra être lancé via un explorateur de fichiers, du type fexplorer.
De plus ces fichiers ne se lancent pas directement pour les mobiles S60v3, dans ce chapitre donc, on ne programmera que sur S60v2.
Mais alors à quoi ca sert ?Et bien je préfére commencer par un programme qui soit le plus simple et le plus court possible afin de commencer en douceur
J'en profiterais aussi pour rapeller quelques fondements du langage C++ en générale.
PS: Je vous conseille de ne pas utiliser les exemples que l'on donnera dans ce chapitre sur vos téléphones, on va se contenter de programmes simples, épurés de tout controle d'erreur et de gestion de la mémoire, et donc capable de faire bugger votre portable. Les émulateurs sont pour le moment amplement suffisant pour les tests.Je vous conseille également de faire systématiquement un copier-coller des exemples donnés dans carbide afin d'avoir un apercu du code coloré syntaxiquement et donc plus compréhensible.
___________________
Sommaire du chapitre 3 Quelques rappels... Le programme de base Installation du projet HelloFM ! HelloFM optimisé Exercices___________________
Quelques rappels...Je dit des rappels, mais ca peut etre nouveau pour certains (ceux qui n'ont jamais programmé par exemple). Dans ce cas pas de panique, jusqu'ici il n' y a rien de très compliqué. Je n'entrerai pas dans le détail mais on verra des exemples pratiques, qui vous aiderons à mieux comprendre.
Si vous avez du mal avec certaines notions, n'hésitez pas à poser vos questions.
- Les commentaires
Les commentaires permettent d'ajouter des informations dans le code source, des annotations, du texte...
Il existe deux facon de commenter un code source:
- En utilisant le double slash: // (commentaire d'un ligne)
- En utilisant le /* et */ (commentaires sur plusieurs lignes)
Exemples:
//Ceci est un commentaire
/*
Nous allons programmer en C++ sur nos mobiles ?
C'est génial!!
Merci FM!!!
*/
- Les instructions
Les instructions sont des commandes que l'on demande à la machine d'effectuer.
Elle se terminent toujours par un ";"
Exemple:
a = 1 + 2;
- Les variables
Les variables sont des 'objets' dans lesquels on va stoker des informations.
Elles se composent d'un nom et d'une valeur.
Exemples:
var = 1 + 2; //La variable de nom "var" prendra la valeur 3 à la suite de cette instruction
uneAutreVariable = 4;
var = var - 1; //Et ici var sera égale à 2
uneAutreVariable = 5 * var; //uneAutreVariable prend la valeur 10
- Les types de variables
Chaque variable, avant utilisation doivent etre declarée et dans la déclaration, il va falloir indiqué son type.
En clair a chaque fois que vous voudrez utiliser une variable, il va falloir dire à la machine si votre variable va contenir un entier, un nombre décimal, une chaine de caractere,...
Des exemples de types et de déclaration de variables:
int var; //int correspond aux entiers
float varVirgule; //float désigne les nombres décimaux
//on peut aussi déclarer plusieurs variables à la fois en les séparant par un virgule
int var, uneAutreVariable;
Si vous utilisez une variable sans la déclarer ou si vous cherchez à stocker une information qui ne correspond pas au type de la variable, vous provoquerez alors une erreur lors de compilation.
PS: Symbian possède des types de variables qui lui sont propre. Par exemple pour déclarer un entier il faudra utiliser TInt, TInt32... on verra les différents types propres à symbian dans un autre chapitre.
- Les fonctions
Les fonctions sont une série d'instructions. A chaque appel de celle-ci, elle execute les instructions qu'elle contient.
Une fonction se présente de cette facon
Type_a_renvoyer nomDeLaFonction(type_parametres parametres)
{
//Les instructions à executer
...
return(uneVariable); //Facultatif, c'est l'instruction qui permet renvoyer une valeur.
/*Si la fonction ne retourne aucune valeur, il faut retirer cette instruction et indiquer void dans le Type_a_renvoyer*/
}
Exemple:
//Fonction qui additionne deux nombres donnés
/* La fonction de nom "Aditionne" à pour parametres deux réels (que l'on nommé ici a et b)
et renvoi un entier */
int Aditionne(int a, int b)
{
int somme; //On déclare la variable somme qui est un entier
// a et b sont dèjà déclarés dans l'entête de la fonction
somme = a + b; //on additionne a et b, le résultat est mis dans la variable somme
return(somme); //la valeur de la variable somme est renvoyée
}
Pour appeler la fonction il suffit de faire par exemple:
resultat = Aditionne(4,7); // la variable resultat prend alors la valeur 11
- Les includes
Les includes permettent d'inclure dans le code source, des fichiers (appelés header, ayant l'extension .h). Ces fichiers contiennent, en général, des fonctions que l'on pourra utiliser dans notre programme.
Notation:
#include <nomDuHeader.h>
Le header de base sur symbian s'appelle e32base.h. Ils contient toutes les fonctions de base propre au symbian:
#include <e32base.h> //header qui contient les fonctions de base sous symbian
- Les structures conditionnelles
Les structures conditionnelles permettent d'éxécuter certaines instructions selon des conditions que l'ont aura définies. - La plus simple if... then ....else (trad: si...alors...sinon)
Structure:
if(condition)
{
bloc d'instructions à éxécuter si condition
est vraie
}
else
{
bloc d'instructions à éxécuter si condition
est faux
}
Voilà par exemple, une fonction qui modifie une variable en sa valeur absolue:
if( a < 0) //Si a est inférieur à 0...
{
a = -a; //Il stocke l'opposé de a dans a
}
PS : Le else n'est pas obligatoire. - Le switch
Il permet de travailler aux cas par cas:
Exemple:
String niveau;
int nbre_mobiles;
//String est le type d'une chaine de caractères
//Les chaines de caractères sont délimitées par des guillemets
nbres_mobiles = 3;
//La vous mettez le nombre de vos mobiles
switch (nbre_mobiles)
{
case 0:
niveau = "T naze!";
break;
case 1:
niveau = "Salut, j'débarque :-)";
break;
case 2:
niveau = "Motivé";
break;
case 3:
niveau = "Apprenti";
break;
case 4:
niveau = "Initié";
break;
case 5:
niveau = "GSMophile";
break;
default:
niveau = "Bac +6 mobilophonie";
break;
}
Vous l'aurez compris, si le nombre de mobiles est égal à 5 par exemple, la variable niveau prendra la valeur "GSMophile"
Les instructions de la condition default sont exécutées lorsque la variable mis en parametre ne correspond à aucun des cas (par exemple pour nbres_mobiles=73)
PS: N'oubliez pas aussi l'instruction break; à la fin de chaque cas. - Do...While (Faire...TantQue)
Un exemple pour bien comprendre:
int a;
a = 1;
do
{
a = a +1;
} while (a <= 20);
Le programme va éxécuter l'instruction a = a + 1; tant que a <= 20.
Attention à ce type de structure (que l'on appelle des boucles): En effet, si l'on met par exemple (a > 1) en condition, le programme ne s'arretera jamais!
a sera égale à 1 puis 2 puis 3, 4, 5..... il ne s'arretera pas car a sera toujours supérieur à 1...
Voilà pour les rappels, on va s'arreter là. Il y a encore un tas d'autres choses à voir, mais cela est suffisant pour attaquer la suite.
J'ai été très bref donc n'hésitez pas à poser vos questions, à faire des tests, et consulter d'autres tutos destinés spécifiquement au C++.
___________________
Le programme de baseVoilà, je vous présente le programme le plus court et le plus simple sur S60
//Le programme de base en C++ pour symbian
#include <e32base.h>
TInt E32Main()
{
return(0);
}
On va maintenant le décortiqué ligne par ligne:
- #include <e32base.h>
Ca c'est l'include qui contient les fonctions de base de symbian.
- TInt E32Main()
Là c'est la fonction E32Main()
C'est la premiere fonction qui sera lancée lors de l'éxécution de votre programme
C'est en quelque sorte le point de départ de votre programme (équivaut à int main(int argc, char *argv[]) en C++ classique)
PS: TInt est un type de variable spécifique à symbian qui équivaut à int en C++ classique
- return(0);
La fonction E32main() doit renvoyer un TInt, donc ici par défaut 0.
Le fait que la fonction retourne un nombre peut etre utile pour la gestion des erreurs, on verra ça aussi dans d'autres chapitres.
___________________
Installation du projetAvant de continuer il va falloir installer le programme que l'on vient de voir sur votre PC, afin de pouvoir travailler dessus.
- Telecharger ce fichier HelloFM.zip et décrompesser le.
- Vous devez alors avoir cà dans votre dossier HelloFM:
- Lancez carbide et allez dans file -> import -> Existing projects into workspace -> next
->
- Puis dans browse et selectionnez le dossier que vous venez de décompresser puis ok -> finish
- Vous avez maintenant ca dans votre onglet projets.
- Dans l'onglet des projets, allez dans le dossier HelloFM puis src puis cliquez deux fois sur le fichier HelloFM.cpp pour afficher le code
PS: Au fait je vous l'avais pas dit mais les fichiers sources en C++ ont une extension .cpp
- Le code source apparait:
Maintenant essayer de le compiler et de l'éxécuter sur l'émulateur... (cf chap 2)
Ca y est ? Alors ?
Il ne c'est rien passé! L'émulateur s'est lancé puis fermé aussitot !!! C'est normal... mais je suppose que vous en doutiez...
Effectivement la fonction E32Main() se lance, retourne(0) et s'arrete...
Maintenant on va donc essayer de faire faire quelque chose de plus concret à notre programme.
___________________
HelloFM !Le premier programme de tous programmeurs s'appelle Hello World, rebaptisé ici Hello FM
(he samir, t'es pas un peu communautariste la ?)Le but de ce programme est très simple: Afficher à l'écran le texte "Hello FM" !
Et pour l'affichage on va utiliser une console!
Cool, une console comme la Playstation ou la XBOX 360 ? Non, pas du tout...
... une console, qu'est ce que c'est alors ? Pour faire simple on va dire que c'est un écran sur lequel on peut afficher que du texte (donc sans fenetre, icones...), comme l'invite de commandes de windows XP par exemple, ou le texte qui défile lorsque vous allumer votre PC.
- Tout d'abord il faut inclure la blibliotheque qui contient toutes les fonctions liés à la console: la voici, elle s'appelle e32cons.h
Si vous avez compris le fonctionnement des headers, vous avez donc certainement compris que le programme allait commencer de cette facon:
#include <e32base.h>
#include <e32cons.h>
Voila pour les headers...
- Maintenant les déclarations:
Dans cette premiere ébauche de notre programme, on va utiliser une console qu'il faudra créer donc nommer et déclarer.
Le type d'une console, c'est CConsoleBase, et on va la nommer ... consoleFM ! (pourquoi le FM apres console ? samir, là ca devient de l'extremisme)
Notre programme ressemble donc à ca:
#include <e32base.h>
#include <e32cons.h>
CConsoleBase* consoleFM;
Pourquoi il y a une étoile sur le type, pour la console ?
On verra ca dans d'autres chapitres... c'est une histoire de pointeurs et d'adressage en mémoire et c'est une longue histoire...
- Maintenant on ajoute la fonction E32Main():
#include <e32base.h>
#include <e32cons.h>
CConsoleBase* consoleFM;
TInt E32Main()
{
return(0);
}
- On s'attaque ensuite à l'intérieur de la fonction main:
Au sujet de la console (commme d'autres objets), une fois déclarée, il va falloir la créer.
La création d'une console se fait via cette instruction:
nomDeLaConsole=Console::NewL(_L("Le titre de la console"),TSize(largeur de la console,longueur de la console));
Ce qui dans notre cas donne ca:
consoleFM=Console::NewL(_L("Console FM"),TSize(KConsFullScreen,KConsFullScreen));
Quelques explications:- Pour les "::", la fonction "_L" et "NewL", on verra ca aussi d'autres chapitres. Retené juste la structure générale de cette instruction.
- KConsFullScreen sont des constantes qui renvoient la taille de l'écran. Le paramètre TSize(KConsFullScreen,KConsFullScreen) permet donc de créer une console qui prendra toute la taille de l'écran.
Le code source ressemble maintenant à ca:
#include <e32base.h>
#include <e32cons.h>
CConsoleBase* consoleFM;
TInt E32Main()
{
consoleFM=Console::NewL(_L("Console FM"),TSize(KConsFullScreen,KConsFullScreen));
return(0);
}
- La console à été déclarée, puis créée, elle possède désormais un tas de fonctions et de propriétés. On y fait appel grace à ce symbole "->".
Par exemple la fonction ClearScreen qui permet d'effacer le contenu de l'écran se lance de cette facon:
consoleFM->ClearScreen(); //Efface l'écran de la console nommé consoleFM
Voici quelques autres fonctions et propriétés d'une console:- Printf(_L("Du texte à afficher")): Affiche un texte
- WhereX(): renvoi la position en abscisse du curseur
- WhereY(): renvoi la postion en ordonnee du curseur
- ClearToEndOfLine(): efface la ligne à partir de la position du curseur
- Getch(): Stoppe l'éxécution du programme et attend qu'une touche soit tapée. Le code de la touche est alors renvoyé.
- etc...
- On peut donc maintenant afficher notre fameux "Hello FM"
On va donc utiliser la fonction Printf. Cela donne:
#include <e32base.h>
#include <e32cons.h>
CConsoleBase* consoleFM;
TInt E32Main()
{
consoleFM=Console::NewL(_L("Console FM"),TSize(KConsFullScreen,KConsFullScreen));
consoleFM->Printf(_L("Hello FM!"));
return(0);
}
- Tentez de compiler et d'éxécuter, résultat: Rien ? comme tout a l'heure.
Pas de panique c'est normal aussi... (samir, tu es sur que tu ne te moques pas de nous là ??)
Mais non, le programme a bien lancé la console et écrit "Hello FM", puis s'est terminé... mais cela à été tellement vite que l'on a rien vu.
Pour résoudre ce problème on va utiliser la fonction getch() que l'on a vu plus haut, qui permet de stopper l'execution du programme jusqu'à ce qu'une touche soit tapée par l'utilisateur.
Et voilà le nouveau code (que j'ai commmenté afin de faire un bilan):
#include <e32base.h> //On inclut le header de base
#include <e32cons.h> //puis le header qui contient les fonctions liées à la console
CConsoleBase* consoleFM; //On déclare une variable de nom consoleFM et de type CConsoleBase
TInt E32Main() //La fonction principale
{
consoleFM=Console::NewL(_L("Console FM"),TSize(KConsFullScreen,KConsFullScreen)); //On créé la console
consoleFM->Printf(_L("Hello FM!")); //On y affiche le texte Hello FM!
consoleFM->Getch(); //On stoppe le programme jusqu'à la pression d'une touche
return(0); //C'est la fin de la fonction principale, on retourne 0.
}
- Maintenant compiler et éxécuter ce code source: Ca y est on obtient enfin ca:
Votre premier programme Hello FM est enfin terminé !!
___________________
HelloFM optimiséMaintenant on va s'interesser à quelques optimisations que l'on peut apporter et s'interesser à quelques fonctions....
- La fonction delete
La fonction delete permet de supprimer un objet créé. Dans notre exemple on a crée une console nommée ConsoleFM, il est péférable, lorsque celle ci n'est plus utilisée de la supprimer.
L'instruction pour supprimer un objet créé est:
delete consoleFM;
Cette instruction permet, entre autres, de libérer de la mémoire et l'on verra dans le prochain chapitre l'importance que la gestion de la mémoire sous symbian.
Il faut garder à l'esprit que nous travaillons sur des mobiles et que les ressources sont par consequent très limitées.
Sous symbian, la fonction delete n'est pas suffisante, et il faudra faire appel à d'autres méthodes de gestion de la mémoire. Ca sera le sujet du prochain chapitre.
- Le retour à la ligne
On va commencer par ajouter une ligne de texte sur notre console afin d'y indiquer à l'utilisateur qui faut appuyer sur une touche pour continuer.
Logiquement le résultat devrait ressembler à ca:
#include <e32base.h>
#include <e32cons.h>
CConsoleBase* consoleFM;
TInt E32Main()
{
consoleFM=Console::NewL(_L("Console FM"),TSize(KConsFullScreen,KConsFullScreen));
consoleFM->Printf(_L("Hello FM!"));
consoleFM->Printf(_L("Appuyer sur une touche..."));
consoleFM->Getch();
delete consoleFM;
return(0);
}
Mais lorsque l'on lance le programme ca donne ca:
Vous l'avez compris il manque un retour à la ligne....
En C++ le retour à la ligne se caractérise par \n
On va donc remplacer l'instruction:
consoleFM->Printf(_L("Hello FM!"));
par
consoleFM->Printf(_L("Hello FM!\n"));
On peut aussi ajouter un retour à la ligne à l'intérieur d'un texte:
consoleFM->Printf(_L("Appuyer sur une touche\npour continuer..."));
- La fonction Getch()
Getch(), comme on l'a vu tout l'heure permet de stopper le programme jusqu'à l'action d'une touche, mais il est capable aussi de renvoyer la touche tapée.
Le type renvoyé par Getch est un TKeyCode, chaque touche ayant son propre code.
En voici quelques-uns: - gauche = 63495
- droite = 63496
- haut = 63497
- bas = 63498
- ok = 63557
- Touche vert (dial) = 63586
- Touche rouge = 63587
- Touche 0 = 48
- Touche 1 = 49
- Touche 2 = 50
- ...
- Touche 9 = 57
Avec ca on peut faire un petit programme du style:
Compter le nombre de OK, par exemple, appuyé par l'utilisateur (ca sert à rien je sais...mais je suis un peu en manque d'imagination)
Ca permettra ainsi de mettre en pratique les rappels vus plus haut.
L'idée est donc de prendre une variable et de l'incrementer d'une valeur à chaque appui sur OK. Si c'est une autre touche, le programme s'arrete.
L'idèal est donc ici l'utilisation de la structure conditionnelle while (vu plus haut dans les rappels)
L'ossature du programme:
On fait
{
Afficher ce nombre
Attendre qu'une touche soit selectionnée
Le nombre d'occurence de OK augmente de 1
}tantque(la derniere touche tapée n'est pas égale à OK)
Si une autre touche est selectionnée, on sort de la boucle while, on arrive alors ici, à la fin du programme.
Concrétement ca donne ca:
//Programme qui compte le nombre de OK tapé
#include <E32base.h> //On inclut le header de base
#include <E32cons.h>
//Les déclarations
CConsoleBase* consoleFM; //La console
TKeyCode uneTouche; //La variable qui contenir le code de la touche
TInt nbreOK; //La variable entière qui contient le nombre de OK
//La fonction principale
TInt E32Main()
{
consoleFM=Console::NewL(_L("Console FM"),TSize(KConsFullScreen,KConsFullScreen)); //La création de la console
consoleFM->Printf(_L("\tHello FM!\n")); //Le \t correspond à la tabulation (afin de centrer le texte)
nbreOK = 0; //On initialise le nombre de OK à 0
do
{
consoleFM->SetPos(0); //On positionne le curseur en début de ligne
consoleFM->ClearToEndOfLine(); //On efface la ligne
consoleFM->Printf(_L("Nombre de OK:%d") , nbreOK); //On affiche le nombre de OK
uneTouche = consoleFM->Getch(); //On récupere le code de la touche que l'on stocke
nbreOK = nbreOK + 1; //On incremente la variable nbreOK
}
while(uneTouche == 63557);
//Tant que la touche est OK n'est pas tapé on recommence (63557 est le TKeyCode de la touche OK)
delete consoleFM; //On supprime la console
return(0); //C'est fini
}
PS: On aurait pu remplacer
nbreOK = nbreOK + 1;
par
nbreOK += 1;
Ces 2 instructions sont équivalentes.
___________________
ExercicesEt bien oui! Tout cours se termine par des exos:
Je vous en propose 3, à des niveaux différents:
- Débutant: Afficher un série de messages, suite à la pression d'une touche
Exemples (désolé pour la médiocrité des exemples... ):
-> ->
Donc rien de compliqué, pas de structures conditionnelles, juste la console à créer et l'utilisation des fonctions getch + printf - Intermédiaire: Ecrire un programme qui pose une question puis demande de repondre par 1 ou 2. Puis affiche un message selon la réponse donnée.
Exemple:
-> - Expert: Faire un menu permettant de lancer des sous-programmes
La navigation se fera à l'aide d'un curseur ">>", et la navigation à l'aide des touches "haut" "bas" et "ok".
Ici dans mon exemple des sous-programmes permettant de compter le nombre de ok (vu plus haut) ou un programme (plus interesant) permettant d'afficher les code des touches tapés.
Les corrections des exercices seront données la semaine prochaine.
Ceux qui n'auront pas fait leurs exercices auront un MP dans leur carnet de correspondance, en cas de récidive vous serez convoqués dans le bureau de Mr Les Admins.
___________________
Voilà ce chapitre à enfin atteint ca fin. Il y a certainement beaucoup de notions nouvelles pour certains, dans ce cas n'hésitez pas à poser des questions.
Prochain chapitre: On verra en détail les spécifités de symbian en ce qui concerne la gestion de la mémoire.
Comme je l'ai dit plus haut, nous travaillons sur des mobiles, de ce fait la mémoire doit être gérer d'une façon autre qu'en C++ classique.
Et nous verrons aussi tout ce qui découle de cette gestion particulière de la mémoire (gestions des erreurs, types de variables, nomenclature des variables...)
Pour le chapitre 5, rebelote: "HelloFM 2", mais cette fois ci ca sera une vraie application avec une véritable interface graphique S60 ! (plus jolie que la console bleue et jaune de symbian
).
@+
[sa]Quelques erreurs corrigées[/sa]
[Edité par Anakronik : Combinage du chapitre 3 afin qu'il se retrouve a la suite ]
Modifié par samir, 01 Jan 2007 - 14:12.