Pointer in C, don't understand how they got this result - c

here is code snippet
void F (int a, int *b)
{
a = 7 ;
*b = a ;
b = &a ;
*b = 4 ;
printf("%d, %d\n", a, *b) ;
}
int main()
{
int m = 3, n = 5;
F(m, &n) ;
printf("%d, %d\n", m, n) ;
return 0;
}
answer
4 4
3 7
I see how 4 4 was computed, I don't get how they got 3 7 (I do understand how 3 is computed, it is not changed since it was not passed by reference)
Thanks !

I've annotated the F function with comments to explain what's going on:
a = 7 ; // a is now 7
*b = a ; // b points to n, so n is now 7
b = &a ; // b now points to a and no longer to n
*b = 4 ; // a is now 4. n is unaffected

At the start of main, we have
m=3 n=5 // int m = 3, n = 5;
then we call F(m, &n), passing m by value, and n by pointer
such that
m = 3 n = 5
a = 3 b->n // F(m, &n);
Now, inside F(), we assign 7 to a:
m = 3 n = 5
a = 7 b->n // a = 7
then we assign a (=7) to the memory address pointed by b (->n)
m = 3 n = 7
a = 7 b->n // *b = a;
next we change b, so that now b points to a:
m = 3 n = 7
a = 7 b->a // b = &a;
and then we assign 4 to the memory address pointed by b (->a)
m = 3 n = 7
a = 4 b->a // *b = 4;
printing a (=4) and *b (->a =4)
and printing m (=3) and n (=7) outside the function

Take a close look at this line
b = &a ;
*b = 4 ;
b gets the reference of a (it's memory address). When you now access *b it points to the memory of the variable a, not to n anymore

Quite subtle indeed. :)
In F a lot of nonsense happens: whichever value is passed via a, it's discarded, and instead 7 is assigned to it. Then, the value of a (which is 7) is assigned to the variable to which b points (which is n, so it's here that n becomes 7).
At the next line, the object to which b points is changed, so that b now points to the local parameter a, and at the following line the object pointed by b (=>a) is set to 4.
Thus, now we have a that is 4, b that points to a (=>so *b==4, since *b==a), m is still 3 (it was passed by value, so it couldn't have been changed by F) and n was set to 7.
By the way, this is exactly the mess you shouldn't to at all in your applications to avoid confusing any people who have the disgrace to work on them. :)

Related

Understanding the math of loops in C

I have these three codes, which do work, but they're not printing what I expected them to print. I don't think I properly understand the math/precedence here and was wondering if someone could help me comprehend.
CODE A
int a;
int b = 1;
for (a = 1; a < b + 4; b++, a = b * 2)
printf("%i\n", a);
I expected it to print out 4, 5. but it's 3, 9. I understand that's correct -- but why?
CODE B.
int a = 5;
int b = 0;
while (a > 3)
{
b += a;
--a;
}
printf("%i, %i\n", a, b);
Admittedly I struggled figuring out the math. It prints out 3, 9 --- but I don't get why.
CODE C.
int a;
int b;
for (a = 7, b = 2; b < a; a++)
b += a - 2;
printf("%d, %d\n", b, a);
This prints out 13, 9 but I got 11, 7.
Let's step through the first loop:
for (a = 1; a < b + 4; b++, a = b * 2)
printf("%i\n", a);
First, we execute the initialization statement, which gives us a=1 and b=1 (b was set earlier in the code).
We execute the test expression (a < b + 4, which is 1 < 1 + 4), which is true, so we continue
We execute the loop body. We haven't performed any operations on a yet, so a is still equal to 1 so our output is:
1
Now execute the update expression, b++, a = b * 2. This
increments b (giving us b=2), and then sets a = b * 2, so a = 4.
We execute the test expression, and 4 < 2 + 4, so we continue.
We execute the loop body, which gives us as output:
4
We execute the update expression. We increment b, giving us
b=3, and then set a = b * 2, giving us a = 6.
We execute the test expression, and 6 < 3 + 4, so we continue.
We execute the loop body, giving us as output:
6
We execute the update expression. We increment b, giving us
b=4, and then set a = b * 2, giving us a = 8.
We execute the test expression. 8 < 4 + 4 is false, so we exit
the loop.
You can walk through a similar process for the other loops.
What might be part of the source of confusion is that a for loop in c will execute until the first semicolon found in the source code if there is not a surrounding pair { ... } to delineate several lines of code. For code A, the stuff after the second semicolon in the for loop is executed on every iteration and the printf statement is executed on every iteration too. In the last code snippet, code C. The printf is only executed after all the iterations of the for loop have completed. The same is true of the while loop in code snippet B, the printf executes after the while terminates. The while loop use of {...} delimiting characters makes this more obvious to the reader while the for loops do not.
Of course you still need to work through the calculations themselves too-which are also fairly tricky.
A for loop consists of the following structure:
for ( init; condition; increment ) {
statement(s);
}
As for how this actually executes, it is exactly equivalent to the following:
init;
while(condition) {
statement(s);
increment;
}
So, if we have the following code (CODE A):
int a;
int b = 1;
for (a = 1; a < b + 4; b++, a = b * 2)
printf("%i\n", a);
That means:
init: a = 1
condition: a < b + 4
increment: b++, a = b * 2
statement(s): printf("%i\n", a);
We can translate that into a while loop by substituting:
int a;
int b=1;
a = 1;
while(a < b + 4) {
printf("%i\n", a);
b++, a = b * 2;
}
Now, we can trace the execution step by step to see what's happening.
First loop:
1. b=1
2. a=1
3. a < b + 4
1 < 1 + 4
1 < 5
true
4. Output: 1
5. b++
b = b + 1
= 1 + 1
= 2
6. a = b*2
= 2*2
= 4
Second loop:
1. a < b + 4
4 < 2 + 4
4 < 6
true
2. Output: 4
3. b++
b = b + 1
= 2 + 1
= 3
4. a = b*2
= 3*2
= 6
Third loop:
1. a < b + 4
6 < 3 + 4
6 < 7
true
2. Output: 6
3. b++
b = b + 1
= 3 + 1
= 4
4. a = b*2
= 4*2
= 8
Fourth loop:
1. a < b + 4
8 < 4 + 4
8 < 8
false
2. End
Looking at Code A:
int a;
int b = 1;
for (a = 1; a < b + 4; b++, a = b * 2)
printf("%i\n", a);
b is set to 1;
a is set to 1;
a (1) is less than b + 4 (5), so the loop executes the printf(), printing 1;
b is incremented to 2; a is set to 4 (b * 2);
a (4) is less than b + 4 (6), so the loop executes the printf(), printing 4;
b is incremented to 3; a is set to 6 (b * 2);
a (6) is less than b + 4 (7), so the loop executes the printf(), printing 6;
b is incremented to 4; a is set to 8 (b * 2);
a (8) is not less than b + 4 (8 too), so the loop terminates.
You can apply a similar technique to the other cases.
Looking at Code B:
int a = 5;
int b = 0;
while (a > 3)
{
b += a;
--a;
}
printf("%i, %i\n", a, b);
a is set to 5;
b is set to 0;
a (5) is greater than 3 so the loop body executes;
b (0) has a (5) added to it, so it becomes 5;
a is decremented, so it becomes 4;
a (4) is greater than 3 so the loop body executes;
b (5) has a (4) added to it, so it becomes 9;
a is decremented, so it becomes 3;
a (3) is not greater than 3 so the loop terminates;
The printf() statement prints a then b, so the result is 3, 9.
Looking at Code C:
int a;
int b;
for (a = 7, b = 2; b < a; a++)
b += a - 2;
printf("%d, %d\n", b, a);
a is set to 7;
b is set to 2;
b (2) is less than a (7), so the loop executes the assignment operator;
a - 2 is 5 so b is set to 7 (2 + 5);
a is incremented to 8;
b (7) is less than a (8), so the loop executes the assignment operator;
a - 2 is 6, so b is set to 13 (7 + 6);
a is incremented to 9;
b (13) is not less than a (9), so the loop terminates;
The printf() statement prints b then a, so the result is 13, 9.

In the given example for finding the value " pp-p" on line 5 why the values are divided by 2 in the explanation?

#include<stdio.h>
void main ()
{
int a[10] = {100, 206, 300, 409, 509, 601}; //Line 1 array declared
int *p[] = {a, a+1, a+2, a+3, a+4, a+5}; //Line 2 pointer to the array
int **pp = p; //Line 3 double pointer initialized
pp++; // Line 4 double pointer incremented
printf("%d %d %d\n",pp-p,*pp - a,**pp); // Line 5
*pp++; // Line 6
printf("%d %d %d\n",pp-p,*pp - a,**pp); // Line 7
++*pp; // Line 8
printf("%d %d %d\n",pp-p,*pp - a,**pp); // Line 9
++**pp; // Line 10
printf("%d %d %d\n",pp-p,*pp - a,**pp); // Line 11
}
/* Line number 5 contains an expression which prints three values, i.e., pp - p, *pp - a, **pp. Let's calculate them each one of them.
pp = 302, p = 300 => pp-p = (302-300)/2 => pp-p = 1, i.e., 1 will be printed.
pp = 302, *pp = 202, a = 200 => *pp - a = 202 - 200 = 2/2 = 1, i.e., 1 will be printed.
pp = 302, *pp = 202, *(*pp) = 206, i.e., 206 will be printed. */
What you see there is basic pointer arithmetics. That's just how adding and substracting to and from pointers works in C.
Let's start with an array:
int a[10] = {100, 206, 300, 409, 509, 601};
You can access these elements using array syntax:
a[0] = xy;
a[2] = 1;
This is identical to the following syntax using pointer arithmetics:
*a = xy;
*(a+2) = 1;
You can see that you can add an index n to access the nth element of your array. For obvious reasons this does not just add the index to the address. Each element has a certain size.
Therefore the rules for arithmetics tell us that the address is adjusted by n bytes, but by n data objects.
How many bytes we need to add/subtract is derived from the size of each object.
For a it is sizeof(int), for p it is sizeof(int*).
The result of adding a number to a pointer is a pointer again. Using normal math rules, you can subtract 2 pointers (if they point into the same array) and get a number which is (again) the number of objects, not the number of bytes.
This means &a[2] - &a[1] == 1. This is true for any size.
Now we look at your code:
int **pp = p;
pp++;
This is same as pp = &p[1] which is pp=p+1. And hence *pp==p[1]==a+1
Now print it:
printf("%d %d %d\n",pp-p,*pp - a,**pp);
Apply the rules from above:
pp-p == p+1 - p == 1
*pp-a == p[1] - a == a+1 - 1 == 1
**pp == *p[1] == *(a+1) == a[1] = 206
==> 1 1 206

Wrong value being printed by printf

I have this piece of C code
#include <stdio.h>
int main(){
int i , j , m , A[5]={0,1,15,25,20};
i = ++A[1];
printf("%d:\n",i);
j = A[1]++;
printf("%d:\n",j);
m = A[i++];
printf("%d:\n",m);
printf("%d %d %d",i,j,m);
return 0;
}
and It's output is
2:
2:
15:
3 2 15
Shouldn't the printf print the values as 2 , 2, 15 but why is it printing 3 , 2, 15
P.S : I really didn't abuse this code , someone else did (my professor perhaps) and I'm just learning C .
The line
m = A[i++];
will increment the variable i in-place after it gets the cooresponding value from the array A.
i is incremented as a part of below statement
m = A[i++];
Lets see what we got here..
int i , j , m , A[5]={0,1,15,25,20};
i = ++A[1]; // takes the value of A[1], increment it by 1 and assign it to i. now i = 2, A[1] = 2
printf("%d:\n",i);
j = A[1]++; // takes the value of A[1](which is 2), assign it to j and increment the value of A[1] by 1. now j = 2, A[1] = 3
printf("%d:\n",j);
//remember the value of i? its 2
m = A[i++]; // takes the value of A[2](which is 15), assign it to m and increment the value of i by 1. now m = 15, i = 3
printf("%d:\n",m);
printf("%d %d %d",i,j,m); // Hola! we solve the mystery of bermuda triangle :)
return 0;
m = A[i++];
this code assign A[2] which is 15 to the variable m ,and then +1 to the current value of i to become 3.

Unexpected Output involving array values with post and pre-increment

Shouldn't the output of following program be -
2 3 20
instead it is showing
3 2 15
Can anyone explain the reason behind this?
#include<stdio.h>
main()
{
int a[5] = {5,1,15,20,25};
int i,j,m;
i = ++a[1];
j = a[1]++;
m = a[i++];
printf("%d %d %d",i,j,m);
}
3 2 15
is the correct output.
i is 3, because i became 2 in i = ++a[1]; for pre-increment and then it got post-incremented in m = a[i++];
j is 2, because j = a[1]++;, no changes afterwards.
m is 15 because m = a[i++]; i is being post-incremented, the old value of i (which is 2) is used in indexing and the post-increment on i is sequenced after the evaluation of the = statement.
Having said that, the recommended signature of main() is int main(int argc, char *argv[]) or at least, int main(void).
At this point, values of variables are:
a = {5,1,15,20,25};
i = uninitialized
j = uninitialized
m = uninitialized
Now,
i = ++a[1];
Gets the value of a[i] which is 1, increments it and it becomes 2, and then, it is stored in i.
At this point, values of variables are:
a = {5,2,15,20,25};
i = 2
j = uninitialized
m = uninitialized
Next,
j = a[1]++;
Gets the value in a[1] which is 2 (since it was incremented in the previous statement), stores this value in j and then, increments the value stored in a[1].
At this point, values of variables are:
a = {5,3,15,20,25};
i = 2
j = 2
m = uninitialized
Then,
m = a[i++];
Gets the value in a[i](a[2] since i is currently 2) which is 15 and this value is stored in m. Then, i is incremented.
At this point, values of variables are:
a = {5,3,15,20,25};
i = 3
j = 2
m = 15
3 2 15 is correct
#include<stdio.h>
main()
{
int a[5] = {5,1,15,20,25};
int i,j,m;
i = ++a[1];
j = a[1]++;
m = a[i++];
printf("%d %d %d",i,j,m);
}
Now lets go line by line assume i , j , m equals 0 {better to initialize}
from line 3 , i = ++a[1];
i = 2 as (++ pre increment , change then use , and a[1] = 1 so , i = 2)
from line 4, j = a[1]++;
j = 2 as (++ here is post increment , use then change , a[1] becomes 3 but j is equals to 2)
from line 5, m = a[i++];
i = 2 by line 3 , here ++ post increment then i will increment to 3 but a[2] will be used .
Hence i = 3 , j = 2 , m = 15
Hope you got it ..........

How to rotate a matrix 90 degrees without using any extra space? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Algorithm to rotate an image 90 degrees in place? (No extra memory)
By saying 90 degrees i mean to say if:
A = {1,2,3,
4,5,6,
7,8,9}
then after 90 degree rotation A becomes:
A = {7,4,1,
8,5,2,
9,6,3}
Transpose and interchange rows or columns (depends whether you want to rotate left or right).
e. g.
1) original matrix
1 2 3
4 5 6
7 8 9
2) transpose
1 4 7
2 5 8
3 6 9
3-a) change rows to rotate left
3 6 9
2 5 8
1 4 7
3-b) or change columns to rotate right
7 4 1
8 5 2
9 6 3
All these operations can be done without allocating memory.
let a be an nxn array 0 based indexing
f = floor(n/2)
c = ceil(n/2)
for x = 0 to f - 1
for y = 0 to c - 1
temp = a[x,y]
a[x,y] = a[y,n-1-x]
a[y,n-1-x] = a[n-1-x,n-1-y]
a[n-1-x,n-1-y] = a[n-1-y,x]
a[n-1-y,x] = temp
Edit If you want to avoid using temp, this works (it also rotates in the correct direction) this time in python.
def rot2(a):
n = len(a)
c = (n+1) / 2
f = n / 2
for x in range(c):
for y in range(f):
a[x][y] = a[x][y] ^ a[n-1-y][x]
a[n-1-y][x] = a[x][y] ^ a[n-1-y][x]
a[x][y] = a[x][y] ^ a[n-1-y][x]
a[n-1-y][x] = a[n-1-y][x] ^ a[n-1-x][n-1-y]
a[n-1-x][n-1-y] = a[n-1-y][x] ^ a[n-1-x][n-1-y]
a[n-1-y][x] = a[n-1-y][x] ^ a[n-1-x][n-1-y]
a[n-1-x][n-1-y] = a[n-1-x][n-1-y]^a[y][n-1-x]
a[y][n-1-x] = a[n-1-x][n-1-y]^a[y][n-1-x]
a[n-1-x][n-1-y] = a[n-1-x][n-1-y]^a[y][n-1-x]
Note: This only works for matrices of integers.
The algorithm is to rotate each "ring", working from the outermost to the innermost.
AAAAA
ABBBA
ABCBA
ABBBA
AAAAA
The algorithm would rotate all the A's first, then B's then C's. Rotating a ring requires moving 4 values at once.
The index i ranges from 0..ring-width-1, e.g. for A the width is 5.
(i,0) -> temp
(0, N-i-1) -> (i, 0)
(N-i-1, N-1) -> (0, N-i-1)
(N-1, i) -> (N-i-1, N-1)
temp -> (N-1, i)
This is then repeated for each successive inner ring, offsetting the co-ordinates reducing the ring width by 2.
[Another answer has appeared with the code, so I'll not repeat that.]
Complete implementation in C using the method described by #Narek above
#include <stdio.h>
int n;
unsigned int arr[100][100];
void rotate() {
int i,j,temp;
for(i=0; i<n; i++) {
for(j=i; j<n; j++) {
if(i!=j) {
arr[i][j]^=arr[j][i];
arr[j][i]^=arr[i][j];
arr[i][j]^=arr[j][i];
}
}
}
for(i=0; i<n/2; i++) {
for(j=0; j<n; j++) {
arr[j][i]^=arr[j][n-1-i];
arr[j][n-1-i]^=arr[j][i];
arr[j][i]^=arr[j][n-1-i];
}
}
}
void display(){
int i,j;
for(i=0;i<n;i++) {
for(j=0;j<n;j++) {
printf("%d",arr[i][j]);}
printf("%s","\n");
}
}
int main(int argc, char *argv[]){
int i,j;
printf("%s","Enter size of matrix:");
scanf("%d",&n);
printf("%s","Enter matrix elements\n");
for(i=0;i<n;i++) {
for(j=0;j<n;j++) {
scanf("%d",&arr[i][j]);
}
}
rotate();
display();
return 0;
}
See this article for in-place matrix transposition; also google for "in-place matrix transposition". It can be easily adapted to perform rotation by 90 degrees. To transpose square matrices, you just interchange b[i][j] with b[j][i] where b[k][l] is a[n*k+l]. On nonsquare matrices, it's considerably more difficult. "Without any extra space" is a rather strong requirement, maybe you meant O(1) space? (assuming integers are fixed size) Implementation in C++: here.
You need one temp variable, then it is just to jump elements around.
temp = A[0];
A[0] = A[6];
A[6] = A[8];
A[8] = A[2];
A[2] = temp;
temp = A[1];
A[1] = A[3];
A[3] = A[7];
A[7] = A[5];
A[5] = temp;
I came across the following implementation:
For square matrices:
for n = 0 to N - 2
for m = n + 1 to N - 1
swap A(n,m) with A(m,n)
For rectangular matrices:
for each length>1 cycle C of the permutation
pick a starting address s in C
let D = data at s
let x = predecessor of s in the cycle
while x ≠ s
move data from x to successor of x
let x = predecessor of x
move data from D to successor of s
For more info, one can refer here: http://en.wikipedia.org/wiki/In-place_matrix_transposition

Resources