Possibile duplicato:
Un indovinello (in C)
Ho un paio di domande riguardo il seguente frammento:
#include #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) int array[] = {23,34,12,17,204,99,16}; int main() { int d; for(d=-1;d <= (TOTAL_ELEMENTS-2);d++) printf("%d\n",array[d+1]); return 0; }
Qui l’output del codice non stampa gli elementi dell’array come previsto. Ma quando aggiungo un typecast di (int) la definizione della macro di ELEMENTS come
#define TOTAL_ELEMENTS (int) (sizeof(array) / sizeof(array[0]))
Visualizza tutti gli elementi dell’array come previsto.
Sulla base di questo ho alcune domande:
Significa se ho qualche definizione di macro come:
#define AA (-64)
per impostazione predefinita in C, tutte le costanti definite come macro sono equivalenti a int signed .
Se sì, allora
Ma se devo forzatamente fare una costante definita in una macro come un int unsigned c’è un suffisso costante di quello che posso usare (ho provato UL, UD non ha funzionato)?
Come posso definire una costante in una definizione di macro per comportarsi come unsigned int?
Guarda questa linea:
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
Nella prima iterazione, stai verificando se
-1 <= (TOTAL_ELEMENTS-2)
L'operatore size_of restituisce un valore senza segno e il controllo fallisce (-1 firmato = 0xFFFFFFFF non firmato su macchine a 32 bit).
Un semplice cambiamento nel ciclo risolve il problema:
for(d=0;d <= (TOTAL_ELEMENTS-1);d++) printf("%d\n",array[d]);
Per rispondere alle altre domande: le macro C sono espanse dal punto di vista del testo, non esiste la nozione di tipi. Il compilatore C vede il tuo loop come questo:
for(d=-1;d <= ((sizeof(array) / sizeof(array[0]))-2);d++)
Se si desidera definire una costante non firmata in una macro, utilizzare il solito suffisso ( u
per unsigned
, ul
per unsigned long
).
sizeof
restituisce il numero di byte in formato non firmato. Ecco perché hai bisogno del cast.
Vedi di più qui .
Per quanto riguarda la tua domanda su
#define AA (-64)
Vedi la definizione e l’espansione delle macro nel C preprocessor
:
Le macro ad oggetti sono state usate convenzionalmente come parte della buona pratica di programmazione per creare nomi simbolici per le costanti, ad es
#define PI 3.14159
… invece di codificare in modo fisso quei numeri nel codice. Tuttavia, sia C che C ++ forniscono la direttiva const, che fornisce un altro modo per evitare costanti hard-coding in tutto il codice.
Le costanti definite come macro non hanno un tipo associato. Usa const
dove ansible.
Rispondere solo a una delle tue sotto-domande:
Per “definire una costante in una macro” (questo è un po ‘sciatto, non stai definendo una “costante”, semplicemente facendo alcuni trucchi di sostituzione del testo) che non è firmato, dovresti usare il suffisso “u”:
#define UNSIGNED_FORTYTWO 42u
Questo inserirà un letterale unsigned int
ovunque tu UNSIGNED_FORTYTWO
.
Allo stesso modo, si vede spesso (in
#define FLOAT_PI 3.14f
Questo inserisce un letterale a virgola mobile float
(cioè “precisione singola”) ovunque si digiti FLOAT_PI
nel codice.