0

I was wondering why is there a necessity writing %f on variable, and f after the number itself?. I understand the need to write f after a number if I want to be specific with the machine, but why do I need to do so when I have declared on the same line that the variable is f?

Sunderam Dubey
  • 1
  • 11
  • 20
  • 40
DGR
  • 422
  • 1
  • 4
  • 14

1 Answers1

1

The f after a number is to make it a float instead of a double. In C, 3.14 is a double, whereas 3.14f is a float. Similarly, you can append u and l to make numbers unsigned and/or or long; e.g., 42U is an unsigned int, 42L is a long, 42UL is an unsigned long, and 42ULL is an unsigned long long.

The %f is a format specifier to tell the function what the type of the variable is. C doesn't really have native type introspection, and printf isn't magic. The signature looks like:

int printf(const char *format, ...);

It has no idea what you're passing unless you specify it in the format string. You should also keep in mind that there is no type safety for variadic functions; you can pass anything you want. For example, while printf("%s", 1729); is likely to cause a crash, it is technically valid code at the language level, and historically compilers have accepted such code without question. These days many compilers are capable of making sure format strings match what you actually pass them, but that's an extension, not part of C itself.

nemequ
  • 16,623
  • 1
  • 43
  • 62
  • 1
    `printf("%s", 1729);` is not perfectly acceptable; the argument must have type `char *`. This causes undefined behaviour and the compiler may or may not give an error. – M.M Jun 01 '22 at 04:07
  • I phrased that badly, I'll try to clear that up a bit, thanks. That said, what you wrote isn't technically true either… If `sizeof(void*) == `sizeof(int)`, there could very well be a valid string stored at the address 1729. Since you can use `char*` to read data at any address, whether you trigger UB actually depends on what data is actually stored at the address 1729... if, for example, there is a null byte there is no undefined behavior. – nemequ Jun 06 '22 at 18:13
  • It's nothing to do with objects at addresses; `1729` has type `int`, and the argument corresponding to `%s` must have type `char *` . Not "may have some other type that is the same size as `char *`". – M.M Jun 06 '22 at 21:12