2014-07-02 10 views
6

Dopo aver letto this Ho iniziato a pensare di aver appreso un bottino su printf(). Improvvisamente ho trovato seguente frammento di codice da this libro:Operatore ternario all'interno di printf

int main() 
{ 
    char str[]="Hello"; 
    int i=5,j=10; 
    printf(i>j?"%50s":"%s",str); //unable to understand this 
    return 0; 
} 

Sorprendentemente sopra codice viene eseguito senza errori e stampe Ciao. Come per la mia conoscenza che segue è la sintassi di printf():

int printf(const char *format,argument_list); 

Quindi, secondo questa sintassi, printf() dovrebbe iniziare con stringa di formato. Ma come puoi vedere sopra il codice printf() inizia con i>j. Significa che ho torto nell'interpretare la sintassi di printf()? L'inserimento dell'operatore ternario all'interno di printf() è un caso speciale?

EDIT

che so di operatore ternario sto chiedendo circa primo argomento di printf() che dovrebbe essere const char * che non sembra nel mio esempio.

+5

Il risultato dell'espressione all'interno del primo parametro deve essere un puntatore a un array di caratteri costante, quindi nulla di sorprendente. –

+0

vuoi dire qualcosa anche senza virgolette è puntatore a stringa costante –

+1

forse le cose diventano più chiare se la scrivi in ​​questo modo: 'printf ((i> j?"% 50s ":"% s "), str)' –

risposta

6

L'operatore condizionale:

i>j?"%50s":"%s" 

è un'espressione e deve essere valutata prima della funzione stessa chiamata possono essere valutati. Possiamo vedere questo andando al progetto di sezione standard C99 6.5.2.2Funzione chiama che dice:

Un argomento può essere un'espressione di qualsiasi tipo di oggetto. Nella preparazione di la chiamata a una funzione, gli argomenti vengono valutati e a ciascun parametro viene assegnato il valore dell'argomento corrispondente. 81)

Allora, qual è il risultato della valutazione del operatore condizionale? Se andiamo alla sezione 6.5.15operatore condizionale si dice (sottolineatura mia):

Il primo operando viene valutato; c'è un punto di sequenza dopo la sua valutazione . Il secondo operando viene valutato solo se il primo confronta non uguale a 0; il terzo operando viene valutato solo se il primo è uguale a 0; il risultato è il valore del secondo o terzo operando , convertito nel tipo descritto di seguito.

così in entrambi i casi il risultato è una stringa letterale che decadrà a puntatore a char che soddisfa il requisito per il primo argomento printf.

+0

Bella spiegazione !! Ma ho ancora dubbi nell'espressione i> j? "% 50s": "% s" cioè non penso che sia const char *, penso che dovrebbe essere racchiuso tra virgolette doppie. Non è? –

+0

Ok ora lo capisco che è dopo aver valutato l'espressione solo "% s" è passato come argomento per printf() –

+0

@ A.s.Bhullar esattamente, è corretto. –

1

Significa che ho torto nell'interpretazione della sintassi di printf()?

No, non stai interpretando male.

L'inserimento dell'operatore ternario all'interno di printf() è un caso speciale?

In C, si può dire che la sua espressione invece di un'istruzione

Il codice è equivalente a:

if (i > j) 
    printf("%50s", str); 
else 
    printf("%s", str); 
1

L'operatore ternario è semplicemente un inline if che viene utilizzato come espressione (mentre un normale if viene utilizzato per creare un blocco). La tua riga è uguale a questo:

if (i > j) 
    printf("%50s", str); 
else 
    printf("%s", str); 
3

Questo codice è normale e non è un caso particolare. Il requisito per printf è che il primo argomento dovrebbe essere del tipo const char*, ma non significa necessariamente che deve essere una stringa letterale come "%s". Tutto ciò significa che è necessario passare come primo argomento un'espressione del tipo const char*. E i>j?"%50s":"%s" soddisfa questo requisito.

+0

Puoi dare qualche esempio di const char * che non è completamente racchiuso tra virgolette doppie? –

+1

'i> j?"% 50s ":"% s "' è di tipo 'const char *' (tecnicamente è 'const char []' ma non importa qui) quindi immagino che questo sia il tuo esempio. Un altro esempio potrebbe essere 'func()', dove 'func' è una funzione che restituisce' const char * '. –

0

Esiste una dichiarazione del modulo: condizione? Conseguente: alternativa.

La condizione è selezionata, e se è vera ne otterrete la conseguente. altrimenti otterrai l'alternativa.

Ad esempio:

5>3 ? 10 : 5 

5> 3 è vero, così avrai 10.

1
if(i>j) 
    printf("%50s",str); 
else 
    printf("%s",str); 

Pertanto, Hello viene stampato in entrambe le situazioni

1

penso che ben capito la sintassi printf ma credo che vi manca qualcosa sulla sintassi C.

Si esiste una forma di "compatta se come" dichiarazione formattata così: (? condizionevera: falsa)

Per esempio si può fare:

int a=5; 
int b=(a==5 ? 128 : 256); 
int c=(a!=5 ? 8 : 9); 

In questo caso, b = 128 ec = 9.

Un altro esempio:

int flag=1; 
printf("The value is: %s", (flag!=0 ? "true" : "false)); 

In questo caso è possibile vedere: Il valore è vero

Sul tuo esempio:

printf(i>j?"%50s":"%s",str); 

se i è superiore rispetto j te utilizzare il formato "% 50s" e, se i è inferiore, utilizzare il formato "% s"

Può essere vista come:

if (i>j) 
    printf("%50s",str); 
else 
    printf("%s",str); 

Si può vedere il vantaggio di prova compatto.

1

D: Significa che ho torto nell'interpretare la sintassi di printf()?
A: No, è sufficiente espandere ciò che è consentito.

D: Posizionare l'operatore ternario all'interno di printf() è un caso speciale?
A: No ?: non è speciale, ma a volte confonde a prima vista.

Il formato fornito a printf() non deve essere un valore letterale. Potrebbe essere una variabile qualsiasi stringa.

int main() { 
    char str[]="Hello"; 
    char *format; 
    int i,j; 

    i = 5; j = 10; 
    format = i > j ? "%50s" : "%s"; 
    printf(format, str); 

    i = 10; j = 5; 
    format = i > j ? "%50s" : "%s"; 
    printf(format, str); 
    return 0; 
} 
2

Si tratta di un operatore ternario e in questa condizione i> j è falso così% s vengono trasmessi come parametro a printf che stamperà il valore di array di caratteri che è ciao.