Pointers in C, out of the code below - c

What should be the output of the code below?
I cant understand what *Y-- do. If someone can explain what *Y do this strange thin in F1. Thanks in advance.
int F1(int , int *);
int A = 3;
int B = 7;
int C = 4;
int D = 2;
void main(void)
{
A = F1 (C, &D);
printf("\n%d %d %d %d", A, B, C, D);
C = 3;
C = F1 (A, &C);
printf("\n%d %d %d %d", A, B, C, D);
}
int F1(int X, int *Y)
{
int A;
A = X * *Y;
C++;
B += *Y;
printf("\n%d %d %d %d", A, B, C, D);
*Y--;
return (C);
}
with CodeBlocks the output is :
8 9 5 2
5 9 5 2
15 13 4 2
5 13 4 2
But I dont understand why 13, if I have B=B+*Y ...B=12 (?)

A = 5, B = 9, C = 3, D = 2 before calling C = F1(A, &C) ;
when we make call to F1(A, &C) see here we are passing address of C, now Y is actually referencing to C .
Instruction Execution in function call
local A variable = 5 * 3 (value at which Y pointing)
C++, Global C now becomes 4 ;
B += *Y (value at which Y pointing. this will be 4 because of previous C
++)
so B = 9 + 4. It is the reason for 13 in third line .

Related

Storing the right value in a two dimensional array in c. But when I tried to print the value it shows bigger value and even negative number

Problem:
In this question I tried to solve a bitwise operator problem. Giving two number as input
Input will be two number. Here is some input:
n = 3
k = 3
Then I need to construct "a" and "b" in some way(for instance when "a = 1" then b will be one past a to <= n. The results of the comparisons are below:
a b and or xor
1 2 0 3 3
1 3 1 3 2
2 3 2 3 1
Here is my code:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
//Complete the following function.
void calculate_the_maximum(int n, int k)
{
// Two dimentional array for storing the value of and or xor
int rowOfArray = 3;
int sets[rowOfArray][k];
//For loop for a
for (int i = 0; i < k; i++)
{
int a = i + 1;
//For loop for b
for (int j = a; j < n; j++)
{
int b = j;
b++;
printf("{%i, %i}\n", a, b);
//Storing and operation result to the array
sets[0][j - 1] = a&b;
printf("And: %i\n", sets[0][j - 1]);
//Storing or operation result to the array
sets[1][j] = a|b;
printf("Or: %i\n", sets[1][j]);
//Storing xor opertaion result to the array
sets[2][j + 1] = a^b;
printf("Xor: %i\n", sets[2][j + 1]);
}
}
//Find the biggest number in array
for (int i = 0; i < rowOfArray; i++)
{
int big;
for (int j = 0; j < k; j++)
{
big = 0;
printf("Big1: %i\n", big);
if (big < sets[i][j])
{
big = sets[i][j];
printf("Big2: %i\n", big);
}
}
printf("big3: %i\n", big);
if (big < k)
{
printf("%i\n", big);
}
else
{
printf("%i\n", 0);
}
}
}
int main() {
int n, k;
scanf("%d %d", &n, &k);
calculate_the_maximum(n, k);
return 0;
}
I used too many printf function to show that what have I done wrong. I stored the value as I expected but later in the for loop when I tried to print the specific position integer I didn't get the correct result even sometimes I got bigger and negative number too.
Here is the output:
3 3
{1, 2}
And: 0
Or: 3
Xor: 3
{1, 3}
And: 1
Or: 3
Xor: 2
{2, 3}
And: 2
Or: 3
Xor: 1
Big1: 0
Big1: 0
Big2: 2
Big1: 0
Big2: 120329728
big3: 120329728
0
Big1: 0
Big2: 1986993953
Big1: 0
Big2: 3
Big1: 0
Big2: 3
big3: 3
0
Big1: 0
Big1: 0
Big2: 32765
Big1: 0
Big2: 3
big3: 3
0
As is, for the input 3 3, j holds the values 1, 2, and 2, so clearly sets[2][j + 1] is Undefined Behaviour since it accesses the subarray at index 3, when valid indices are [0, 2].
Given the source problem, the issues are more clear.
k is simply a limit on output, and should not be used as a bound for iteration, or for calculating the storage required for the number of k-combinations.
It is unnecessary to store all the results at once. For each combination, each value of the operation a ? b (where ? is a bitwise operator) can be tested against the value k and the currently stored maximum value for the given operator.
Here is a quick solution. Compile with -DDEBUG to see additional output.
#include <stdio.h>
void setmax(int *dest, int value, int limit)
{
if (value < limit && value > *dest)
*dest = value;
}
void calc(int n, int k)
{
int and = 0;
int or = 0;
int xor = 0;
#ifdef DEBUG
printf("INFO: a b and or xor\n");
#endif
for (int a = 1; a < n; a++) {
for (int b = a + 1; b <= n; b++) {
setmax(&and, a & b, k);
setmax(&or, a | b, k);
setmax(&xor, a ^ b, k);
#ifdef DEBUG
printf("INFO: %-3d %-3d %-3d %-3d %-3d\n",
a, b, a & b, a | b, a ^ b);
#endif
}
}
printf("%d\n%d\n%d\n", and, or, xor);
}
int main(void)
{
int n, k;
if (2 != scanf("%d%d", &n, &k))
return 1;
calc(n, k);
}
Sample runs:
./a.out <<< "3 3"
2
0
2
./a.out <<< "5 4"
2
3
3
If you run the code, you'll get stack corruption error which is due to indexing the array beyond its allocated size. Accessing memory that's not for your program is undefined behavior. Anything might happen. The program may crash or it may not. For my specific compiler and the fact that I ran the code in debug mode and not release mode, the program crashed with the error I mentioned.
Now to fix the error, from what you explained, you have three columns for and, or and xor. So you need to reverse the dimensions of set (set[k][rowOfArray], better change the name to rowSize or n_columns or so). Also reverse the indexing, e.g. change set[0][j-1] to set[j-1][0] and so on. I'm not sure what you're trying to do in the second part, though.

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.

I tried to make a code but it seems it return a wrong value on the output of sum

Here is my code written in c language, I keep on changing the code and placing the x=a and y=b in different location on the source code but it worse.
#include<stdio.h>
main()
{
int sum, a=3, b=5, x=0, y=0;
while(a<10){
printf("\n%d",a);
a+=3;
x=a;
if(a>10){
goto c;
}
}
c:
while(b<10){
printf("\n%d",b);
b+=5;
y=b;
if(b>10){
return 0;
}
}
sum=x+y;
printf("\nSum is %d", sum);
}
It is obvious that the sum must be 23, but it returned 22:
3
6
9
5
Sum is 22
Look in you code, there is the answer...
#include<stdio.h>
main()
{
int sum, a=3, b=5, x=0, y=0;
while(a<10){
printf("\n%d",a);
a+=3;
x=a;
if(a>10){
goto c;
}
}
c:
while(b<10){
printf("\n%d",b);
b+=5;
y=b;
if(b>10){
return 0;
}
}
sum=x+y;
printf("\nSum is %d", sum);
}
While a < 10...
before store 3 inside x, you increase a to 3 (3+3=6), then you store 6 inside x
after that, you add 3 to a (6+3=9) and store it inside x...
after that, you add 3 to a (9+3=12) and stores it inside x...
x = 6
x = 9
x = 12
You never store 3 inside x and then you store 12, one step further
and the you go to c (goto c;), and you keep 12 inside x...
while b < 10...
b = 5... but you increase in 5... then you got 10 inside b...
And then you store it inside y...
and then... 10 is not less than 10 (because 10 is equal to 10) you go out the loop
and then you got...
x = 12
+ y = 10
------------
= 22
And that was the explanation why you got 22 instead 23...
But here is the answer to get 23
#include <stdio.h>
int main(int argc, const char * argv[]) {
int sum, a=3, b=5, x=0, y=0;
while(a<10)
{
printf("\n%d",a);
x+=a; //x = x + a
a+=3;
if(x>10){
goto c;
}
}
c:
while(b<10)
{
printf("\n%d",b);
y+=b; // y = y + b //but this run just once
b+=5;
if(y>10){
return 0;
}
}
sum=x+y;
printf("\nSum is %d", sum);
}
Based on your comment, this will give you 3 + 6 + 9 + 5 = 23
#include<stdio.h>
main()
{
int sum, a=3, b=5, x=0, y=0;
while(a<10){
x+=a;
a+=3;
printf("\n%d ",x);
if(x>10){
goto c;
}
}
c:
while(b<10){
y=b;
b+=5;
printf("\n%d",y);
if(b>10){
return 0;
}
}
sum=x+y;
printf("\nSum is %d", sum);
}

Perplexing Output of C language program using Turbo C++ 3.0 compiler

Concerning my determination for output.It's 1 40 1 While using C it displays output as 0 41 1 How's that possible?What wrong step I'm going into?
#include<stdio.h>
#include<conio.h>
void main(void)
{
clrscr();
int n,a,b;
n = 400;
a = n % 100; //remainder operation
b = n / 10; //division operation
n = n % 10; //remainder operation
printf("%d %d %d",n++,++b,++a); //post-,pre-,pre- increment used
getch();
}
What your compiler prints is correct. Here is the program flow:
#include<stdio.h>
#include<conio.h>
void main(void)
{
clrscr();
int n,a,b;
n = 400; // n has value 400
a = n % 100; // a has value 0
b = n / 10; // b has value 40
n = n % 10; // n has value 0
// n++ evaluates to 0, afterwards n has the value 1
// ++b evaluates to 41, afterwards b has the value 41
// ++a evaluates to 1, afterwards a has the value 1
printf("%d %d %d",n++,++b,++a);
// Thus, 0 41 1 is printed.
getch();
}
Notice especially that the postfix-incrememnt operator n++ returns the value of n unchanged and then changes n. That's why 0 is printed in the first column.

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

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. :)

Resources