0Pricing
C Academy · Lekcja

memcpy i memset

Funkcje operujące na surowej pamięci

memcpy i memset to bezpłatna lekcja C Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C Academy zawiera 4 lekcji w sumie.

Funkcje operujące na surowej pamięci

W przeciwieństwie do funkcji napisowych, memcpy i memset działają na surowych bajtach i ignorują terminatory null.

Są zadeklarowane w bibliotece <string.h> i operują na podanej liczbie bajtów, dzięki czemu nadają się do dowolnych typów danych.

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

int main(void) {
    int src[] = {1, 2, 3};
    int dest[3];
    memcpy(dest, src, sizeof(src));
    printf("%d %d %d\n", dest[0], dest[1], dest[2]);
    return 0;
}

Sygnatura memcpy

void *memcpy(void *dest, const void *src, size_t n);

Funkcja kopiuje dokładnie n bajtów z src do dest i zwraca dest. Użyj sizeof, aby uzyskać właściwą liczbę bajtów.

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

int main(void) {
    char src[] = "copy me";
    char dest[16];
    memcpy(dest, src, strlen(src) + 1);
    printf("%s\n", dest);
    return 0;
}

Prawidłowe zliczanie bajtów

Liczba dotyczy bajtów, a nie elementów. W przypadku tablicy typu int trzeba pomnożyć ją przez sizeof(int).

Użycie sizeof(array) dla rzeczywistej tablicy automatycznie zwraca jej całkowity rozmiar w bajtach.

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

int main(void) {
    double a[4] = {1.5, 2.5, 3.5, 4.5};
    double b[4];
    memcpy(b, a, 4 * sizeof(double));
    printf("%.1f %.1f\n", b[0], b[3]);
    return 0;
}

Obszary nie mogą się nakładać

memcpy ma niezdefiniowane zachowanie, jeśli obszary źródłowy i docelowy się nakładają.

Gdy zakresy mogą się nakładać, na przykład podczas przesuwania elementów w jednej tablicy, użyj zamiast tego memmove, która bezpiecznie obsługuje nakładanie.

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

int main(void) {
    char buf[] = "ABCDEF";
    memmove(buf + 2, buf, 4);
    printf("%s\n", buf);
    return 0;
}

Sygnatura memset

void *memset(void *ptr, int value, size_t n);

Funkcja wypełnia n bajtów pod adresem ptr bajtem o wartości value. Wartość jest interpretowana jako unsigned char, więc znaczenie ma tylko 8 najmłodszych bitów.

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

int main(void) {
    char buf[6];
    memset(buf, 'x', 5);
    buf[5] = '\0';
    printf("%s\n", buf);
    return 0;
}

Zerowanie pamięci

Najczęstszym zastosowaniem memset jest wyczyszczenie bufora lub struktury, czyli ustawienie wszystkich bajtów na zero przed użyciem.

memset(arr, 0, sizeof(arr)) ustawia każdy bajt na 0, co jest poprawną reprezentacją zera dla typów int, float i wskaźników.

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

int main(void) {
    int counts[5];
    memset(counts, 0, sizeof(counts));
    for (int i = 0; i < 5; i++) printf("%d ", counts[i]);
    printf("\n");
    return 0;
}

memset działa bajt po bajcie

Należy zachować ostrożność: memset ustawia każdy bajt, a nie każdy element. Użycie tej funkcji do wypełnienia tablicy typu int wartością 1 NIE ustawi elementów na jeden.

Każdy element typu int będzie miał wszystkie bajty ustawione na 0x01, co da wartość 0x01010101, a nie 1.

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

int main(void) {
    int a[2];
    memset(a, 1, sizeof(a));
    printf("%d\n", a[0]);
    return 0;
}

Zerowanie struktury

memset pozwala wygodnie zainicjalizować całą strukturę zerami w jednym wywołaniu zamiast ustawiać każde pole osobno.

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

struct Point { int x; int y; int z; };

int main(void) {
    struct Point p;
    memset(&p, 0, sizeof(p));
    printf("%d %d %d\n", p.x, p.y, p.z);
    return 0;
}

Kopiowanie struktur

Strukturę można skopiować za pomocą memcpy, choć zwykłe przypisanie (b = a;) zazwyczaj robi to samo w bardziej czytelny sposób.

memcpy jest preferowane podczas kopiowania za pośrednictwem ogólnych wskaźników void *, gdy typy zostały utracone.

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

struct Rec { int id; char tag; };

int main(void) {
    struct Rec a = {42, 'A'};
    struct Rec b;
    memcpy(&b, &a, sizeof(a));
    printf("%d %c\n", b.id, b.tag);
    return 0;
}

memcmp: porównywanie pamięci

Pokrewna funkcja, memcmp(a, b, n), porównuje n surowych bajtów i zwraca 0, jeśli są identyczne.

W przeciwieństwie do strcmp nie zatrzymuje się na terminatorze null, dlatego działa na dowolnych danych binarnych.

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

int main(void) {
    int a[] = {1, 2, 3};
    int b[] = {1, 2, 3};
    if (memcmp(a, b, sizeof(a)) == 0)
        printf("Arrays have identical bytes\n");
    return 0;
}

Dlaczego te funkcje są szybkie

Funkcje memcpy i memset są często ręcznie optymalizowane w asemblerze, aby przenosić wiele bajtów jedną instrukcją.

Zwykle działają znacznie szybciej niż ręcznie napisana pętla bajtowa, dlatego do masowego przenoszenia i inicjalizowania danych preferuj te funkcje.

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

int main(void) {
    char big[1000];
    memset(big, 0, sizeof(big));
    printf("Cleared %lu bytes\n", sizeof(big));
    return 0;
}

Szybki test

Sprawdź swoją wiedzę na temat działania memset na poziomie bajtów.

Podsumowanie

Poznałeś(-aś) funkcje operujące na surowej pamięci:

  • memcpy kopiuje n bajtów; obszary nie mogą się nakładać (jeśli mogą, użyj memmove).
  • memset wypełnia n bajtów jedną wartością bajtową; świetnie nadaje się do zerowania.
  • Liczby dotyczą bajtów — używaj sizeof i uważaj na pułapki związane z różnicą między bajtami a elementami.
  • memcmp porównuje surowe bajty, nie zatrzymując się na '\0'.

Często zadawane pytania

Czy lekcja „memcpy i memset” jest bezpłatna?

Tak — pełny tekst „memcpy i memset” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C Academy, przejdź na CoddyKit PRO. Kurs C Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „memcpy i memset”?

Funkcje operujące na surowej pamięci Ćwiczysz C Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć C Academy?

Nie wymagamy żadnego doświadczenia. C Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „memcpy i memset”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji C Academy?

Tak. Każda lekcja C Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. strlen, strcpy, strcat
  2. strcmp i porównywanie
  3. strtok i tokenizacja
  4. memcpy i memset
← Powrót do C Academy