In most cases, those numbers are "random" values that just happen to be in the stack or in registers depending on the processor. In the olden days, all the parameters to a function were passed on the stack, pushed in reverse order. For printf(), the first parameter, and the last pushed, would be the format string. In your example, the stack would look like:
sp[0] = "%d %d %d"
printf would grab the top of the stack (the format string) and parse it, grabbing additional parameters in higher stack locations, format them according to the format string and output them appropriately.
If you had a well formed printf call, e.g. printf("%d %d %d", 1, 2, 3), then the stack would look like
sp[3] = 3
sp[2] = 2
sp[1] = 1
sp[0] = "%d %d %d"
printf would do what you expect: grab the appropriate stack location for each format specifier and format it appropriately. When you don't pass the other parameters, whatever happens to be in those stack locations are output instead, hence the "random" values.