Menu
Coddy logo textTech

Pointeur vs Valeur

Fait partie de la section Object Oriented Programming du Journey C de Coddy — leçon 9 sur 61.

Lorsque vous passez une structure à une fonction, le langage C vous offre deux options : la passer par valeur (copier l'intégralité de la structure) ou la passer par pointeur (copier uniquement l'adresse). Ce choix a un impact significatif sur les performances.

Le passage par valeur crée une copie complète de la structure sur la pile. Pour une petite structure avec quelques entiers, cela ne pose pas de problème. Mais imaginez une structure de plusieurs centaines d'octets — chaque appel de fonction copie toutes ces données :

typedef struct {
    char name[100];
    int scores[50];
    double average;
} Student;

// Par valeur : copie ~608 octets à chaque appel
void print_by_value(Student s) {
    printf("%s: %.2f\n", s.name, s.average);
}

// Par pointeur : copie seulement 8 octets (l'adresse)
void print_by_pointer(const Student *s) {
    printf("%s: %.2f\n", s->name, s->average);
}

La syntaxe diffère également. Avec un paramètre de valeur, vous utilisez l'opérateur point (s.name). Avec un pointeur, vous utilisez l'opérateur flèche (s->name).

La version avec pointeur est plus efficace car elle ne transmet qu'une adresse mémoire — généralement 8 octets, quelle que soit la taille de la struct.

C'est pourquoi les programmeurs C passent presque toujours les structures par pointeur. Utilisez const lorsque la fonction ne doit pas modifier les données, et un pointeur classique lorsqu'elle le doit. Vous obtenez à la fois de l'efficacité et une intention claire.

challenge icon

Défi

Facile

Construisons un module Product qui démontre la différence entre le passage de structures par valeur et par pointeur. Vous allez créer deux fonctions d'affichage : une qui reçoit la structure entière sous forme de copie, et une qui reçoit simplement un pointeur vers celle-ci.

Vous allez créer trois fichiers :

  • product.h : Déclarez une structure Product avec trois membres : char name[50], double price, et int quantity. Déclarez également deux fonctions :
    • display_by_value — prend un Product par valeur et affiche ses informations
    • display_by_pointer — prend un const Product * et affiche les mêmes informations
    Utilisez des gardes d'inclusion avec le symbole PRODUCT_H.
  • product.c : Implémentez les deux fonctions. Notez la différence de syntaxe : la version par valeur utilise l'opérateur point (p.name), tandis que la version par pointeur utilise l'opérateur flèche (p->name). Les deux fonctions doivent afficher les données dans le même format.
  • main.c : Créez un Product, puis appelez les deux fonctions d'affichage pour montrer qu'elles produisent une sortie identique malgré l'utilisation de styles de paramètres différents.

Vous recevrez trois entrées : le nom du produit (une chaîne de caractères), le prix (un double), et la quantité (un entier).

Dans votre fichier principal, initialisez un Product avec ces valeurs, puis appelez display_by_value suivi de display_by_pointer.

Les deux fonctions doivent imprimer dans ce format :

Product: {name}, Price: {price}, Qty: {quantity}

Utilisez %.2f pour le prix afin d'afficher deux décimales.

Par exemple, avec les entrées Laptop, 999.99, et 5, la sortie serait :

Product: Laptop, Price: 999.99, Qty: 5
Product: Laptop, Price: 999.99, Qty: 5

Aide-mémoire

Lorsque vous passez des structures à des fonctions, vous pouvez choisir entre le passage par valeur (copie de l'intégralité de la structure) ou le passage par pointeur (copie de l'adresse uniquement).

Le passage par valeur crée une copie complète de la structure :

void print_by_value(Student s) {
    printf("%s: %.2f\n", s.name, s.average);  // Utilisez l'opérateur point
}

Le passage par pointeur ne transmet que l'adresse mémoire :

void print_by_pointer(const Student *s) {
    printf("%s: %.2f\n", s->name, s->average);  // Utilisez l'opérateur flèche
}

Différences clés :

  • Par valeur utilise l'opérateur point (s.member)
  • Par pointeur utilise l'opérateur flèche (s->member)
  • Les pointeurs sont plus efficaces pour les structures volumineuses (seulement 8 octets contre la taille totale de la structure)
  • Utilisez const avec les pointeurs lorsque la fonction ne doit pas modifier les données

Les programmeurs C préfèrent généralement passer les structures par pointeur pour de meilleures performances.

Essayez vous-même

#include <stdio.h>
#include <string.h>
#include "product.h"

int main() {
    char name[50];
    double price;
    int quantity;
    
    // Lire les entrées
    scanf("%s", name);
    scanf("%lf", &price);
    scanf("%d", &quantity);
    
    // TODO : Créer une variable Product et l'initialiser avec les valeurs d'entrée
    // Conseil : Utiliser strcpy pour copier le nom dans le champ name de la structure
    
    // TODO : Appeler display_by_value avec le Product
    
    // TODO : Appeler display_by_pointer avec un pointeur vers le Product
    
    return 0;
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Object Oriented Programming