What's really going on inside getchar () and printf ()? Explain the whole process

I was learning from geeksforgeeks , and when I saw this, the thought occurred to me that like getchar()

other similar functions return int (due to program failure or EOF), why is the format specifier used %c

, why not %d(or %i)

.

// Example for getchar() in C
#include <stdio.h>
int main()
{
   printf("%c", getchar());
   return 0;
}

      

I know that the character we enter is a character and it is taken by a function getchar()

and we display it with %c

.

But my problem is what actually happens internally getchar()

and printf()

throughout the whole process, where getchar()

is this integer returned, where is it stored and how is the entered character outputted, printf()

what is going on internally printf()

?

I did some research on the implementation printf()

and found out that printf is part C standard library

(also known as libc

) and is a variadic function ( printf ), but I didn't find out what is actually going on inside this function and how it knows the format specifier that it should print a character or int?

Please help me find out the whole detailed process that is going on.

+3


source to share


3 answers


The man page getchar

states the following:

fgetc()

reads the next character from the stream and returns it as unsigned char

passed in int

or EOF at the end of the file or error.

getc()

is equivalent fgetc()

, except that it can be implemented as a macro that evaluates the stream more than once.

getchar()

is equivalent getc(stdin)

.

So let's say you enter a character A

. Assuming your system is using ASCII character representation, this character has an ASCII value of 65. So, in this case, getchar

returns 65 as int

.



This value int

65, returned getchar

, is then passed printf

in as the second argument. The function printf

looks at the format string first and sees the format specifier %c

. The man page for printf

reads as follows regarding %c

:

If there is no modifier l

, the argument is int

converted to                unsigned char

, and the resulting character is written.

So printf

reads the next argument as int

. Since we passed in int

with a value of 65, that's what it reads. This value is then converted to a value unsigned char

. Since it is still enraged with this type, the value is still 65. printf

then prints a character for that value. And since 65 is the ASCII value for a character A

, the character appears A

.

+2


source


(I am assuming your computer has x86-64 processor and is running Linux)

why the format specifier% c is used, why not% d (or% i).

Suppose the corresponding argument (before printf

) was 99 (an int

). If you are using %c

then a letter c

(ASCII code 99) is displayed . If you use %d

or %i

then it is 99

displayed printf

, etc.

printf

as you noticed, is a variation function. It is implemented with variadic primitives such as va_start

and va_end

, which are macros extended to some built-in known to the compiler. How exactly arguments are passed and results are given ( calling convention ) is determined (by processor and OS specific) in an ABI ( Application Binary Interface ) document .

Some implementations of the C standard library printf

(and related functions such as vfprintf

) will end up using putc

or something related.

Please note that the standard I / O functionality (the ones listed in <stdio.h>

) will most likely be provided by some Operating Systems: Three Simple Pieces for more information about the OS.

Quite often, the C standard library uses some kind of calling system to communicate with the operating system kernel . For Linux, they are listed in syscalls (2) , but read Advanced Linux Programming . Write (2) syscall will be used to output some data (but the C standard library is usually buffering, see setvbuf (3) ).



BTW, for Linux / x86-64 both GNU glibc and musl-libc are free software C implementations , and you can look into their source code (most of them are coded in C, with few assemblies to glue the system call).

But my problem is what is actually going on inside getchar () and printf () throughout the whole process, where getchar () returns that integer, where is it stored ...?

The ABI specifies that the result of a return function int

goes through a register %rax

, and getchar

(like any other return function int

) it works that way. See the X86-64 Linux ABI referenced here .

... and how does the character we type appear on the printf () screen, i.e. what happens inside printf ()?

After many layers of software, when the stream stdout

is flushed (for example, by calling fflush (3) , a \n

newline, or exit (3) , including returning from main

in crt0 ), the C standard library will use write (2) syscall. The kernel will process it to show something (but the details are terribly complicated, read the tty demystified first ). In fact, millions of lines of source code are involved (including inside the kernel - read DRM , inside the display server , for example X.Org or Wayland - also some code inside the GPU - insideterminal emulator ). Linux is free software, so in principle you can learn all of this (but it takes more than a lifetime, a typical Linux distribution has about twenty billion lines of source code). See also the OSDev wiki, which gives some practical information, including the native Intel grapĥics (which are the most primitive graphics today).

PS. You have to spend over ten years understanding all the details (and I don't know).

+1


source


To understand that you should read the default promotions .

where getchar () returns this integer where it is stored

C will handle this for you.

how the input character is output printf()

%c

report printf()

printable symbol.

+1


source







All Articles