It is essential that the data types in printf() and scanf() parameter lists match up, in type and number of items, with the conversion specifications in the function format string. The effects of errors are illustrated in the following examples. First an attempt to display an integer using floating-point conversion.
main()
{
printf("The number was %10.5lf\n",2445);
printf("The number was %10.5lf\n",-2445);
}
Which produced the output The number was 0.00000 The number was -NaNThe behaviour of this program may differ on different computers. On a PC using Turbo C, the computer just hung and had to be rebooted. What has gone wrong here is fairly easy to understand. The printf() function, when it saw a floating point conversion specified in the format string, expected a floating point number as the first parameter and attempted to interpret the set of bits it found as if they were a floating point number. In the first case it simply produced a wrong result, in the second case the symbols NaN mean not a number which means that the string of bits representing -2445 cannot be interpreted as a floating point number.
There are also problems with trying to mix the floating point types as the following example illustrates.
main()
{
float x = 4.5;
double xx = 4.5;
long double xxx = 4.5;
printf(" x as a double %10.5lf\n",x);
printf("xxx as a double %10.5lf\n",xxx);
printf(" xx as a float %10.5f\n",xx);
printf("xxx as a float %10.5f\n",xxx);
printf(" x as a long double %10.5Lf\n",x);
printf(" xx as a long double %10.5Lf\n",xx);
}
Producing the following output which has been slightly rearranged to fit it all on one page. Each of the long sequences of digits was actually a single line of output. x as a double 4.50000 xxx as a double -10560771802106750553398 2096423699136116217666493230020800324921 4912735106858866710700289811217622935490 4090954051838156513573918189866268647291 1431518496733949893763566106655226622410 6346315206950304034682546775452344161447 0053554697053546159686477391079668453299 14986496.00000 xx as a float 4.50000 xxx as a float -10560771802106750553398 2096423699136116217666493230020800324921 4912735106858866710700289811217622935490 4090954051838156513573918189866268647291 1431518496733949893763566106655226622410 6346315206950304034682546775452344161447 0053554697053546159686477391079668453299 14986496.00000 Segmentation fault (core dumped)which should be enough to encourage anyone to be careful with type matching when using printf(). The above spectacular results were obtained using the standard compiler on a SUN Sparc station. Other compilers may give up or produce weird results in different ways.
Before the program crashed it produced 4 lines of output. On the first line there was no particular problem and printf() was quite happy to interpret the value of of the float variable x as if it were a double . Actually the value of printf()' s second parameter has been automatically converted from float to double , this is known as function parameter promotion and is part of the ANSI standard. It is discussed later.
When generating the second line of output printf() expected a double value and mis-interpreted the supplied long double bit pattern.
On the third line printf() was expecting a float but knew that all float parameters are promoted to double so correctly interpreted the supplied bit pattern, unfortunately this didn't work when a long double was supplied.
The effects of the fifth executable line were rather different, printf() expected a long double and in trying to get it something went dramatically wrong causing the program to crash. The actual crash shown here was recorded on a Unix system, the message Segmentation fault means that the program attempted to access a part of the computer memory that had been allocated to a different program. It does suggest that code such as
printf("x=%10.5Lf\n",2.5) is likely to cause a disaster. (It did !). The problem is that "2.5" is seen as constant of type double rather than as a constant of type long double . A constant can, of course, be forced to be of a particular type as described earlier. The program
main()
{
printf("x = %10.5Lf\n",2.5L);
}
was perfectly well behaved producing the output x = 2.50000