3.1 printf() and scanf()
printf() writes formatted output to the console; scanf() reads formatted input from the keyboard into variables. scanf() requires the address-of operator (&) for normal variables so it can write directly into that memory location — this is a very common source of bugs for beginners who forget the &.
How scanf() interacts with memory:
- In C, function arguments are passed by value (copy). To allow
scanf()to modify the caller's variable, you must provide the memory address where the entered value should be stored using the&operator. - Forgetting the
&inscanf("%d", age)passes the current uninitialized value ofageas an arbitrary memory address, causing illegal memory writes and immediate segmentation faults (crashes). - Strings (character arrays like
char name[50];) already decay to memory addresses, soscanf("%s", name)does not use an explicit&.
int age;
printf("Enter age: ");
scanf("%d", &age); // &age = address of age
printf("You are %d years old
", age);
3.2 Format Specifiers
Format specifiers tell printf/scanf how to interpret the bytes of a variable: %d/%i for int, %f for float, %lf for double (in scanf), %c for char, %s for strings, %u for unsigned int, %x for hexadecimal, %p for pointers. Using the wrong specifier for a type is undefined behaviour.
| Specifier | Target Data Type | Usage Details |
|---|---|---|
%d or %i | int | Signed decimal integer |
%f | float | Standard 4-byte decimal floating point |
%lf | double | Long float / double precision (mandatory in scanf) |
%c | char | Single character |
%s | char[] / string | Sequence of characters terminated by whitespace |
%u | unsigned int | Non-negative unsigned decimal integer |
%x / %X | int in hex | Hexadecimal representation (lowercase/uppercase) |
%p | void* / pointer | Hexadecimal memory address prefixed by 0x |
3.3 Character I/O: getchar(), putchar(), gets()/fgets()
getchar() reads a single character from input; putchar() writes a single character. For whole lines, gets() (unsafe, removed from modern C) has been replaced by fgets(), which takes a buffer size and prevents overflow — always prefer fgets() over gets().
getchar()&putchar(): Read and output one character at a time from stdin/stdout.getchar()returns anintso it can capture the special EOF (End-Of-File) marker (-1).- Why
gets()was abolished:gets()had no parameter to bound user input length. If a user entered more characters than the destination array size, it silently overflowed the buffer, overwriting the return address on the call stack — a notorious vector for buffer overflow exploits. - Safe Alternative
fgets():fgets(buffer, sizeof(buffer), stdin)reads up tosizeof(buffer) - 1characters and automatically appends the null terminator