Structure d’un programme C++ et compilation

Salut ce forum apprends les bases du c++

Moderator: Rick

Post Reply
Hydraxx
Site Admin
Posts: 114
Joined: Mon Jan 12, 2026 4:04 pm
Location: France
Contact:

Structure d’un programme C++ et compilation

Post by Hydraxx »

STRUCTURE D’UN PROGRAMME C++ ET COMPILATION

À QUOI ÇA SERT ?

Avant d’apprendre les variables, les pointeurs ou les classes, il faut comprendre ce qu’est réellement un programme C++.

Quand tu écris :

Code: Select all

int main()
{
    return 0;
}
ce texte n’est pas directement exécuté par le processeur. Il doit d’abord être transformé en code machine.

Le chemin général ressemble à ceci :

Code source C++

Préprocesseur

Compilation

Assemblage

Fichier objet

Édition de liens

Exécutable

Cette chaîne est fondamentale en développement système, car elle explique ensuite :
  • les symboles ;
  • les fichiers .obj/.o ;
  • les bibliothèques statiques ;
  • les DLL et .so ;
  • les erreurs du linker ;
  • les imports/exports ;
  • les conventions d’appel ;
  • les tables de symboles ;
  • le reverse engineering.

1. LA FONCTION main()


Dans un programme C++ classique, main() est le point d’entrée du programme au niveau du langage.

Code: Select all

int main()
{
    return 0;
}
Le type de retour est int.

La valeur retournée est transmise au système d’exploitation.

Par convention :

Code: Select all

return 0;
signifie que le programme s’est terminé normalement.

Une valeur différente de 0 peut être utilisée pour signaler une erreur.

Exemple :

Code: Select all

int main()
{
    if (somethingFailed())
        return 1;

    return 0;
}
Pourquoi retourner un nombre ?

Parce qu’un autre programme peut lancer ton exécutable et récupérer son code de sortie.

Sous Linux, le shell peut afficher ce code avec :

Code: Select all

echo $?
Sous Windows, un processus parent peut également récupérer le code de sortie d’un processus enfant.

Donc main() n’est pas seulement une convention syntaxique : sa valeur de retour sert à communiquer avec l’environnement qui a lancé le programme.


2. main() AVEC DES ARGUMENTS


main() peut recevoir les arguments passés sur la ligne de commande.

Code: Select all

int main(int argc, char* argv[])
{
    return 0;
}
argc signifie "argument count".

argv signifie "argument vector".

Exemple d’exécution :

Code: Select all

programme.exe fichier.txt 42
On obtient conceptuellement :

Code: Select all

argc == 3

argv[0] = "programme.exe"
argv[1] = "fichier.txt"
argv[2] = "42"
argv est un tableau de pointeurs vers des chaînes C.

On peut faire :

Code: Select all

#include <iostream>

int main(int argc, char* argv[])
{
    for (int i = 0; i < argc; ++i)
    {
        std::cout << argv[i] << '\n';
    }

    return 0;
}
Intérêt système :

Les arguments sont préparés par le runtime avant l’appel à main(). En réalité, lorsqu’un exécutable est chargé, le système ne saute généralement pas directement à main(). Il saute vers un point d’entrée défini par le runtime C/C++, qui initialise l’environnement du programme avant d’appeler main().

Donc :

Point d’entrée PE/ELF

runtime C/C++

initialisations

main()

C’est particulièrement important en reverse engineering.


3. COMMENTAIRES


Le commentaire sur une ligne :

Code: Select all

// Ceci est un commentaire
Le commentaire sur plusieurs lignes :

Code: Select all

/*
    Ceci est un commentaire
    sur plusieurs lignes
*/
À quoi servent-ils ?

Ils servent à expliquer l’intention du code.

Un bon commentaire explique surtout POURQUOI quelque chose est fait.

Exemple mauvais :

Code: Select all

i++; // incrémente i
Le code le dit déjà.

Exemple plus utile :

Code: Select all

// On saute l’entrée 0 car elle contient l’en-tête du protocole.
++i;

4. #include ET LE PRÉPROCESSEUR


Exemple :

Code: Select all

#include <iostream>
#include est traité avant la compilation proprement dite.

Le préprocesseur traite notamment :
  • #include
  • #define
  • #ifdef
  • #ifndef
  • #if
  • #endif
Exemple :

Code: Select all

#ifdef _WIN32
    // code Windows
#else
    // autre plateforme
#endif
À quoi cela sert ?

Cela permet de sélectionner du code selon la plateforme ou la configuration.

Exemple bas niveau :

Code: Select all

#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif

5. MODULES C++


Le C++ moderne introduit les modules.

Exemple :

Code: Select all

import std;
Pourquoi ?

Historiquement, les headers sont inclus textuellement.

Si 50 fichiers incluent le même gros header, le compilateur doit analyser énormément de contenu plusieurs fois.

Les modules visent à :
  • accélérer les compilations ;
  • mieux isoler les interfaces ;
  • éviter plusieurs problèmes liés aux macros ;
  • réduire les dépendances textuelles.
Important :

Un module et un namespace ne sont PAS la même chose.

Le module organise l’unité de compilation/import.

Le namespace organise les noms.

Par exemple un module peut contenir :

Code: Select all

namespace Network
{
    void connect();
}

namespace Database
{
    void connect();
}

6. LES ÉTAPES DE COMPILATION


1) Prétraitement

Le préprocesseur traite les directives.

2) Compilation

Le compilateur :
  • vérifie la syntaxe ;
  • vérifie les types ;
  • applique les règles du langage ;
  • optimise éventuellement ;
  • produit une représentation proche du code machine.
3) Assemblage

Création d’un fichier objet :

Windows :

Code: Select all

programme.obj
Linux :

Code: Select all

programme.o
4) Linking

Le linker rassemble :
  • les fichiers objets ;
  • les bibliothèques ;
  • les symboles externes.
Exemple :

main.cpp :

Code: Select all

int add(int, int);

int main()
{
    return add(1, 2);
}
math.cpp :

Code: Select all

int add(int a, int b)
{
    return a + b;
}
main.cpp connaît l’existence de add(), mais pas son implémentation.

Le linker retrouve la définition dans math.obj.

Si math.obj n’est pas lié, on obtient une erreur du type "unresolved external symbol".


7. DÉCLARATION ET DÉFINITION


Déclaration :

Code: Select all

int add(int a, int b);
Elle dit :

"Une fonction add existe et accepte deux int."

Définition :

Code: Select all

int add(int a, int b)
{
    return a + b;
}
Elle fournit réellement le code.

Cette distinction devient capitale avec :
  • headers ;
  • fichiers .cpp ;
  • DLL ;
  • bibliothèques ;
  • exports/imports.

8. ENTRÉES ET SORTIES


Sortie classique :

Code: Select all

std::cout << "Hello\n";
Erreur standard :

Code: Select all

std::cerr << "Erreur\n";
Entrée :

Code: Select all

int value{};
std::cin >> value;
Exemple :

Code: Select all

#include <iostream>

int main()
{
    int age{};

    std::cout << "Age : ";
    std::cin >> age;

    std::cout << "Tu as " << age << " ans\n";
}
C++23 apporte aussi std::print et std::println selon le support du compilateur.

Code: Select all

std::println("Valeur = {}", 42);

9. '\n' CONTRE std::endl

Code: Select all

std::cout << "Hello\n";
ajoute simplement une nouvelle ligne.

Code: Select all

std::cout << "Hello" << std::endl;
ajoute une nouvelle ligne ET force un flush du buffer.

Un flush force les données à être poussées vers le flux.

Cela peut coûter plus cher en performances.

Donc ne pas utiliser std::endl systématiquement sans raison.


À RETENIR

  • Le code C++ doit être transformé en code machine.
  • Le préprocesseur agit avant le compilateur.
  • Les fichiers .cpp sont généralement compilés séparément.
  • Le linker résout les symboles entre fichiers.
  • main() est le point d’entrée C++ visible, mais pas nécessairement le point d’entrée binaire.
  • Comprendre compilation et linking est indispensable pour le système et le reverse.

Return to “Bases du C++”

Who is online

Users browsing this forum: No registered users and 1 guest