Domanda

Quando uso malloc e manipoli la memoria in modo simile, posso fare affidamento sul fatto che sizeof (char) è sempre 1?

Ad esempio, devo allocare memoria per N elementi di tipo char . È necessario moltiplicare per sizeof (char) necessario:

char* buffer = malloc( N * sizeof( char ) );

oppure posso fare affidamento su sizeof (char) sempre 1 e saltare la moltiplicazione

char* buffer = malloc( N );

Comprendo completamente che sizeof viene valutato durante la compilazione e quindi il compilatore potrebbe persino compilare la moltiplicazione e quindi la penalità delle prestazioni sarà minima e molto probabilmente zero.

Chiedo principalmente informazioni sulla chiarezza e la portabilità del codice. Questa moltiplicazione è mai necessaria per il tipo char ?

È stato utile?

Soluzione

Anche se non è necessario, ritengo che sia buona norma lasciare la dimensione di (char) perché rende il codice più leggibile ed evita l'uso di un numero magico. Inoltre, se il codice deve essere modificato in un secondo momento, in modo che invece di un carattere stia trasformando la dimensione di qualcosa in un puntatore per quell'oggetto, è più facile cambiare il codice che se hai solo un " 1 " ;.

Altri suggerimenti

Per definizione, sizeof (char) è sempre uguale a 1. Un byte è la dimensione del carattere in C, qualunque sia il numero di bit in un byte presente (8 sulla CPU desktop comune).

L'esempio tipico in cui un byte non è 8 bit è PDP-10 e altre vecchie architetture simili a un mini-computer con byte a 9/36 bit. Ma i byte che non sono 2 ^ N stanno diventando estremamente rari credo

Inoltre, penso che questo sia uno stile migliore:

char* buf1;
double* buf2;

buf1 = malloc(sizeof(*buf1) * N);
buf2 = malloc(sizeof(*buf2) * N);

perché funziona qualunque sia il tipo di puntatore.

sizeof (char) è sempre 1, indipendentemente dal tipo di manipolazione della memoria che esegui.

Tuttavia, sizeof (TCHAR) può variare a seconda delle opzioni del compilatore.

Lo considero un tipo di anti-pattern . Segnala che il programmatore non sapeva bene cosa stesse facendo, il che lancia immediatamente il resto del codice in una luce dubbia.

Certo, non è (citando Wikipedia) "inefficace", ma lo trovo "tutt'altro che ottimale". Non costa nulla in fase di runtime, ma ingombra il codice con inutili cianfrusaglie, segnalando nel frattempo che qualcuno lo riteneva necessario.

Inoltre, si noti che l'espressione non analizza come una chiamata di funzione: sizeof non è una funzione. Non stai chiamando una funzione che gli passa il simbolo magico char . Stai applicando l'operatore prefisso unario incorporato sizeof a un'espressione, e la tua espressione è in questo caso un cast al tipo char , che in C è scritto come (char) .

È perfettamente possibile, e altamente raccomandato ogni volta che è possibile, utilizzare sizeof su altre espressioni, quindi produrrà la dimensione del valore dell'espressione:

char a;
printf("A char's size is %u\n", (unsigned int) sizeof a);

Questo stamperà 1 , sempre, su tutte le implementazioni C conformi.

Sono anche fortemente d'accordo con David Cournapeau e sto pensando di ripetere il tipo nome in un malloc () -call to also essere una specie di anti-modello.

Invece di

char *str;

str = malloc(N * sizeof (char));

che molti avrebbero scritto per allocare un buffer di stringa con capacità di carattere N, preferirei

char *str;

str = malloc(N * sizeof *str);

Oppure (solo per stringhe) omettere la sizeof come sopra, ma questo ovviamente è più generale e funziona altrettanto bene per qualsiasi tipo di puntatore.

Non è necessario. Vedi qui (ad esempio).

sizeof(char) è definito dallo standard C come sempre 1 (byte). Si noti che poiché sizeof restituisce un numero di byte il numero di bit per byte è irrilevante (e in termini pratici è comunque 8).

Qualcos'altro da tenere a mente è che il compilatore conosce staticamente il valore di sizeof (char) è 1 e sa anche che la moltiplicazione di un numero per 1 statico implica che non è necessario eseguire la moltiplicazione; il compilatore lo ottimizzerà. Le preoccupazioni relative alle prestazioni non devono essere prese in considerazione per questi motivi.

Da " Nuovo standard C. Un commento economico e culturale " ;.

  1. Statistiche: 2,0% delle dimensioni di sono prese da char e 1,5% - da unsigned char . Pagina 1033 nella versione 1.2 del libro.
  2. pagina 1037.
  

Il numero di bit nella rappresentazione di un tipo di carattere è   irrilevante. Per definizione il numero   di byte in byte è un tipo di carattere   uno.

     

Linee guida per la codifica A volte gli sviluppatori   associare un byte come sempre contenente   otto bit. Su host dove il   il tipo di carattere è di 16 bit, questo può   portare al presupposto errato che   applicando sizeof a un tipo di carattere   restituirà il valore 2.   Questi problemi sono discussi altrove.

L'uso di sizeof (char) rende il tuo codice più leggibile e portatile.

Su x86, sappiamo tutti che un carattere è 1 byte. Ma scriverlo esplicitamente aiuta a chiarire le tue intenzioni, il che è sempre una buona cosa.

Inoltre, cosa succede se il tuo codice viene inserito su un'altra piattaforma in cui un carattere non è 1 byte. E se invece un personaggio fosse solo 4 bit?

D'accordo, non è necessario, ma non rallenta il tempo di esecuzione e pagherà in quel raro caso in cui è necessario trasferire il codice su un'architettura diversa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top