Chuck Dries Chuck Dries - 3 months ago 11
C Question

Why do I use a star for pointers when printing chars but not strings in C?

Alright I've got two questions, both based on the same snippet of sample code provided by my professor:

char arr[3][3] = {
{ '0', '1', '2' },
{ '3', '4', '5' },
{ '6', '7', '\0' }
char* base = &arr[0][0], *a = &arr[0][0];
a = base + 5;
printf("base=%d a=%d", base, a);
printf("*a = %c ", *a);
a = base + 3;
printf("row = %s", a); // HERE!

So in the line I marked, we reference a instead of *a. This is what I don't understand. Isn't
a number? I understand that a string knows to just go ham on an array of characters until it hits a null terminator, but I don't understand why you don't need the star. Is a not just some long ass number? Does formatting it with %s make it know to follow the pointer, and if so, why doesn't %c do the same? Why does using the star when trying to print with %s cause an exception?

qxz qxz

The different format specifiers tell printf how to interpret the argument:

  • %d treats it as a normal integer. Passing it a pointer (a) results in undefined behavior, but is likely to print part of the pointer's address (a large number)
  • to properly print the address of a pointer, use %p instead of %d.
  • %c treats it as a character (but still takes an int; char is implicitly converted). Your code passes *a, which is indeed a character: the char that a points to.
  • %s treats it as a pointer to the beginning of a null-terminated string of chars. Your code passes a, which is that: a pointer-to-char. It will follow the pointer along, printing characters until it hits \0.

So the type of the expression a is pointer-to-char, while *a is char. If you use a char with %s, printf will try to use it as a pointer. Since this "points to" a memory location between 0x00 and 0xFF, it will give you a segmentation fault for invalid memory access.