0Pricing
C Academy · Lezione

memcpy e memset

Funzioni per la memoria grezza

memcpy e memset è una lezione C Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C Academy include 4 lezioni in totale.

Funzioni per la memoria grezza

A differenza delle funzioni per le stringhe, memcpy e memset operano su byte grezzi e ignorano i terminatori nulli.

Sono dichiarate in <string.h> e operano su un numero di byte specificato dall'utente, quindi sono utilizzabili con qualsiasi tipo di dato.

#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;
}

La firma di memcpy

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

Copia esattamente n byte da src a dest e restituisce dest. Usate sizeof per ottenere il numero corretto di byte.

#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;
}

Contare correttamente i byte

Il conteggio è espresso in byte, non in elementi. Per un array di int, dovete moltiplicare per sizeof(int).

Usando sizeof(array) su un array reale ottenete automaticamente la dimensione totale in byte.

#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;
}

Le regioni non devono sovrapporsi

memcpy ha un comportamento indefinito se le regioni sorgente e destinazione si sovrappongono.

Quando gli intervalli potrebbero sovrapporsi, ad esempio nello spostamento di elementi all'interno di un array, usate invece memmove, che gestisce correttamente la sovrapposizione.

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

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

La firma di memset

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

Riempie n byte a partire da ptr con il byte value. Il valore viene interpretato come unsigned char, quindi contano solo gli 8 bit meno significativi.

#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;
}

Azzerare la memoria

L'uso più comune di memset consiste nel cancellare un buffer o una struct impostando tutti i byte a zero prima dell'uso.

memset(arr, 0, sizeof(arr)) imposta ogni byte a 0, che rappresenta uno zero valido per interi, numeri in virgola mobile e puntatori.

#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 opera byte per byte

Fate attenzione: memset imposta ogni byte, non ogni elemento. Usarlo per riempire un array di int con il valore 1 NON produce degli 1.

Ogni int avrebbe tutti i byte impostati a 0x01, ottenendo 0x01010101 anziché 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;
}

Cancellare una struct

memset è utile per inizializzare a zero un'intera struct con una sola chiamata, invece di impostare manualmente ogni campo.

#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;
}

Copiare le struct

È possibile copiare una struct con memcpy, anche se la semplice assegnazione (b = a;) di solito svolge lo stesso compito in modo più chiaro.

memcpy è preferibile quando si copia attraverso puntatori generici void *, in cui i tipi non sono più disponibili.

#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: confrontare la memoria

Una funzione correlata, memcmp(a, b, n), confronta n byte grezzi e restituisce 0 se corrispondono.

A differenza di strcmp, non si ferma davanti a un terminatore nullo, quindi funziona con qualsiasi dato binario.

#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;
}

Perché sono veloci

memcpy e memset sono spesso ottimizzate manualmente in assembly per spostare molti byte con una singola istruzione.

Di solito sono molto più veloci di un ciclo sui byte scritto manualmente, quindi preferitele per lo spostamento e l'inizializzazione di grandi quantità di dati.

#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;
}

Verifica rapida

Verificate la vostra comprensione del comportamento di memset a livello di byte.

Riepilogo

Avete imparato le funzioni per la memoria grezza:

  • memcpy copia n byte; le regioni non devono sovrapporsi (usate memmove se potrebbero farlo).
  • memset riempie n byte con un unico valore di byte; è ottima per azzerare la memoria.
  • I conteggi sono espressi in byte: usate sizeof e fate attenzione alle differenze tra byte ed elementi.
  • memcmp confronta i byte grezzi senza fermarsi davanti a '\0'.

Domande Frequenti

La lezione «memcpy e memset» è gratuita?

Sì — il testo completo di «memcpy e memset» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C Academy, passa a CoddyKit PRO. Il corso C Academy include 4 lezioni in totale.

Cosa imparerò in «memcpy e memset»?

Funzioni per la memoria grezza Eserciti C Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C Academy?

Non è richiesta alcuna esperienza precedente. C Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «memcpy e memset»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C Academy?

Sì. Ogni lezione C Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. strlen, strcpy, strcat
  2. strcmp e confronto
  3. strtok e tokenizzazione
  4. memcpy e memset
← Torna a C Academy