Menu
Coddy logo textTech

Wskaźnik czy wartość

Część sekcji Programowanie obiektowe ścieżki C w Coddy. Lekcja 9 z 61.

Gdy przekazujesz strukturę do funkcji, C daje ci dwie możliwości: przekazać ją przez wartość (skopiować całą strukturę) lub przez wskaźnik (skopiować tylko adres). Wybór ma istotny wpływ na wydajność.

Przekazywanie przez wartość tworzy pełną kopię struktury na stosie. W przypadku małej struktury z kilkoma liczbami całkowitymi jest to w porządku. Ale wyobraź sobie strukturę mającą setki bajtów: każde wywołanie funkcji kopiuje wszystkie te dane:

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

// Przez wartość: kopiuje ~308 bajtów przy każdym wywołaniu
void print_by_value(Student s) {
    printf("%s: %.2f\n", s.name, s.average);
}

// Przez wskaźnik: kopiuje tylko 8 bajtów (adres)
void print_by_pointer(const Student *s) {
    printf("%s: %.2f\n", s->name, s->average);
}

Składnia również się różni. W przypadku parametru przekazywanego przez wartość używasz operatora kropki (s.name). W przypadku wskaźnika używasz operatora strzałki (s->name).

Wersja ze wskaźnikiem jest bardziej wydajna, ponieważ przekazuje tylko adres pamięci, zazwyczaj 8 bajtów niezależnie od rozmiaru struktury.

Dlatego programiści C niemal zawsze przekazują struktury przez wskaźnik. Użyj const, gdy funkcja nie powinna modyfikować danych, a zwykłego wskaźnika, gdy powinna. Zyskujesz zarówno wydajność, jak i jasny zamiar.

challenge icon

Wyzwanie

Łatwy

Zbudujmy moduł Product, który pokazuje różnicę między przekazywaniem struktur przez wartość a przez wskaźnik. Utworzysz dwie funkcje wyświetlające: jedną, która otrzymuje całą strukturę jako kopię, i drugą, która otrzymuje tylko wskaźnik do niej.

Utworzysz trzy pliki:

  • product.h: Zadeklaruj strukturę Product z trzema polami: char name[50], double price i int quantity. Zadeklaruj też dwie funkcje:
    • display_by_value: przyjmuje Product przez wartość i wyświetla jego informacje
    • display_by_pointer: przyjmuje const Product * i wyświetla te same informacje
    Użyj strażników dołączania z symbolem PRODUCT_H.
  • product.c: Zaimplementuj obie funkcje. Zwróć uwagę na różnicę składni: wersja przekazująca przez wartość używa operatora kropki (p.name), a wersja wskaźnikowa używa operatora strzałki (p->name). Obie funkcje powinny wyświetlać informacje w tym samym formacie.
  • main.c: Utwórz obiekt Product, a następnie wywołaj obie funkcje wyświetlające, aby pokazać, że generują identyczne dane wyjściowe mimo użycia różnych sposobów przekazywania argumentów.

Otrzymasz trzy dane wejściowe: nazwę produktu (ciąg znaków), cenę (liczbę typu double) i ilość (liczbę całkowitą).

W pliku main zainicjalizuj obiekt Product tymi wartościami, a następnie wywołaj display_by_value, po czym display_by_pointer.

Obie funkcje powinny wyświetlać informacje w tym formacie:

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

Użyj %.2f dla ceny, aby wyświetlić ją z dokładnością do dwóch miejsc po przecinku.

Na przykład dla danych wejściowych Laptop, 999.99 i 5 dane wyjściowe będą następujące:

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

Spróbuj swoich sił

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

int main() {
    char name[50];
    double price;
    int quantity;
    
    // Wczytaj dane wejściowe
    scanf("%s", name);
    scanf("%lf", &price);
    scanf("%d", &quantity);
    
    // TODO: Utwórz zmienną typu Product i zainicjalizuj ją wartościami wejściowymi
    // Wskazówka: Użyj strcpy, aby skopiować nazwę do pola name struktury
    
    // TODO: Wywołaj display_by_value, przekazując Product
    
    // TODO: Wywołaj display_by_pointer, przekazując wskaźnik do Product
    
    return 0;
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator C online