ordi_fil.gif (5517 octets)

Index

ordi_gar.gif (7546 octets)

pinjaune.gif (976 octets)Comment fonctionner avec Visual C++ pinjaune.gif (976 octets)Exemple d'un programme
pinjaune.gif (976 octets)Extensions de fichiers pinjaune.gif (976 octets)Description d'un projet
pinjaune.gif (976 octets)Entête d'un programme C++ pinjaune.gif (976 octets)Description d'une librairie
pinjaune.gif (976 octets)Entête d'une fonction C++ pinjaune.gif (976 octets)Que mettre dans un fichier .h ou .hpp ?
pinjaune.gif (976 octets)Commentaires pinjaune.gif (976 octets)Utiliser l'aide en ligne de Visual C++

 

Comment fonctionner avec Visual C++

Vous devez créer vos projets sur le disque C:. En effet, Visual C++ génère de nombreux et volumineux fichiers lorsqu'il travaille. Un programme élémentaire peut facilement remplir une disquette lorsqu'il est compilé. Nous vous suggérons de toujours travailler sur disque dur (C:). Une fois votre travail terminé ou lorsqu'il vous faut partir, ne copier que les fichiers qui portent les extensions suivantes :

  1. Les fichiers d'entêtes (.h et .hpp)
  2. Les fichiers sources (.c et .cpp)
  3. Le fichier de l'espace de travail (.dsw et .opt)
  4. Le fichier du projet (.dsp)

Nous vous suggérons également de conserver le nom du dossier dans lequel votre projet est créé. Par exemple, si nous avons créé un projet nommé MachineÀLaver, un fichier d'entête Laveuse.h et des fichiers sources Trempage.c, Lavage.c, Rinçage.c et Séchage.c. Après compilation du projet (si tout est correct), nous devrions avoir la hiérarchie suivante :

Vous n'avez qu'à conserver ce qui suit sur votre disquette :

NOTE: Vous pouvez changer le nom du répertoire. Par exemple, pour conserver des versions consécutives du programme de machine à laver, je conserverai sur disquette :

Dans chacun de ces répertoires, je conserverai les versions du 8, du 11 et du 20 septembre respectivement. Je conserverai ma version à remettre dans le dernier répertoire.

Retour à l'index


Extension des fichiers

L'extension du fichier doit être représentative. De par les limitations du MS-DOS, la convention est de la limiter à trois caractères. Vous devriez choisir les extensions suivantes :

Document PDf nom_fichier.pdf
Document Word nom_fichier.doc
Entête C nom_fichier.h
Entête C++ nom_fichier.hpp
Exécutable nom_fichier.exe
Exécutable Java nom_fichier.class
Fichier texte nom_fichier.txt
Programme C nom_fichier.c
Programme C++ nom_fichier.cpp
Programme Java nom_fichier.java

Retour à l'index


Entête d'un programme C++

L'entête d'un programme permet de connaître ce qu'il y a dans le programme, qui l'a programmé et quand il a été fait. Il n'est pas nécessaire de s'éterniser dans les commentaires, le style télégraphique faisant l'affaire. Vous avez un exemple d'entête qui suit :

//////////////////////////////////////////////////////////////////////////
// Nom:              exemple.cpp
// Description:     Démontre l'entête d'un programme
// Programmeur:     Pierre-Martin Tardif, professeur
// Création:        8 septembre 1998
// Modifications:   PMT - premiere version
// Notes:           Aucune remarque particulière
//////////////////////////////////////////////////////////////////////////

À la suite de l'entête, nous avons les parties qui suivent :

  1. Déclaration du fichier d'inclusion spécifique (même nom, changer l'extension)
  2. Déclaration des fichiers d'inclusion
  3. Déclaration des variables globales

Ainsi, nous aurions le code qui suit :

////////////////////// INCLUSIONS   /////////////////////////////////////
#include "exemple.cpp"            // Inclusion spécifique à exemple.cpp
#include <iostream.h>             // Classes d'entrée/sortie
#include <new.h>                  // Fonctions pour la gestion de la mémoire
int iExempleGlobale;
char cExempleGlobale;

Pour ce qui est des noms de variable, je vous suggère de commencer vos nom de variables par une(des) lettre(s) minuscule(s) indiquant le type de la variable. Ainsi, nous avons les combinaisons suivantes :

Par la suite, vous utilisez une combinaison de nom(s), adjectif(s) et verbe(s) qui décrivent le plus succinctement possible votre variable. Chaque mot commence par une majuscule et continue par des minuscules. Par exemple, nous aurions :

Retour à l'index


Entête d'une fonction

L'entête d'une fonction permet de connaître ce qu'il y a dans la fonction, qui l'a programmée et quand elle a été complétée. Il n'est pas nécessaire de s'éterniser dans les commentaires, le style télégraphique faisant l'affaire. Vous avez un exemple d'entête qui suit :

//////////////////////////////////////////////////////////////////////////
// Méthode:         AfficheNombre()
// Description:     Affiche le nombre calculé
// Programmeur:     Pierre-Martin Tardif, professeur
// Création:        8 septembre 1998
// Modifications:   PMT - premiere version
// Paramètres:      aucun paramètre
// Membres:         aucun membre (ou variable globale)
// Retourne:        le nombre calculé sous une valeur entière
//////////////////////////////////////////////////////////////////////////

Retour à l'index


Les commentaires dans un programme

Les commentaire servent à décrire soit un fichier (entête de fichier), une fonction (entête de fonction), un bloc de programme ou une seule instruction. Il est important que les commentaires soient significatifs. Il est encore plus important de mettre assez de commentaires pour qu'une autre personne puisse comprendre le déroulement d'un programme, d'une fonction, d'un bloc de programme ou d'une instruction. De plus, il est utile de commenter tout endroit important dans un programme.

 

Retour à l'index


Exemple d'un programme

En utilisant les conventions qui précèdent, nous aurions le programme qui suit :

//////////////////////////////////////////////////////////////////////////
// Nom:              exemple.cpp
// Description:     Démonstration d'un programme (lecture d'une image TIFF)
// Programmeur:     Pierre-Martin Tardif, professeur
// Création:        8 septembre 1998
// Modifications:   PMT - premiere version
// Notes:           Aucune remarque particulière
//////////////////////////////////////////////////////////////////////////

////////////////////// INCLUSIONS  /////////////////////////////////////
#include "exemple.cpp"            // Inclusion spécifique à exemple.cpp
#include <iostream.h>             // Classes d'entrée/sortie
#include <tiff.h>                 // Librairie de lecture/écriture du format TIFF

//////////////////////////////////////////////////////////////////////////
// Methode:         doLoadTIFF()
// Description:     Lit un fichier de format TIFF en utilisant libtiff.dll
// Programmeur:     Pierre-Martin Tardif, professeur
// Creation:        12 septembre 1997
// Modifications:   PMT - deuxième version
// Parametres:      Nom du fichier
// Membres:         aucuns
// Retourne:        rien
//////////////////////////////////////////////////////////////////////////
void doLoadTIFF(char *pcFileName) {
    TIFF* tTiffFile = TIFFOpen(pcFileName, "r");
    if (tTiffFile != NULL) {
        int iWidth, iHeight;
        size_t tTotalPixels;
        uint32* puiData;
        TIFFGetField(tTiffFile, TIFFTAG_IMAGEWIDTH, &iWidth);
        TIFFGetField(tTiffFile, TIFFTAG_IMAGELENGTH, &iHeight);
        sHeight = (short) iHeight;   // Hauteur de l'image lue
        sWidth  = (short) iWidth;     // Largeur de l'image lue (commentaire d'instruction)
        oData[R_INDEX] = Image(sHeight, sWidth);   // Initialise l'image rouge
        oData[G_INDEX] = Image(sHeight, sWidth);   // Initialise l'image verte
        oData[B_INDEX] = Image(sHeight, sWidth);   // Initialise l'image bleue
        tTotalPixels = iWidth * iHeight;   // Dimension totale de l'image

// La ligne qui suit alloue de la mémoire, il ne faut pas oublier de la libérer (zone importante)
        puiData = (uint32*) _TIFFmalloc(tTotalPixels * sizeof (uint32));  // Alloue la mémoire
        if (puiData != NULL) {
            if (TIFFReadRGBAImage(tTiffFile, iWidth, iHeight, puiData, 0)) {   // Lit l'image sur disque

// Convertit l'image lue du format TIFF à la représentation interne choisie (commentaire de bloc)
                for (register short sLine = 0; sLine < sHeight; ++sLine) {
                    for (register short sCol = 0; sCol < sWidth; ++sCol) {
                        register uint32 uiData = puiData[(int)sLine * (int)sWidth + (int)sCol];
                        oData[R_INDEX].setValue((float) TIFFGetR(uiData), sHeight-sLine-1, sCol);
                        oData[G_INDEX].setValue((float) TIFFGetG(uiData), sHeight-sLine-1, sCol);
                        oData[B_INDEX].setValue((float) TIFFGetB(uiData), sHeight-sLine-1, sCol);
                    }
                }
            } else {  // Erreur lors de la lecture
                _TIFFfree(puiData);
            }  // if (TIFFRead...
            _TIFFfree(puiData);
        }      // if (puiData...
        TIFFClose(tTiffFile);
    }          // if (tTiff...
    return;
}

//////////////////////////////////////////////////////////////////////////
// Méthode:         main()
// Description:     Fonction principale, qui est exécutée en premier
// Programmeur:     Pierre-Martin Tardif, professeur
// Création:        8 septembre 1998
// Modifications:   PMT - premiere version
// Paramètres:      arguments standards
// Membres:         aucun membre (ou variable globale)
// Retourne:        toujours zéro (0), indiquant que tout s'est bien passé
//////////////////////////////////////////////////////////////////////////
int main(int argc, char **argv) {
    doLoadTIFF("essai.jpg");    // Lit l'image
    return 0;
}

Retour à l'index


 

Description d'un projet

Le projet sert à mettre ensemble un ou des fichiers pour produire un exécutable ou une librairie. Pour créer un projet, il suffit de choisir le menu File->New et l'onglet Projects. Dès lors, vous avez la fenêtre suivante :

Fenêtre d'un projet (VC++ 6.0)

Les différentes options disponibles (ATL COM AppWizard,  Cluster Resource Type Wizard, etc.) correspondent aux différentes applications que vous pouvez créer. Pour créer une application utilisant les fonctions d'entrée-sortie standard du langage C/C++, vous devez absolument choisir l'option Win32 Console Application. Les options Win32 Application et MFC AppWizard (exe) permettent de créer des interfaces graphiques. Les options Win32 Static Library, Win32 Dynamic-Link Library et MFC AppWizard (dll) permettent de créer des librairies. Finalement, la plupart des autres options permettent de créer des programmes Windows ayant une tâche spécifique.

Une fois que vous avez entré votre nom de projet et son emplacement, le bouton OK devient disponible. Dès que vous le cliquez, vous créez votre projet qui se situe dans un espace de travail (workspace). Vous pouvez ajouter des fichiers à votre projet en utilisant File->New, Projet->Add to Project et en cliquant sur le bouton droit de la souris dans la fenêtre de l'espace de travail :

Fenêtre de l'espace de travail par défaut (VC++ 6.0)

Vous pouvez changer les options de votre projet en utilisant Project->Setting ou Alt+F7. Alors la fenêtre des options apparaîtra :

Fenêtre des options (VC++ 6.0)

Les options les plus importantes sont situées dans C/C++ et Link. Vous remarquez que les options de la fenêtre précédente sont pour "Win32 Release". En effet, il existe toujours deux versions d'un projet lors de sa création sous Visual C++. Il y a la version "Win32 Debug" et la version "Win32 Release".

La différence entre ces deux versions est surtout au niveau du déverminage et de l'optimisation. La version "Debug" sert principalement à trouver les problèmes lors de l'exécution d'un programme. La version "Release" ne contient pas les options de déverminage. Elle est plus compacte et plus rapide. C'est habituellement cette version que l'on transmet à notre client ou que l'on utilise tous les jours. Pour passer de la compilation d'une version à l'autre, il faut choisir Build->Set Active Configuration.... Vous remarquerez que les fichiers compilés se trouvent dans les sous-répertoires Debug et Release selon la version que l'on a choisi.

Finalement, il est possible d'avoir plusieurs projets dans un même espace de travail. Par exemple, lorsque vous démarrez Visual C++, essayez File->New. Par la suite, sélectionnez l'onglet Workspaces. Dans le champ Workspace name, entrez test et cliquez OK. Vous êtes maintenant dans un espace de travail sans projet. Il faut maintenant créer un premier projet en choisissant File->New puis l'onglet Projects. Choisissez l'option Win32 Console Application et entrez projet1 comme premier projet. Maintenant, n'oubliez surtout pas de choisir l'option Add to current workspace et cliquez OK. Pour ajouter un second projet, choisissez  File->New puis l'onglet Projects. Choisissez encore une fois l'option Win32 Console Application et entrez projet2 comme second projet. Maintenant, vérifiez si l'option Add to current workspace est déjà sélectionnée et cliquez OK. Regardez la fenêtre de l'espace de travail qui devrait ressembler à ceci :

Fenêtre de l'espace de travail pour 2 projets (VC++ 6.0)

Présentement, c'est le projet2 qui est sélectionné. Pour avoir projet1 sélectionné, il suffit de choisir Project->Set Active Projet->projet1.

En résumé, pour vos travaux demandant plusieurs exercices, vous pourriez utiliser un seul espace de travail contenant tous les projets que vous avez à faire.

 

Retour à l'index


 

Description d'une librairie

Une librairie est simplement un ensemble de fonctions rassemblées dans un même fichier. Par exemple, dans le langage C, il y a les fonctions printf(), scanf(), sin(), cos(), strlen(), strcpy(), etc. Ces fonctions ne font pas partie des mots clés (ou mots réservés) du langage C. Cependant, elles sont disponibles sur la majorité des compilateurs C, car elles font parties de la librairie standard du langage C (crt.dll ou libc.lib sous Windows).

Pour pouvoir compiler ces fonctions dans votre programme, il faut inclure les fichiers d'entêtes où elles sont déclarées. Ainsi, le compilateur saura si les paramètres que vous donnez à ces fonctions sont valides. Pour utiliser strlen(), il faut include string.h. Pour utiliser sin(), il faut inclure math.h. Ces inclusions se font de la façon suivante :

#include <string.h>

#include <math.h>

Après la compilation, c'est l'étape de l'édition des liens. L'édition des liens consiste à prendre tous les fichiers compilés de votre projet et de les lier avec les librairies. Si une des fonctions que vous avez utilisée dans votre programme n'existe ni dans vos fichiers de votre projet, ni dans les librairies standards, il y aura un erreur de l'éditeur de liens (error LNK2001: unresolved external symbol). Si tout va bien, l'éditeur créera votre exécutable (.exe) ou votre librairie (.lib, .dll) selon la définition de votre projet.

Finalement, nous allons faire la distinction entre l'édition de liens statique et dynamique. L'édition de liens statique permet de créer des exécutables autonomes. Cependant, la taille de ces fichiers sera assez élevée. De plus, si l'une des librairie utilisée est mise à jour, il faut recompiler l'exécutable pour utiliser la mise à jour. Finalement, l'édition des liens n'a lieu qu'une fois, après la compilation du programme. Lorsque le programme est chargé en mémoire, aucune édition des liens n'est nécessaire.

L'édition des liens dynamique permet de créer des exécutables de tailles réduites. De plus, il n'y a habituellement aucun besoin de recompiler le programme si une des librairies utilisée a été mise à jour. Cependant, à l'exécution du programme, le système d'exploitation recherchera les librairies dynamiques (.dll sous Windows) pour faire la liaison des liens finale. Il s'écoulera un certain temps lors du chargement de l'application. De plus, si l'une des librairies est manquante (fichier dll non trouvé), le programme ne pourra pas s'exécuter.

Par exemple, le programme qui écrit "Bonjour" à l'écran en C, prend 32Ko en version statique et 16Ko en version dynamique. Un autre exemple est une application Windows qui prend 256Ko en version statique et 40Ko en version dynamique.

 

Retour à l'index


 

Que mettre dans un fichier d'entête (.h ou .hpp)

Dans un fichier .h ou .hpp, il faut habituellement mettre :

  1. L'entête du fichier :

//////////////////////////////////////////////////////////////////////////
// Nom:             exemple.h
// Description:     Démontre l'entête d'un fichier d'inclusion
// Programmeur:     Pierre-Martin Tardif, professeur
// Création:        8 septembre 1998
// Modifications:   PMT - premiere version
// Notes:           Aucune remarque particulière
//////////////////////////////////////////////////////////////////////////

  1. Les commandes au préprocesseur :

    #define ETIQUETTE VALEUR_ETIQUETTE

    #define MACRO(a,b) cout << "La valeur de " << a << " est " << b << endl;

    #include <nom_fichier.h>

  2. Les déclarations de type :

    typedef unsigned char byte;

    typedef int MATRICE_ENTIERE[100][100];

  3. Les déclarations des fonctions que je définis moi-même :

    int MaPremiereFonction(void);

    void PresseTouche(void);

  4. Des constantes :

    const int NOMBRE_COLONNE = 3;

    const float PI = 3.1415926536;

Voici le fichier math.h dans À CORRIGER quelque peu décortiqué:

ENTÊTE DU FICHIER

/***
*math.h - definitions and declarations for math library
*
* Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved.
*
*Purpose:
* This file contains constant definitions and external subroutine
* declarations for the math subroutine library.
* [ANSI/System V]
*
* [Public]
*
****/

COMMANDES AU COMPILATEUR
#if _MSC_VER > 1000
#pragma once
#endif
#ifndef _INC_MATH
#define _INC_MATH
#if !defined(_WIN32) && !defined(_MAC)
#error ERROR: Only Mac or Win32 targets supported!
#endif
#ifdef _MSC_VER
/*
* Currently, all MS C compilers for Win32 platforms default to 8 byte
* alignment.
*/
#pragma pack(push,8)
#endif /* _MSC_VER */

MACROS

/* Define _CRTIMP */

#ifndef _CRTIMP
#ifdef _DLL
#define _CRTIMP __declspec(dllimport)
#else /* ndef _DLL */
#define _CRTIMP
#endif /* _DLL */
#endif /* _CRTIMP */

/* Definition of _exception struct - this struct is passed to the matherr
* routine when a floating point exception is detected
*/

DÉFINITIONS DE TYPE

/* Definition of a _complex struct to be used by those who use cabs and
* want type checking on their argument
*/

CONSTANTES

/* Constant definitions for the exception type passed in the _exception struct
*/

#define _DOMAIN 1 /* argument domain error */
#define _SING 2 /* argument singularity */
#define _OVERFLOW 3 /* overflow range error */
#define _UNDERFLOW 4 /* underflow range error */
#define _TLOSS 5 /* total loss of precision */
#define _PLOSS 6 /* partial loss of precision */

#define EDOM 33
#define ERANGE 34

DÉCLARATIONS DE FONCTION (PROTOTYPES)

/* Function prototypes */
int __cdecl abs(int);
double __cdecl acos(double);
double __cdecl asin(double);
double __cdecl atan(double);
double __cdecl atan2(double, double);
double __cdecl cos(double);
double __cdecl cosh(double);
double __cdecl exp(double);
double __cdecl fabs(double);
double __cdecl fmod(double, double);
long __cdecl labs(long);
double __cdecl log(double);
double __cdecl log10(double);
double __cdecl pow(double, double);
double __cdecl sin(double);
double __cdecl sinh(double);
double __cdecl tan(double);
double __cdecl tanh(double);
double __cdecl sqrt(double);

MACROS

/* Macros defining long double functions to be their double counterparts
* (long double is synonymous with double in this implementation).
*/
#define acosl(x) ((long double)acos((double)(x)))
#define asinl(x) ((long double)asin((double)(x)))
#define atanl(x) ((long double)atan((double)(x)))
#define atan2l(x,y) ((long double)atan2((double)(x), (double)(y)))
#define _cabsl _cabs
#define ceill(x) ((long double)ceil((double)(x)))
#define cosl(x) ((long double)cos((double)(x)))
#define coshl(x) ((long double)cosh((double)(x)))
#define expl(x) ((long double)exp((double)(x)))
#define fabsl(x) ((long double)fabs((double)(x)))
#define floorl(x) ((long double)floor((double)(x)))
#define fmodl(x,y) ((long double)fmod((double)(x), (double)(y)))
#define frexpl(x,y) ((long double)frexp((double)(x), (y)))
#define _hypotl(x,y) ((long double)_hypot((double)(x), (double)(y)))
#define ldexpl(x,y) ((long double)ldexp((double)(x), (y)))
#define logl(x) ((long double)log((double)(x)))
#define log10l(x) ((long double)log10((double)(x)))
#define _matherrl _matherr
#define modfl(x,y) ((long double)modf((double)(x), (double *)(y)))
#define powl(x,y) ((long double)pow((double)(x), (double)(y)))
#define sinl(x) ((long double)sin((double)(x)))
#define sinhl(x) ((long double)sinh((double)(x)))
#define sqrtl(x) ((long double)sqrt((double)(x)))
#define tanl(x) ((long double)tan((double)(x)))
#define tanhl(x) ((long double)tanh((double)(x)))
#endif /* _MSC_VER */

#endif /* _INC_MATH */

Comme nous le voyons, les fichiers d'inclusion peuvent être très complexes. L'exemple précédant (math.h) a été écourté !

 

Retour à l'index


 

L'aide en ligne de Visual C++

Pour obtenir de l'aide, il suffit d'enforcer l'icône helpicon.jpg (1013 bytes) à l'aide de la souris ou d'aller dans le menu help. Cette aide (et plus encore) est également disponible sur http://premium.microsoft.com/msdn/library/. Vous y trouverez toutes les fonctions, les mots clés et les structures du langage C (aller dans Visual C++ Documentation -> Reference -> C/C++ language reference).

 

Retour à l'index