Een char afdrukken met printf

Zijn beide codes hetzelfde

char ch = 'a';
printf("%d", ch);

Zal het een afvalwaarde afdrukken?

Ik ben hierover in de war

printf("%d", '\0'); 

Zal dit een 0 of een afvalwaarde afdrukken?
Want als ik dit doe

printf("%d", sizeof('\n')); 

Het print 4. Waarom is sizeof('\n')4 bytes?
Hetzelfde in C++ drukt 1 bytes af. Waarom is dat?

Dus hier is de hoofdvraag

in c taal is printf("%d", '\0')verondersteld om 0 af te drukken

en in C++ printf("%d", '\0')verondersteld om afval af te drukken?


Antwoord 1, autoriteit 100%

%ddrukt een geheel getal af: het zal de ascii-representatie van je personage afdrukken. Wat je nodig hebt is %c:

printf("%c", ch);

printf("%d", '\0');drukt de ascii-representatie van '\0'af, die 0 is (door 0 te escapen vertel je de compiler om de ascii-waarde 0 te gebruiken.

printf("%d", sizeof('\n'));drukt 4 af omdat een letterlijke letter een intis, in C, en niet een char.


Antwoord 2, autoriteit 20%

Dit wordt verondersteld de ASCII-waarde van het teken af te drukken, aangezien %dde escape-reeks is voor een geheel getal. Dus de waarde die als argument van printfwordt gegeven, wordt bij het afdrukken als geheel getal beschouwd.

char ch = 'a';
printf("%d", ch);

Hetzelfde geldt voor printf("%d", '\0');, waarbij het NULL-teken wordt geïnterpreteerd als het gehele getal 0.

Ten slotte is sizeof('\n')4 omdat in C deze notatie voor tekens staat voor het corresponderende ASCII-getal. Dus ‘\n’ is hetzelfde als 10 als een geheel getal.

Het hangt allemaal af van de interpretatie die je aan de bytes geeft.


Antwoord 3, autoriteit 15%

In C hebben tekenconstante-expressies zoals '\n'of 'a'het type int(dus sizeof '\n' == sizeof (int)), terwijl ze in C++ het type charhebben.

De instructie printf("%d", '\0');moet gewoon 0; het type van de uitdrukking '\0'is inten de waarde is 0.

De instructie printf("%d", ch);moet de gehele codering afdrukken voor de waarde in ch(voor ASCII, 'a'== 97).


Antwoord 4, autoriteit 13%

In C wordt chargepromoveerd tot intin expressies. Dat verklaart vrijwel elke vraag, als je erover nadenkt.

Bron: De C-programmeertaal door Brian W.Kernighan en Dennis M.Ritchie

Een must read als je C wilt leren.

Zie ook deze stack-overlooppagina, waar mensen met veel meer ervaring dan ik het veel beter kunnen uitleggen dan ik ooit kan.


Antwoord 5, autoriteit 7%

#include <stdio.h>
#include <stdlib.h>
int func(char a, char b, char c) /* demonstration that char on stack is promoted to int !!!
                                    note: this promotion is NOT integer promotion, but promotion during handling of the stack. don't confuse the two */
{
  const char *p = &a;
  printf("a=%d\n"
         "b=%d\n"
         "c=%d\n", *p, p[-(int)sizeof(int)], p[-(int)sizeof(int) * 2]); // don't do this. might probably work on x86 with gcc (but again: don't do this)
}
int main(void)
{
  func(1, 2, 3);
  //printf with %d treats its argument as int (argument must be int or smaller -> works because of conversion to int when on stack -- see demo above)
  printf("%d, %d, %d\n", (long long) 1, 2, 3); // don't do this! Argument must be int or smaller type (like char... which is converted to int when on the stack -- see above)
  // backslash followed by number is a oct VALUE
  printf("%d\n", '\377');             /* prints -1   -> IF char is signed char: char literal has all bits set and is thus value -1.
                                                     -> char literal is then integer promoted to int. (this promotion has nothing to do with the stack. don't confuse the two!!!) */
                                      /* prints 255  -> IF char is unsigned char: char literal has all bits set and is thus value 255.
                                                     -> char literal is then integer promoted to int */
  // backslash followed by x is a hex VALUE
  printf("%d\n", '\xff');             /* prints -1   -> IF char is signed char: char literal has all bits set and is thus value -1.
                                                     -> char literal is then integer promoted to int */
                                      /* prints 255  -> IF char is unsigned char: char literal has all bits set and is thus value 255.
                                                     -> char literal is then integer promoted to int */
  printf("%d\n", 255);                // prints 255
  printf("%d\n", (char)255);          // prints -1   -> 255 is cast to char where it is -1
  printf("%d\n", '\n');               // prints 10   -> Ascii newline has VALUE 10. The char 10 is integer promoted to int 10
  printf("%d\n", sizeof('\n'));       // prints 4    -> Ascii newline is char, but integer promoted to int. And sizeof(int) is 4 (on many architectures)
  printf("%d\n", sizeof((char)'\n')); // prints 1    -> Switch off integer promotion via cast!
  return 0;
}

Antwoord 6

Ja, het drukt afval af, tenzij u geluk hebt.

erg belangrijk.

Het type van het PRINTF / SPRINTF / FPRINTF-argument moet overeenkomen met het bijbehorende type CHAR.

Als de typen niet overeenkomen en het compileren, zijn de resultaten zeer ongedefinieerd.

Veel nieuwere compilers weten over printf en probleemwaarschuwingen als de typen niet overeenkomen. Als u deze waarschuwingen krijgt, bevestigt u ze.

Als u typen voor argumenten voor variabele functies wilt converteren, moet u de cast (dwz expliciete conversie) leveren omdat de compiler niet kan achterhalen dat een conversie moet worden uitgevoerd (zoals het kan met een functie-prototype met getypte argumenten).

printf("%d\n", (int) ch)

In dit voorbeeld wordt afdrukken verteld dat er een “int” op de stapel is. De cast zorgt ervoor dat wat dan ook terugkeert (een soort van lang geheel getal, meestal), printf krijgt een int.

printf("%d", (int) sizeof('\n'))

Other episodes