I came across the following code in an MCQ quiz,
#include <stdio.h>
int main()
{
int j =2, k =4;
printf(&j["Programming"], &k["Theory"]);
k = j ^ 3;
if (k == j)
printf(&k["Practical"], "Trytosolve");
else
printf(&j["Problem creation"]);
return 0;
}
where ampersand is used in the beginning itself and outside the quotes ("") of printf statement. I am only aware of the traditional use of printf statement and its format specifiers.
I tried to run this code, and it showed no error but this warning:
format not a string literal and no format arguments
and the following output
ogrammingoblem creation
(this was one of the options in multiple choices)
I tried to search for such use, but could not find. Can someone explain this use of & and square brackets?
Because I hate answers in the form of comments I will spell it our here again in a bit more detail:
Say we have an array a
and a variable i
of integral type, then a[i]
is equivalent to *(a + i)
, i.e. we can obtain the i
th element of a
by decaying a
into a pointer to its first element, incrementing that pointer by i
and dereferencing the result. This it true because arrays occupy contiguous addresses in memory.
Now, as it turns out, i[a]
is also equivalent to a[i]
, this is more of a "trick" that nobody (to my knowledge) would ever use in production. It's sort of intuitively justifiable that this would be the case because a[i] == *(a + i) == *(i + a) == i[a]
.
So then, &j["Programming"] == &(*(j + "Programming"))
. And because dereferencing a pointer and then taking it's address is a noop, this is j + "Programming" == "Programming" + j == "ogramming"
, because strings are just arrays of characters.
Same for the other branch, which is executed because 2 ^ 3 == 1 != 2
.
Maybe this example program will show you the math behind the scenes:
#include <stdio.h>
int main(void)
{
int j=2, k=4;
char *p1 = "Programming";
// Print the address of j
printf("&j = %p\n", &j);
printf("\n");
printf("Pointer arithmetic\n");
// Print the address of "Programming"
printf("p1 = %p\n", p1);
// Print the value of j
printf("j = %8d\n", j);
// Print the result of the pointer computation
printf("&j[\"%s\"] = %p\n", p1, &j[p1]);
// Print the result of the equivalent pointer computation
printf("p1 + j = %p\n", p1 + j);
printf("\n");
printf("Print strings\n");
// Print "Programming" after skipping the first two letters
printf("&j[\"%s\"] = %s\n", p1, &j[p1]);
// Print "Programming" after skipping the first two letters
printf("p1 + j = %s\n", p1 + j);
return 0;
}
Output
&j = 0x7fffb3325aa8
Pointer arithmetic
p1 = 0x4006e4
j = 2
&j["Programming"] = 0x4006e6
p1 + j = 0x4006e6
Print strings
&j["Programming"] = ogramming
p1 + j = ogramming
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With