I was working with some of the interview questions when I found this code.
#include<stdio.h>
int main()
{
short int a=5;
printf("%d"+1,a); //does not give compiler error
return 0;
}
It prints the following:
d
I am unable to understand how the printf function works here.
Let's look at the first argument to the printf() call.
"%d" + 1
This points to the same thing as ptr does in the following code.
char *ptr = "%d";
ptr = ptr + 1;
So, what does it mean to increment a pointer? Well, we advance the pointer sizeof(*ptr) * 1 bytes forward.
So, in memory we have:
%d\0
^^
||
|This is where ("%d" + 1) points to.
This is where ("%d") points to.
So, your code is more or less functionally equivalent to doing:
short int a = 5;
printf("d", a);
Which will evaluate and then ignore the extra function argument and print d.
One more thing: You're very close to causing undefined behavior in that code. printf("%d", a) is using the wrong format string. The correct format string for a short int is "%hd".
You can find a full table of format strings here.
"%d" + 1 does pointer arithmetic, the compiler sees it as "d", so
printf("%d"+1,a);
becomes:
printf("d", a);
You can see why it outputs d in your compiler.
As #sharth points out in the comment, the extra argument a here is evaluated and discarded.
This is my answer based off #DCoder 's comment. "%d" is a pointer to the first character of the two character array %d. Incrementing this by one gives a pointer to d. The fact that there is a second argument now does not matter as the result of the expression "%d"+1 is simply the character d. If you try adding 0 your output is 5 as expected. If you try adding 2, there is no output as there is only "" is being passed to printf.
In this case printf("%d"+1,a); = printf("d",a).
You are specifying printf to print from +1 position which is "d", so printf will simply print d on screen.
Related
The output of the following program is _________
#include <string.h>
int main()
{
char ch[]="abc",x[3][4];
int i;
for(i=0;i<3;i++)
strcpy(x[i],ch);
for(i=0;i<3;i++)
printf("%s",&x[i][i]);
printf("\n");
}
The answer is abcbcc, but I think the answer should be abc.
strcpy() is used to copy the following to the previous, so the second row of abc is also the third row of abc in the first row array.
a b c
a b c
a b c
Then output diagonal.
Another puzzle: Why is there a & in printf("%s",&x[i][i])?
I thought it would be printf("%s",x[i][i]).
The answer is abcbcc, but I think the answer should be abc.
The answer is correct.
for(i=0;i<3;i++)
printf("%s",&x[i][i]);
printf("\n");
On the first iteration, the value of i is 0.
So the call of printf() is:
printf("%s",&x[0][0]);
which prints abc.
i is then incremented, and the second iteration prints bc, and the third then prints c.
And because you didn't print a newline, the output of all 3 iterations was concatenated.
Why is there a & in printf("%s",&x[i][i])? I thought it would be
printf("%s",x[i][i]).
Because the %s format specifier expects a null-terminated string. And x[i][i] evaluates to a char. Mismatching the types and their format specifiers will lead to undefined behaviour.
void main()
{
printf("Adi%d"+2,3);
}
output= i3
This printf statement worked, but how the statement worked ?
printf("Adi%d"+2,3);
"Adi%d" - is interpreted as start of the address of the memory where the string literal "Adi%d" is stored. When you add 2 to it, it became address of memory where string "i%d" is stored. So basically you passed to printf string: "i%d". Then %d and printf came into play replacing %d with 3, hence the output i3.
Its part of pointer to character, nothing to do with printf, "Adi" + 2 will make it read from position 0 + 2 = 2 that will be i
int main()
{
char* a = "Adi" + 2;
printf(a); // output i
}
the code is like this:
char c;
scanf("%d", &c);
inputting 3...
My guess is that when 3 is inputted, it is as type int;
and then type-demoted to char and assigned to c;
I print the value of c in specifier %d yielding 3, seems to be as expected;
but printing the value of c with specifier %c yields --a blank-- on the terminal;this is one question...(1);
to test more I furthermore declare a variable ch with type char and initialized it like this:
char ch = 1;
and the test is like this:
(i&j)? printf("yes") : printf("no");
and the result is "no"
I print out the value of i&j, and it is 0
but 1&3 should be 1? this is another question....(2);
my question is (1) and (2)
You're actually invoking undefined behavior doing that.
By using the format string %d, you're telling scanf to expect an int* as a parameter and you're passing it a pointer to a single character. Remember that scanf has no further type information on what you're passing it than what you're putting in the format string.
This will result in scanf attempting to write an int sized value to memory at an address that points to a char sized reservation, potentially (and for most architectures) writing out of bounds.
After invoking UB, all bets are off on your further calculations.
Suppose that scanf() were not a varargs-function, but a plain ordinary function taking a pointer-to-int as the 2nd argument:
int noscanf(char *format, int *ptr)
{
*ptr = 42;
return 1;
}
int main(void)
{
char ch;
int rc;
// This should *at least* give a warning ...
rc = noscanf("Haha!" , &ch);
return 0;
}
Now, scanf() is a varargs function. The only way for scanf() to determine the type of the (pointer) arguments is by inspecting the format string. And a %d means : the next argument is supposed to be a pointer to int. So scanf can happily write sizeof(int) bytes to *ptr.
I can't see a variable jthere. So i&j will be 0. And yes, if i == 1 and j == 3 then i & j == 1.
(i&j)? printf("yes") : printf("no");
statement gives the output yes,for i=1 and j=3.
And for (1) question ASCII 3 is for STX char which is not printable.
This code:
char arr1[20] = "fedcba";
char *ptr;
ptr = &arr1[2];
puts(arr1);
printf("%d\n",*arr1 - *ptr);
printf("%d\n",arr1 - ptr);
I understand that the first printing puts the string.
printf I - what is supposed to print? It says * arr1 - * ptr?
printf II - What is the difference between one and two?
The first prints the difference between 2 chars:
The second prints the difference between 2 pointers.
*arr1 dereferences a char* and returns the first character, which is 'f'.
ptr = &arr1[2]; will make ptr point to "dcba". It takes the address of the third character in arr1. *ptr returns 'd'.
So the first printf returns the difference between characters f and d - which is 2.
The second one is the difference between the two pointers. It's legal since they both point inside the same character array. It's the same as arr1 - &arr[2] which will most likely be -2, since arrays are stored continuously in memory.
printf("%d\n",*arr1 - *ptr);
This prints the result of the first character of arr1 minus the first character of ptr.
Here is clearer version that does the same thing: printf("%d\n",arr1[0] - ptr[0]);
printf("%d\n",arr1 - ptr);
This prints the pointer difference between arr1 and ptr, which is 2.
Essentially the property holds that: (a[x] - a) is equivalent to x
Just add these two lines to your program for better understanding...
printf("\n%d AND %d... %c",arr1, *arr1, *arr1);
printf("\n%d AND %d... %c",ptr, *ptr, ptr[0] ); //ptr[0] == *ptr
Hope this helps...
#include<stdio.h>
int main(void)
{
int a=5;
printf("%d"+1,a);
}
Output: d.
I didn't get how the output is coming: d ?
You passed as first argument of printf "%d"+1; "%d" is actually seen as a const char * that points to a memory location where %d is stored. As with any pointer, if you increment it by one, the result will point to the following element, which, in this case, will be d.
a is not used, but this should not be a problem since in general (I don't know if it's standard-mandated Edit: yes it is, see bottom) the stack cleanup responsibility for variadic functions is up to the caller (at least, cdecl does it that way, this however may or may not be UB, I don't know*).
You can see it easier this way:
#include<stdio.h>
int main(void)
{
int a=5;
const char * str="%d";
printf(str + 1, a);
}
str ---------+
|
V
+----+----+----+
| % | d | \0 |
+----+----+----+
str + 1 ----------+
|
V
+----+----+----+
| % | d | \0 |
+----+----+----+
Thus, ("%d"+1) (which is "d") is interpreted as the format string, and printf, not finding any %, will simply print it as it is. If you wanted instead to print the value of a plus 1, you should have done
printf("%d", a+1);
Edit:
* ok, it's not UB, at least for the C99 standard (§7.19.6.1.2) it's ok to have unused parameters in fprintf:
If the format is exhausted while arguments remain, the excess arguments are
evaluated (as always) but are otherwise ignored.
and printf is defined to have the same behavior at §7.19.6.3.2
The printf function is equivalent to fprintf with the argument stdout interposed
before the arguments to printf.
String literals are pointers. Advancing the pointer to "%d" by 1 results in "d". The argument is discarded.
You should do printf("%d", a+1). "%d" + 1 is a pointer to "d" inside an array of char ({'%','d','\0'}).
Because of +1. If you want to increment a do: printf("%d", a + 1); instead.
Suppose you had:
char x[] = "%d";
What do you expect
printf(x + 1, a);
to print?
Hint: t.c:5: warning: too many arguments for format
"%d" is String constant, it will be stored in the char[] in the memory. During runtime, "%d" returns the starting location of the char[]. Increasing character array pointer by one, will point to the next character. Hence "d" alone is passed to the printf function. so the output is "d"