understand c logic printf & valuables - c

I am trying to understand the logic behind the printf numbers in the code below. Can someone explain how the valuables change? What symbol is executed first (|| , &&, != and so on)? In which direction is it executed?
#include <stdio.h>
static float w = 3.9;
short
f (short a, short *b)
{
a++;
(*b)++;
w++;
printf ("13: %d %d %4.2f\n", a, *b, w);
return a - *b;
}
int
main ()
{
short x, y, z, arr[] = { 4, 8, 0, 6 }, *p = arr;
char m[] = "dcrfvtgb", *pc;
y = 2;
z = 3;
x = (++y != z);
printf ("1: %d %d %d\n", x, y, z);
x = y = 6;
x *= (y = 5);
printf ("2: %d %d\n", x, y);
x = 0;
y = 2;
z = 7;
printf ("3: %d %d %d %d\n", !x || y && !z, x, y, z);
x = 5;
y = 3;
printf ("4: %d %d %d\n", x, y, x < y ? x : y);
y = 0;
if (y)
x = 7;
else
x = 5;
printf ("5: %d %d\n", x, y);
y = 8;
if (z = (y++ > 8))
x = 9;
else
x = 0;
printf ("6: %d %d %d\n", x, y, z);
x = y = 5;
while (y++ < 5)
x += y;
printf ("7: %d %d\n", x, y);
for (x = y = 5; y < 7; x = y++)
printf ("8:%d %d\n", x, y);
for (x = 2, y = 5; y >= 1; x++, y /= 3);
printf ("9: %d %d\n", x, y);
printf ("10: %d %d\n", p[2], *(arr + 1));
x = y = 3;
z = f (x, &y);
printf ("11:%d %d %d %4.2f\n", x, y, z, w);
for (x = y = z = 10; z-- > 9; x *= y);
printf ("12: %d %d %d\n", x, y, z);
for (pc = m; *pc; pc++)
(*pc)--;
printf ("14: %s %c\n", m + 2, *(m + 1));
return 0;
}

#abligh says "The C standard does not specify the order in which the arguments are evaluated."
As far as I know, the Intel implementation pushes the arguments right-to-left onto the stack, which means that the arguments are evaluated right-to-left.
printf ("12: %d %d %d\n", x, z, z++);
In this example the first value of z, when printed, will be one higher than the second value of z when printed.

The printf function takes a format string as the first argument, then zero or more other arguments. Each of the things beginning with % in the format string correspond to one of the other arguments. At least the way you are using it, these are in the same order, so the first % placeholder corresponds to to the second argument (i.e. the first after the format string), the second % placeholder to the next and so forth. The letter following the % (and sometimes other characters) describe the type of argument and how it is to be printed. See the manual page for printf() for more information.
Each of the arguments is evaluated before the call to printf. The C standard does not specify the order in which the arguments are evaluated. So if you have (e.g.), !x || y && !z as an argument, each of those will be evaluated prior to the call to printf(). For the order in which the components of those are evaluated, see operator precedence.
Note that that only tells you what order operators are evaluated in (i.e. in x + z * y, this says the z * y is evaluated before the +). It doesn't tell you whether x, y or z will be evaluated first; as they may be expressions themselves, that's important. So, for instance in:
int
f(int a, int b, int c)
{
return g(a) + h(b) * i(c);
}
in the general case you have no guarantee in which order g(a), h(b), and i(c) are evaluated. You only know the order in which the + and * are evaluated.
If you want to know more about evaluation order, you need to research sequence points.

Related

Values inserted to my parameter suddenly vanished after the first expression

I have problems for my function, since after the first expression, the values inserted to my parameters (float x, float y) suddenly becomes 0.
I called this function with main (), the output for c = x/y works as expected. But for d = x - (y * c), it gives me an output of 0, I check where the problem is and it appears to be because of x and y since they both have 0 values for some reason
I have not finished my function for greatest common divisor, since I'm still stuck at this problem
'''
int gcd (float x, float y)
{
int c = x / y;
printf ("This's your quotient: %d\n", c);
int d = x - ( y * c ); // d = 0 since y, x = 0
printf ("This's your remainder: %d\n", d);
printf ("c %d\n",c); // works normally
printf ("y %f\n",y); // y = 0
printf ("x: %f\n",x); // x = 0
}
Here is example code that fixes the issues I noticed and changing the signature to separate calculations from output:
#include <stdio.h>
void quotient_reminder(unsigned x, unsigned y, unsigned *q, unsigned *r) {
if(y == 0) return;
*q = x / y;
*r = x - (y * *q); // d = 0 since y, x = 0
}
int main() {
unsigned q, r;
quotient_reminder(25.0, 7.1, &q, &r);
printf ("This's your quotient: %u\n", q);
printf ("This's your remainder: %u\n", r);
}
and it will return:
This's your quotient: 3
This's your remainder: 4

How do logical && and || operators along with increment and decrement work?

Evaluate the following expressions. Find x,y,z values in each case. Assuming x=1 and y=5 initially, what do you observe:
z=++x && ++y;
z=--x && --y;
z=++x || ++y;
z=--x || --y;
How are logical operators affecting the values?
I believe "what do you observe" is very explicit in that you should see something. That almost certainly means writing the code and examining what happens.
In any case, the logical operators treat 0 as false, anything else as true. The output of those operators is 0 for false and 1 for true.
Also keep in mind that the pre-increment and -decrement operators change the value before use.
And, finally, be aware that && and || are short-circuiting operators which means the second sub-expression may not always be evaluated. For example:
int x = 1 ; int y = 5 ; int z = --x && --y;
will leave y equal to 5, because the --x is zero/false so we know that the whole expression will be false - there's no need to evaluate the second sub-expression.
That should be enough to figure out what the results are, based on your pre-conditions for x and y.
As a hint, let's look at the first one. ++x and ++y will be 2 and 6 respectively so both true. Hence true && true will give true, ending up as 1.
And now, since you have written some code (as per your comment asking about what you considered strange behaviour of the -- and ++ operators in some cases), here's my sample code which shows the operations:
#include <stdio.h>
int main() {
int x, y, z;
x = 1; y = 5; printf("oldx = %d, oldy= %d", x, y);
z=++x && ++y;
printf(", newx= %d, newy = %d, z = %d\n", x, y, z);
x = 1; y = 5; printf("oldx = %d, oldy= %d", x, y);
z=--x && --y;
printf(", newx= %d, newy = %d, z = %d\n", x, y, z);
x = 1; y = 5; printf("oldx = %d, oldy= %d", x, y);
z=++x || ++y;
printf(", newx= %d, newy = %d, z = %d\n", x, y, z);
x = 1; y = 5; printf("oldx = %d, oldy= %d", x, y);
z=--x || --y;
printf(", newx= %d, newy = %d, z = %d\n", x, y, z);
return 0;
}
The output of that is:
oldx = 1, oldy= 5, newx= 2, newy = 6, z = 1
oldx = 1, oldy= 5, newx= 0, newy = 5, z = 0
oldx = 1, oldy= 5, newx= 2, newy = 5, z = 1
oldx = 1, oldy= 5, newx= 0, newy = 4, z = 1

Increment operator not showing expected result

I am not getting the result I expected.
void main(){
int x = 5;
int y = x++;
printf("%d, %d", x, y);
}
I am getting 6, 5 as output, but I expected 6, 6.
You're using the post-increment operator.
The line:
int y = x++;
is equivalent to:
int y = x;
x += 1;
The increment of x occurs after the value of x is copied to y.
The pre-increment operator is probably what you're looking for, which would be used like:
int y = ++x;
This is equivalent to:
int y;
x += 1;
y = x;
which appears to be what you expect.
The ++ operator behaves differently depending where it is.
y = x++; will get the value of x and then increment it. (Post-increment)
y = ++x; will increment x first, and then give that new value to y. (Pre-increment)
You're probably looking for pre-increment.
You are using the postincrement operator. It evaluates to the value of the variable before it is incremented, which is why y contains 5.
For your case you want the preincrement operator.
y = ++x:
You have used the post-increment operator (i.e x++) and assigned it to y, so y will be 6 and x will be 5.
For your expected output, use the pre-increment operator, like so:
int main() {
int x = 5;
int y = ++x;
printf("%d, %d", x, y);
}

C compilation error, called object is not a function

I have the following code in C to make some arithmatic calculation
#include <stdio.h>
#include <stdlib.h>
int main()
{
float x,y;
float z;
printf("Enter x y z \n");
scanf("%f %f %f ", &x, &y , &z);
z = ((4.2 (x+y)))/ (z - (0.25*z))/ (y+z)/ ((x+y) * (x+y));
printf("\n z = %f", z);
return 0;
}
when i build the program , i get the following error message in the following code line
z = ((4.2 (x+y)))/ (z - (0.25*z))/ (y+z)/ ((x+y) * (x+y));
called object is not a function or dunction pointer
That's a typo, you're missing an operator:
z = ((4.2 * (x + y))) / (z - (0.25*z)) / (y + z) / ((x + y) * (x + y));
^
whatever the operator is
C has no support for mathematics-implicit multiplication operator (more or less as you would write in an equation in school). E.g.
// y = 2x
int y;
y = 2 * x;

A function is pulling variable values from a different function, but I don't want it to and don't know how it's doing it

For my programming class we are making a main() function that calls multiple other functions. Two of these functions are numberStats() and triad(), both of which have their own variables, no global variables are used, and numberStats() is called immediately before triad(). Neither codes have similar variable names, but for some reason when I use the triad function, which asks the user to input 3 ints, it spits out the first int correctly but the 2nd and 3rd ints are the two ints inputted into the numberStats() function. Can anyone explain why this is happening and what I might be able to do to fix it? Thank you in advance, new blood here.
EDIT*
here's the output code: (if it's italicized then it's the numbers I entered in as input)
numberStats: Please enter two positive ints: 5 800 //I input 5 and 800
800 is larger
5 is smaller
800 + 5 = 805
800 - 5 = 795
800 * 5 = 4000
800 % 5 = 0
triad: Please enter three positive ints:
1 2 3 //I input 1 2 and 3
you entered 1, 5, and 800
Not all equal
Sorted order: 1, 5, 800
I obviously did not enter 1, 5, and 800 for the triad function, why would it tell me I did?
EDIT** Source code for numberStats() and triad():
void numberStats(void)
{
int var1, var2, a, b, c, d;
printf("numberStats: Please enter two positive ints: ");
scanf("%d %d",&var1, &var2);
if (var1 > var2){
printf("%d is larger\n",var1);
printf("%d is smaller\n",var2);
a = var1 + var2;
b = var1 - var2;
c = var1 * var2;
d = var1 % var2;
printf("%d + %d = %d\n",var1,var2,a);
printf("%d - %d = %d\n",var1,var2,b);
printf("%d * %d = %d\n",var1,var2,c);
printf("%d %% %d = %d\n",var1,var2,d);
}
else if (var1 < var2){
printf("\n%d is larger\n",var2);
printf("%d is smaller\n",var1);
a = var2 + var1;
b = var2 - var1;
c = var2 * var1;
d = var2 % var1;
printf("%d + %d = %d\n",var2,var1,a);
printf("%d - %d = %d\n",var2,var1,b);
printf("%d * %d = %d\n",var2,var1,c);
printf("%d %% %d = %d\n",var2,var1,d);
}
else if (var1 == var2){
printf("%d and %d are the same\n",var1,var2);
a = var1 + var2;
b = var1 - var2;
c = var1 * var2;
d = var1 % var2;
printf("%d + %d = %d\n",var1,var2,a);
printf("%d - %d = %d\n",var1,var2,b);
printf("%d * %d = %d\n",var1,var2,c);
printf("%d %% %d = %d\n",var1,var2,d);
}
}
void triad(void)
{
int x, y, z, low, mid, high;
printf("\ntriad: Please enter three positive ints: \n");
scanf("%d, %d, %d", &x, &y, &z);
printf("you entered %d, %d, and %d\n", x, y, z);
if (x == y && y == z){
printf("All equal\n");
}
if (x <= y && x <= z){
low = x;
if (y <= z){
mid = y;
high = z;
}
else{
mid = z;
high = y;
}
printf("Not all equal\n");
}
if (x >= y && x >= z){
high = x;
if (y <= z){
low = y;
mid = z;
}
else{
low = z;
mid = y;
}
printf("Not all equal\n");
}
if ((x >= y && x <= z) || (x <= y && x >= z)){
mid = x;
if (y >= z){
high = y;
low = z;
}
else{
high = z;
low = y;
}
printf("Not all equal\n");
}
printf("Sorted order: %d, %d, %d\n", low, mid, high);
}
The functions triad() and scanf() are causing the trouble:
int x, y, z, low, mid, high;
printf("\ntriad: Please enter three positive ints: \n");
scanf("%d, %d, %d", &x, &y, &z);
You're looking for commas in the data, but not entering them (you gave "1 2 3" but you needed to give "1,2,3" with commas (and optional spaces) separating the numbers). scanf() returned 1 instead of 3, but you ignored it. Don't! Check your inputs, every time.
As a result, you have quasi-random values in y and z, which is why you're running into problems.
A basic debugging technique is to print the values just read:
if (scanf("%d, %d, %d", &x, &y, &z) != 3)
…report error and bail out…
printf("x = %d, y = %d, z = %d\n", x, y, z);

Resources