Liens rapides pour usage courant: (Accès à la liste des squelettes) (Polycopié)
objet instanciation surcharge constructeur destructeur inline offline public private protected héritage initialisation virtuel friend polymorphisme sous-typage templates surcharge-opérateurs
Extensions de Synchronous C++: active @corps accept select
SC++ -o out filename.cxx
Ci-dessous sont donnés 4 exemples de squelettes de programmes:
#include <stdio.h> /* programme C simple */
fonct () { }
main ()
{
}
----------------------------------
#include <stdio.h> /* programme C recuperant les parametres*/
#include <stdlib.h>
/* de la ligne de commande */
main (int argc, char **argv)
{
int i;
for (i=0; i<argc; i++)
printf("%s\n", argv[i]);
exit(0); /* utilise stdlib */
}
-------------------------------------------------------------------------------------
#include <scxx.h> // programme sC++ contenant un objet actif
#include <stdio.h>
int setRealTimeMode=SetRealTimeMode(); // initialisation du noyau avant le main
active class ActObj {
public:
void sign() {};
private:
@ActObj() {
printf("Bonjour\n");
select {
accept sign;
||
accept ~ActObj;
}
}
}Obj;
void main() {} // Le main attend que les objets se terminent
// ou acceptent leur destruction
---------------------------------------------------------------------------------------
#include <scxx.h> // programme sC++ qui utilise une
#include <stdio.h> // fenetre simple XTerm dans le main
#include <GUI.h>
#include <XTerm.h>
#include <CharString.h>
main (int argc, char **argv) {
GUI gui (argc, argv);
XTerm xTerm(gui, "Ma fenetre");
CharString sStr;
char str[80];
int i;
xTerm.WriteString("Bonjour, tapez fin de ligne\n");
xTerm.ReadString(sStr);
sscanf(sStr.Buffer(), "%d", &i); // conversion ASCII entier
sprintf(str,"Valeur = %d\n",i);
xTerm.WriteString(str);
waituntil (now() + 100);
}
description des interfaces à fenêtres /
autres exemples avec fenêtres /
fichiers.h
cc -o out filename.c programme C cxx -o out filename.cxx programme C++ SC++ -o out filename.cxx programme sC++ SC++ -o out filename.cxx -lSockets au cas ou l'on utilise les sockets
type nom ( type nom1, type * nom2 , type & nom2 ) {
instructions;
return expr;
}
nom ( type nom1, type * nom2 , type & nom2 ) {
instructions;
return int_expr;
}
void nom ( type nom1, type * nom2 , type & nom2 ) {
instructions;
return;
}
type nom ( nom1, nom2 )
type1 nom1;
type2 * nom2;
{
.... ;
return expr;
}
int nom, * nom;
int nom [ constante ];
int nom = 0;
void ;
char ;
short ;
int ;
long ;
unsigned, unsigned int ;
unsigned short ;
unsigned long ;
float ;
double, long float ;
enum xxx {aa, bb,cc}; // definition de type
enum {aaa,bbb,ccc} yyy; // definition de variable
----------------------------------
struct nom_de_type_optionnel {
} nom_de_variable_optionnel ;
----------------------------------
typedef struct indifferent {
} nom_de_type;
while () ;
----------------------------------
while () {
}
----------------------------------
do {
}
while ();
----------------------------------
for (i=0;i<10;i++) {
}
----------------------------------
for (;;);
----------------------------------
for (;;) {
}
if ()
;
else
;
----------------------------------
if ()
;
else if ()
;
else
;
----------------------------------
if () {
}
else if () {
}
else {
}
switch (VAR) {
case XXX : ;
break;
case YYY : {
break; }
default: ;
}
label: goto label; ---------------------------------- break; ---------------------------------- continue;
Les priorités décroissent de la première ligne à la dernière.
[] () {} . ->
* & - ! ++ -- sizeof( )
* / %
<< >> < <= > >=
== !=
&
!
|
&&
||
condition ? vrai : faux;
= *= /= %= += -= <<= >>= &= ^= |=
,
typedef struct enreg { char a; } enreg ;
enreg *point;
char * ptr, caractere;
char array[10];
array[0] = 'a';
ptr = array;
caractere = * ptr;
point = (enreg*)malloc(sizeof(enreg));
point->a = caractere;
free(point);
Voir aussi les pointeurs sur les classes. En C++ on utilise new et delete pour les classes et les struct.
#include "stdio.h"
scanf("%d%f", &variable1, &variable2);
%d %i %u %f %e %g (==%f ou %e) %c %s %o %x %%
%0d %5.2f %-6d %ld
\n \32 \" \' \t
#include "stdio.h"
printf("texte%dtexte%f\n", variable1, variable2);
class A {
public:
int x;
void f() { }
int g();
};
A obj;
obj.x = 0;
obj.f();
A * ptr; // définition ptr = new A; // instanciation A * ptr1 = new A; // définition et instanciation ptr -> x = 0; // affectation à un champ ptr -> f(); // appel d'une methode
class XXX {
method ( ... ) { ..... }
public:
XXX ( int i ) { .... }
~XXX ( ) { ..... }
};
XXX * Z;
Z = new XXX (19);
delete Z;
class XXX {
method ( ... ) { ..... }
public:
XXX ( int i ) { .... }
~XXX ( ) { ..... }
};
class XXX {
method ( ... );
public:
XXX ( ... );
~XXX ( );
};
XXX::method ( ... ) { ........ }
XXX::XXX ( ... ) { ........ }
XXX::~XXX ( ... ) { .......... }
class D: A, private B, public C {
A ma;
};
class XXX (int) { ... }; // XXX a des parametres d'initialisation
class A: XXX { // pas de parametres possibles ici
XXX a; // ni ici
public:
A ( ... ): XXX(12), a(34); // placer les parametres apres le constructeur
};
class A {
public: int x;
protected: int y;
};
class B : private A {
public: A :: x;
protected: A :: y;
};
class A {
public:
enum colors {blue, red, yellow=100,green};
typedef int tt;
struct B { int m; char c; };
};
void main( ) {
A::tt x; /* types définis dans la classe A */
A::colors c = A::red;
A::B bstruc;
}
class X { int a;
friend void f ( X * ) ; // tout le monde peut définir f() };
void f (X * p) { // dans f() on peut atteindre
p -> a = 0; // les membres de X
};
void main () {
X * ptr = new X; // on peut mettre l'objet en
f (ptr); // paramètre et éviter la
} // forme d'appel d'objet
class B; // annonce de définition future de B
class A {
private: int a;
f ();
friend B; // autorisation en faveur de B
};
class B { // B peut atteindre les membres de A
// des façons suivantes
void g () { A :: a = 0; A :: f (); }
void h (A* p) { p->a = 0; p->f(); }
};
class B;
class A {
private: int a;
friend void B :: f(); // autorisation en faveur de la
}; // fonction B :: f() seulement
class B {
void f () { A::a = 0; } // la définition de f() peut
}; // utiliser les membres de A
class X { public: int x; };
class A: virtual public X { };
class B: virtual public X { };
class C: public A, public B { x=0; };
void main () {
C objectC;
objectC . x = 0;
}
class A {
public:
virtual void f() { ........ } };
class B: public A { }; // non surchargé
B bb;
bb . f();
bb . A :: f ();
class A {
public:
virtual void f() { ........ } };
class C: public A {
public:
void f(); // surchargé
};
C cc;
cc . f(); // accède C::f()
cc . A :: f ();
class A {
public:
virtual void f ( ) { ........ };
};
class B: public A {
public:
void f ( int ); }; // surchargé avec un autre
// type de paramètre
B bb;
bb . f ( i ); // accède B::f()
bb . f ( ); // accède A::f()
template<class T, int N> class Clas { // definition
public:
T arr[N];
T f(T*,int);
Clas(T var);
};
template<class T, int N> // constructeur
Clas<T,N>::Clas(T var) {
for (int i=0;i<N;i++)
arr[i]=var;
}
template<class T, int N> // methode
T Clas::f(T *var, int j) {
T temp;
temp = arr[j];
arr[j] = *var;
return (temp);
}
Clas<int,10> Obj(1); // instanciation
active class XXX {
public:
method ( ... ) { ..... } // methode
XXX ( ) { ..... } // constructeur
~XXX ( ) { ..... } // destructeur
@XXX ( ... ) // corps (programme interne)
{ for (;;) {
accept method;
}
}
};
select {
accept Receive;
||
call O2->Send ( );
||
waituntil (now()+ T1);
||
default;
}
select {
when (FreeStoreAvailable)
accept Receive;
||
when ( ! Empty (B2))
call O2->Send ( );
||
waituntil (now()+ T1);
||
when (TimerActive)
waituntil (TimeoutStart + T1);
||
when (InAHurry)
default;
}
#include <scxx.h> // programme sC++ qui utilise une
#include <stdio.h> // fenetre active dans le programme main
#include <GUI.h>
#include <XTerm.h>
#include <CharString.h>
main (int argc, char *argv[])
{
GUI gui(argc, argv); // manager des fenetres, avant tout objet de fenetrage
XTerm xterm (gui,"HELLO",10,30,100,100);
int i;
CharString msg;
char txt[80];
xterm.WriteString("Type a number:");
xterm.ReadString(msg);
sscanf(msg.Buffer(),"%d", &i);
sprintf(txt,"Number is '%d'",i);
xterm.WriteString(txt);
waituntil(now()+100);
}
La fenêtre ci-dessus est créée par le programme ci-dessous. Elle est composée d'une colonne (RowColumn) qui englobe trois éléments. Notez que (RowColumn) peut aussi créer des lignes, grâce à un paramètre, comme l'indique l'exemple qui suit celui qui est donné ci-dessous. La commande base.Realize provoque l'affichage de la fenêtre. Pour lire ou écrire dans les fenêtres, on utilise les commandes illustrées dans la deuxième partie du programme.
#include <scxx.h> // programme sC++ qui utilise une
#include <stdio.h> // fenetre active dans le programme main
#include <GUI.h>
#include <RowColumn.h>
#include <TextField.h>
#include <PushButton.h>
#include <Text.h>
#include <CharString.h>
main (int argc, char *argv[])
{
GUI gui(argc, argv); // manager des fenetres, avant tout objet de fenetrage
RowColumn base ( gui, "RootWindow" );
Text texte ( base, 4);
TextField ligne ( base );
PushButton quit ( base, "QUITTER" );
base.Realize(); // affiche la fenetre
CharString msg;
ligne.ReadText(msg); // Bloquant: evenement == enter
ligne.GetText(msg); // Non bloquant
texte.ReadText(msg); // Bloquant: evenement == crtl-enter
texte.GetText(msg); // Non bloquant
texte.AppendText(msg); // impression a la fin du texte
texte.AppendText("hello\n");
quit.Pressed();
}
#include <scxx.h>
#include <GUI.h>
#include <RowColumn.h>
#include <TextField.h>
#include <PushButton.h>
#include <Text.h>
#include <CharString.h>
int setRealTimeMode = SetRealTimeMode(); // parce qu'il y a des objets avant main
GUI gui; // parce qu'il y a des objets gui avant main
RowColumn base ( gui, "RootWindow" );
RowColumn groupe ( base, 1, GUIOrientation::HORIZONTAL);
Text texte ( base, 10);
TextField ligne ( base );
PushButton quit ( base, "QUITTER" );
PushButton bouton1 ( groupe, "Bouton1" );
PushButton bouton2 ( groupe, "Bouton2" );
PushButton bouton3 ( groupe, "Bouton3" );
GUIRealizer baseRealizer(base);
active class Obj {
@Obj () { // corps de l'objet (processus)
CharString msg;
for (;;) {
select {
ligne.ReadText(msg); // pret avec enter
||
texte.ReadText(msg); // pret avec crtl-enter
||
quit.Pressed();
accept ~Obj; // accepte sa propre destruction
}
}
}
};
Obj O1;
void main ( ) { }
Autre exemple: interface GUI dans un objet
Dans l'exemple suivant on a placé l'interface GUI dans un objet.
Observer l'initialisation !
#include <scxx.h>
#include <GUI.h>
#include <RowColumn.h>
#include <TextField.h>
#include <PushButton.h>
#include <Text.h>
#include <CharString.h>
int setRealTimeMode = SetRealTimeMode(); // parce qu'il y a des objets avant main
GUI gui; // parce qu'il y a des objets gui avant main
active class Obj {
RowColumn base; // Les membres d'un objet doivent etre initialises
RowColumn groupe; // apres les parametres du constructeur
Text texte;
TextField ligne;
PushButton bouton1;
PushButton quit;
GUIRealizer baseRealizer;
public:
Obj(): base ( gui, "RootWindow" ),
groupe ( base, 1, GUIOrientation::HORIZONTAL),
texte ( base, 10),
ligne ( base ),
quit ( base, "QUITTER" ),
bouton1 ( groupe, "Bouton1" ),
baseRealizer(base) {}
private:
@Obj () { // corps de l'objet (processus)
waituntil (now() + 100);
}
};
Obj O1;
void main ( ) { }
// le programme attend de pouvoir effacer l'objet actif, ce qui n'est
// possible que lorsqu'il accepte explicitement sa destruction.
Création et utilisation d'un socket TCP serveur
explications
#include <TCPSocket.h>
int result;
char msg[100];
// déclaration et initialisation du socket-démon (OK: result=0)
TCPSocketDaemon * sd = new TCPSocketDaemon (result, 5000);
// déclaration socket de données
TCPSocket * ns;
// attente de la génération d'un nouveau socket correspondant
// à un nouveau client
ns = sd -> SocketCreated ();
// émission d'un message sur le socket créé (OK: result=nbre de bytes)
result = ns -> Send (msg, sizeof(msg), 0); (connection fermée: result==0)
// réception d'un message du socket créé (erreur: result<0)
result = ns -> Recv (msg, sizeof(msg), 0);
// ferme un socket
delete ns;
Création et utilisation d'un socket TCP client
explications
#include <TCPSocket.h>
int result;
char msg[100];
// déclaration et initialisation du socket (OK: result=0)
TCPSocket * sd = new TCPSocket (result, "host", 5000);
// émission d'un message sur le socket créé (OK: result=nbre de bytes)
result = sd -> Send (msg, sizeof(msg), 0); (connection fermée: result==0)
// réception d'un message du socket créé (erreur: result<0)
result = sd -> Recv (msg, sizeof(msg), 0);
Création et utilisation d'un socket UDP serveur
Les sockets UDP décrits ci-dessous sont tels qu'il sont définis dans UNIX.
Ils sont suivis de sockets proches de ceux de TCP, en ce sens qu'ils
définissent également un canal.
#include <UDPConn.h>
int result;
char msg[100];
// déclaration et initialisation du socket-démon (OK: result=1)
UDPConnDaemon * sd = new UDPSocketDaemon (&result, 5000);
// déclaration socket de données
UDPConn * ns;
// attente de la génération d'un nouveau socket correspondant
// à un nouveau client
ns = sd -> SocketCreated ();
// émission d'un message sur le socket créé (OK: result=nbre de bytes)
result = ns -> Send (msg, sizeof(msg), 0); (connection fermée: result==0)
// réception d'un message du socket créé (erreur: result<0)
result = ns -> Recv (msg, sizeof(msg), 0);
Les sockets UDP décrits ci-dessous se comportent comme les sockets TCP,
quant à l'ouverture et aux ports, mais ils
envoient des datagrammes non fiables.
Création et utilisation d'un socket UDP client
explications
#include <UDPSocket.h> // connection oriented (il y a aussi un socketTCP pour gérer l'ouverture et la fermeture !)
int result;
char msg[100];
// déclaration et initialisation du socket (OK: result=1)
UDPSocket * sd = new UDPsocket ("host",5000,&result);
// émission d'un message sur le socket créé (OK: result=nbre de bytes)
result = sd -> Send (msg, sizeof(msg), 0); (connection fermée: result==0)
// réception d'un message du socket créé (erreur: result< 0)
result = sd -> Recv (msg, sizeof(msg), 0);
Machine à états finie
explications
Etat1: select {
accept Send;
goto Etat2;
||
call Oa->Connect ( paramx );
goto Etat1;
}
Etat2: select {
. . .
}
Manuel hypertexte de C, C++ et sC++ / EPFL / petitpierre@lti.di.epfl.ch