Confuso sull’espansione della macro C e sull’aritmetica dei numeri interi

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.

  • Come funziona questo typecast?

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 per esempio) sufficienti per impostare il tipo esatto in virgola mobile:

 #define FLOAT_PI 3.14f 

Questo inserisce un letterale a virgola mobile float (cioè “precisione singola”) ovunque si digiti FLOAT_PI nel codice.