The scanf() and printf() functions are a nightmare for many beginners in C language. Especially scanf(), which involves the concept of variable addresses. If you forget to write the address operator &, the program often exits abnormally. Why is this?
If you compile and execute the above program and input 2, 3, 4, the program exits abnormally (a return value of non-0 indicates abnormal exit) without giving us a chance to input d and e.
To understand the reason behind this, we need to clarify the concepts of variables, variable names, and addresses.
A variable occupies a certain space in memory, and each variable in C language has a corresponding data type. The data type determines the length of memory space the variable occupies, the encoding format, and the operations that can be performed on it (for more on data types, please refer to the article: C Language Series: How to Understand Variable Types?).
To better understand this, let’s use an analogy.
Suppose Zhang San is a freshman in the computer department, assigned to bed number 3 in room 502 of building 28 in the south area. The storage space of room 502, bed number 3 corresponds to a variable, currently allocated for Zhang San’s use, but after 4 years, the same bed will be assigned to Li Si. Here, 南区28栋502室第3号床位 is equivalent to the variable’s address.
scanf(“%d”, &a) means to read an integer from the screen and place it at the location of a. If you forget to write the address operator and write it as scanf(“%d”, a), it would be problematic. This is equivalent to placing the integer read from the screen at the address pointed to by the value of a. Because the address specified by the value of a is certainly not the address of a itself.
To see where the input number is placed, we can print the values of a, b, c, d, e before input.
At this point, we find the output as follows: a=0, b=1, c=0 (Note: Different runs may yield different results).
This indicates that the statement scanf(“%d%d%d”, a, b, c) is attempting to place the three integers 2, 3, 4 into the memory locations with addresses 0, 1, 0. This is like when Zhang San graduates, he was supposed to assign the newly enrolled Li Si to 南区28栋502室第3号床位, but due to forgetting to write the address operator, he directly assigns Li Si to the principal’s office, replacing the principal. This would cause chaos, leading to an unexpected exit of the program, and it will no longer execute subsequent statements.
To clarify the addresses of a, b, c, we can add printf() statements to print the addresses.
At this point, the program outputs that the addresses of a, b, c are all long integers and differ by 4, because a, b, c are all of int type, each occupying 4 bytes. The addresses of d differ from c and e by 8, because d and e are of double type, each occupying 8 bytes.
At the same time, we also see that the addresses of a, b, c, d, e decrease from large to small. This is because a, b, c, d, e are all defined as local variables within the function. The system uses a stack to store local variables, and the stack grows from high addresses to low addresses.
With this knowledge, we truly understand what it means to add the address operator in scanf().
At this point, the program can correctly input data.
Finally, let’s talk about the sisters of printf() and scanf().
The last f in scanf() and printf() means formatted, which refers to formatted input/output. These two functions read from the display and output to the display, respectively. They each have two sisters:
fscanf() and fprintf(): The f stands for file, meaning reading from a given file / writing to a given file;
sscanf() and sprintf(): The s stands for string, meaning reading from a string / writing to a string.
For more articles on C language:
C Language Common Errors (1): Confusions of Beginners
C Language Common Errors (2)
C Language Series: How to Understand Variable Types?