Why this c program output like this? - c

#include<stdio.h>
main
{
int x[]={1,2,3,4,5};
int i,*j;
j=x;
for(i=0;i<=4;i++)
{
printf("%u",j);
j++;
}
}
output:
65512
65514
65516
65518
65520
But when I change the printf to"
printf("%u",&j[i]);
Output is:
65512
65516
65520
65524
65528
Why the address differ by 2 in first case and 4 in second casee?
What is wrong with just printing j and printing &j[i]?

You get jumps of 4 in the second example because you are incrementing j and offsetting by i! Both of these contribute a difference of 2.
Note also that printf is not type-safe; it is up to you to ensure that the arguments match the format-specifiers. You have specified %u, but you've given it an int *, you should use %p for pointers.

First, just to make it clear, you are printing the pointer j, and not the pointed value, *j
Now, regarding the printed address. In your second example:
for(i=0;i<=4;i++)
{
printf("%u",&j[i]);
j++;
&j[i] equals to (j+i). i is incremented in each iteration, which contributes 2 to the pointer's value, and j is incremented too, which contributes another 2.

Related

Confusion with i++ and i=i+1

Please do help me with explaining the output of my code. Currently I'm an amateur in C. If i++ and i=i+1 are the same things then why such difference in output?
#include <stdio.h>
void main()
{
int i=0;
printf("%d %d %d \n",i++,i,i++);
int j=0;
printf("%d %d %d \n",j=j+1,j,j=j+1);
return 0;
}
output:
1 2 0
2 2 2
Process returned 7 (0x7) execution time : 0.081 s
Press any key to continue.
To understand the logic behind your output, you need to have an idea of Pointer and how it works.
The C language exhibits an undefined behavior (https://en.wikipedia.org/wiki/Undefined_behavior) where you can't predict the way the syntax will work on the execution.
i++ -> increments i, but returns the previous value of i.
++i-> increments i, and returns the new value of i after assignment.
i = i + 1 -> adds 1 to i, writes it to i, and then returns the new value of i after assignment.
Refer this link for more info: https://en.wikipedia.org/wiki/Sequence_point
Based on this principle, the output can be analyzed as below.
int i=0;
printf("%d %d %d \n",i++,i,i++);
Firstly, i=0
it starts execution from the right side i++
First, it assigns the value& the pointer stores 0; then the increment will take place. So, i=1.
In the next step, there is only a variable. So, the pointer doesn't store the value; it only stores the address. Therefore, i=1.
Last step execution is the same as the first step. So, i=2.
Now, it will print the stored value. So, the output is 1 2 0.
Now, let's analyze the second OUTPUT.
In the second output, the expression is j=j+1.
So, first, it executes all the steps and then prints the value.
So, the second output is 2 2 2.
I hope you now got the difference between i++ & i=i+1.

C - Does a variable declared in loop get the memory at same place each time the loop executes?

Please read the code below.
#include <stdio.h>
int main(void)
{
char* a[4];
int i=0;
while(i<3)
{
char b[50];
scanf(" %s",b);//Assume user enters one two three
a[i++]=b;
}
i=0;
while(i<3)
printf(" %s ",a[i++]);//Why does it always print three three three
return 0;
}
Clarify the following:
Is it that b gets allocated same 50 bytes in memory each time so that all the elements of array a point to same 50 bytes and thus we get only three printed three times(i.e. what's entered last)
Since after the completion of while, array b can be removed very well but no it remains there every single time printing only three's. Why?
Is it not at all a coincidence that this code prints only three's when it could print one two three, one three three as well. What's wrong?
I know the question is very wrongly put. Forgive me for that. I am new here.
QUESTION #1:
The variable b is a variable that is strictly local to the
while loop.
Therefore, do not reference via a pointer any memory formerly used by b outside (after) the while loop.
Storage for b will be reallocated 3 times.
At the end of the while loop, b will go out of scope.
QUESTION #2:
After the while loop, a is not a valid pointer anymore
because a was assigned to point to b,
and b has gone out of scope after the while loop.
NEVERTHELESS, the memory allocated to b may still
not have been modified. You cannot predict what the value of dereferencing a will be after the while loop - since a is only assigned based on b.
QUESTION #3:
(Please see #2) The code that is dereferencing a after the while loop is using a stale pointer - I would not rely on the output.
The code in the question exhibits undefined behaviour because the second loop attempts to access the data that was only valid in the first loop. Therefore, there is very little that can usefully be said.
The question title is "does a variable declared in a loop get the same address each time the loop executes". Here's a proof by counter-example that the address of the variables in a loop need not always be the same, even in a single invocation of a non-recursive function.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
srand(time(0));
for (int i = 0; i < 3; i++)
{
int n = rand() % 30 + 5;
char a[n];
for (int j = 0; j < n - 1; j++)
a[j] = rand() % 26 + 'a';
a[n-1] = '\0';
printf("a: %p %2d [%s]\n", (void *)a, n, a);
char b[50+n];
scanf("%s", b);
printf("b: %p %2d [%s]\n", (void *)b, n+50, b);
}
return 0;
}
On a Mac running macOS Sierra 10.12.4 (using GCC 7.1.0), one run of the program (lv83) produced:
$ ./lv83 <<< 'androgynous hermaphrodite pink-floyds-greatest-hits-dark-side-of-the-moon'
a: 0x7fff507e53b0 23 [sngrhgjganmgxvwahshvzt]
b: 0x7fff507e5360 73 [androgynous]
a: 0x7fff507e53c0 9 [wblbvifc]
b: 0x7fff507e5380 59 [hermaphrodite]
a: 0x7fff507e53b0 26 [pqsbfnnuxuldaactiwvjzvifb]
b: 0x7fff507e5360 76 [pink-floyds-greatest-hits-dark-side-of-the-moon]
$
The address at which the two arrays are allocated varies depending on how big they are. By using different formulae for the sizes of the two arrays, the base addresses could be tweaked. It looks as though the compiler rounds the base address of the arrays to a multiple of 16.

Code to print the no of elements in an array gives one less than the no of elements

I've written a code to find the number of elements in an integer array as follows:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int arr[] = {2, 3, 5, 5};
int i;
for(i = 0; i < 4; i++)
{
printf("%d %d\n", &arr[i], arr[i]);
}
printf("%d", &arr[i - 1] - arr);
return 0;
}
The last printf prints 3 as opposed to 4 which is the number of elements in the array. Why does the code print one less than the no of elements in the array?
You pass the wrong format specifier to printf. So whatever output you get in the loop is the result of undefined behavior. To print a pointer correctly and portably you must use the %p specifier and pass a void*:
printf("%p %d\n", (void*)&arr[i], arr[i]);
The reason the last printf prints 3 (even though the format specifier is maybe wrong again), is because that's the offset between the the last cell in the array and the beginning. That's what you calculate, so remember that the last cell is indexed with offset 3.
The result of subtracting two pointers can be captured in the type ptrdiff_t. And to print that you'd need the %td format specifier, if we are to make your code more portable again:
printf("%td", &arr[i-1]-arr);
To calculate the array length, you'd need to subtract a pointer to "one passed the end" element of the array (don't worry, calculating that address is not undefined behavior) and a pointer to the beginning. Applying that to the print statement after your loop
printf("%td", (arr + i) - arr);
Which quite expectantly, is just i (4).
Your last printf need correction for specifiers as in your case the difference in first and last position address can easily fit in int but caan produce undefined behaviour so use td specifier as difference in address is of ptrdiff_t type. The problem is that how you calculate your length of array, keep in mind that indexing is done from zero that is if you have array length of 4, last index would be 3 and
array length according to your code is 3 - 0 = 3
but actually it should be 3 - 0 + 1 = 4
change your outside printf to
printf("%td",&arr[i-1] - arr + 1);
I hope this would help you. Also you printf in your for loop needs correct specifier as you are trying to print the address instead of int.

return statement in c ??? why this function always returning 20?

int akki(int arr[],int m,int n){
int i;
for(i=0;i<m;i++){
if(arr[i]==n)
return i;
}
return 20;
}
void main(){
int i,m,n,arr[10],a;
printf("Enter size of array:");
scanf("%d",&m);
printf("Enter %d elements of array:",m);
for(i=0;i<m;i++){
scanf("%d",arr[i]);
}
printf("Enter element to be searched:");
scanf("%d",&n);
a=akki(arr,m,n);
if(a!=20)
printf("Element found at %d position",a+1);
else
printf("Element not found");
}
IT is Returning 20 or some garbage value..even if condition matches... it is returning value of i.It is linear search function where m is size of array arr and n is element to be searched...
please explain in detail..i am new in c language
thankzzz in advance
You have a problem in your code. Change
scanf("%d",arr[i]);
To
scanf("%d",&arr[i]);
This is done because scanf expects an argument of type int* but you provide argument arr[i] which is of type int. Also add a check that ends the program if user inputs a number which is greater than 10 for the first scanf.
There can be two reasons.
Case 1 [Much likely for _always_]
Simple. Because your if(arr[i]==n) condition is not met, and i<m became false. It came out of for() loop and hence, return 20.
case 2 [Less likely for _always_]
By chance, the value of n is present at the 21st location [index 20] in the input array.
Apart from the coding aspect, did you understand what's the logical purpose of this function? If not, begin with that. It searches for a specific value in an array of given length, and if no element of the array matches that value, it returns 20.
Now analyze your case, based on your input.
EDIT:
After seeing the complete code, as Mr. CoolGuy has pointed out, use
scanf("%d",&arr[i]);
Just for more reference, you can look at Chapter 7.19.6.2, paragraph 12 , %d format specifier, which goes like
... The corresponding argument shall be a pointer to signed integer.
In your code, arr[i] is of type int. What you need is a int *, i.e., &arr[i].

Recursion in C programming Language

I am learning recursion now-a-days. Here are three codes. The first and third is giving me the expected output but the second is not? Can somebody tell me what is just the difference in them.
Code 1:
void tail(int i){
if (i>0) {
printf("%d\n",i);
tail(i-1);
}
}
int main()
{
tail(5);
}
Code 2:
void tail(int i){
if (i>0) {
printf("%d\n",i);
tail(i--);
}
}
int main()
{
tail(5);
}
Code 3:
void tail(int i){
if (i>0) {
printf("%d\n",i);
tail(--i);
}
}
int main()
{
tail(5);
}
output of Code 1:
5
4
3
2
1
output of Code 2:
5
5
5
.
.
. Infinite
output of Code 3:
5
4
3
2
1
Please help me out. I am confused!
Result is as expected
decrement is post decrement so it would first use current value and then decrement. So function gets repeatedly called with current value so infinite loop.
Working fine for me . Similar to first
Of course code number 2 won't. In code number 2 you typed tail(i--); what -- operator (after the variable name) does is first using him in the line you requested and THEN decrease him by one.
Let's say I have the line printf("%d", i--); It'll print i in it's current value and only after printing it, it will be decreased, it first uses I, and then decreases it - same would happen if you would just type:
printf("%d", i);
i--;
About the -- operator BEFORE the variable. It'll first decrease and then do the requested action - so printf("%d", --i); will decrease i by one and then print it.
We all agree code 1 works well, code 2 actually is in an infinite loop BECAUSE you decrease the variable AFTER calling the function - so it decreases in one function only.
Basically, what it does is like:
printf("%d", i); //which is 5
tail(i);//which is still 5
i--; //will never get to this line because we called another function with variable 5
and so on.
About code number 3, it works perfectly, it's like code number 1 (but code number one won't actually decrease the variable, just call the function with the variable-1).
EDIT:
for more information, you can search in this article :)
The 3 have to work. The 2 don't work because i is decremented after been passed to the function.
You should work with pointers in second case. Each time you are passing the same value into recursive function ... first goes function call and after that you have decrement operation. As a result you have the same value (5) in each recursive call.
The second doesn't give you your desired output because you are using post-decrement operator i--.
This means "use i and then decrement i" as opposed to --i which means "decrement i and then use i".
So in your third case, i whose value is 5, gets decremented to 4, and then tail(4) is called.
In the second case, tail(i--) is called, which means call tail(5) and then do i-=1; .
If i-- and --i are given as standalone statements, they are equivalent, for example
for(int i=5;i>0;i--)
is effectively the same as
for(int i=5;i>0;--i)
But in cases such as follows:
int i=5;
int a=i--;
printf("%d %d", i, a);
This gives out put 4 5 whereas
int i=5;
int a=--i;
printf("%d %d", i, a);
will give output 4 4.

Resources