My professor posted
int main(int argc, char **argv)
{
// enter code here
printf("Test 1: trying odd(3) AND even(2)...\n");
printf("%d\n", odd(3) && even(2));
printf("Test 2: trying odd(3) OR even(2)...\n");
printf("%d\n", odd(3) || even(2));
printf("Test 3: trying odd(4) AND even(7)...\n");
printf("%d\n", odd(4) && even(7));
printf("Test 4: trying odd(4) OR even(7)...\n");
printf("%d\n", odd(4) || even(7));
return 0;
}
int odd(int n)
{
printf("in odd!\n");
return n % 2 == 1;
}
int even(int r)
{
printf("in even!\n");
return r % 2 == 0;
}
as an assignment asking why lines 2 and 3 only return in odd! but 1 and 4 return in odd! and in even! I'm unsure as to why as I don't know the difference between the Return 1 and Return 0 commands. From what I can gather Return 1 will always return the value (in this case in odd!) but return 0 will only return it if it satisfies a certain condition?
Also: does the code int length(char *name,int start,double finish): return the length of a word in characters as a real number?
Thanks in advance to anyone that decides to help me.
This is called "Short-circuit evaluation".
...in which the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression...
Therefore, you have to figure out what will these two functions odd and even return:
odd(): If n % 2 == 1 , return 1, otherwise 0
even(): If n % 2 == 0 , return 1, otherwise 0
And in the main() function,
odd(3) AND even(2): odd(3) return 1, and check the return value of even(2), therefore the even() is called.
odd(3) OR even(2): odd(3) return 1, because of 'short-circuit evaluation', it doesn't need to check the even(2), therefore the even() isn't called.
odd(4) AND even(7): odd(4) return 0, because of 'short-circuit evaluation', it doesn't need to check the even(7), therefore the even() isn't called.
odd(4) OR even(7): odd(4) return 0, and check the return value of even(7), therefore the even() is called.
when evaluating a logical expressions, it checks the condition one by one and whenever the whole expression is known (whatever the remaining are) it stops evaluating them.
Example
unsigned char a = 1; // true
unsigned char b = 0; // false
case 1
if (a && b) printf("Yes");
check a: yes it is true
check b: no it is not true
Result: the expression is wrong and it doesn't print Yes
case 2
if (a && !b) printf("Yes");
checks a: yes it is true
checks b: yes it is false
Result: the expression is right and it prints Yes
case 3
if (a || b) printf("Yes");
checks a: yes it is true
checks b ?!!! WHY? no need to check b since the whole expression result is known only by checking a, do you agree?
Result: checks aand print Yes without even checking b
Project that on your code now ;)
Return 0; - the function returns 0.
Return 1; - the function returns 1.
In your case odd function returns 1 when number (n) is odd and 0 when the number is even.
This is done by "asking" if the reminder when dividing by 2 equels 1.
Also even function returns 1 when number (r) is even, and 0 when the number is odd.
This is done by "asking" if the reminder when dividing by 2 equels 0.
In your main function, and (&&) and or logical operations are done, on the results of the return values of odd and even functions.
Example:odd(3) return 1, even(2) return 1 then 1&&1 equals 1 (the result).
The logical Boolean algebra operators AND and OR (&& and ||) in C operate with an optimization known as short-circuit evaluation.
This is how the optimization works.
Imagine that you came up with a rule for yourself:
You will only date someone if they own a cat AND a dog AND a fish.
Now imagine you start talking to someone that you may be interested in dating. They say:
Well, I have a cat, I don't have a fish, but I do have a dog.
When did you stop paying attention to what they said? As soon as they said that they didn't have a fish, because as soon as they said that, they broke your "AND" rule. So, the rest of the sentence is completely irrelevant. This is short-circuiting AND.
Now imagine that you changed your rule:
You will only date someone if they own a cat OR a dog OR a fish.
Now imagine you start talking to someone that you may be interested in dating. They say:
Well, I don't have a cat, I have a fish, and I don't have a dog.
When did you stop paying attention to what they said? As soon as they said that they had a fish, because as soon as they said that, they satisfied your "OR" rule. So, the rest of the sentence is completely irrelevant. This is short-circuiting OR.
Short-circuit evaluation is a performance optimization for evaluating logical expressions.
In your example, the even() function returns true if the number passed to it is even, and the odd() function returns true if the number passed to it is even. Otherwise these functions return false. Look at each of the Boolean expressions and notice when short-circuit evaluation must occur.
There's also another way to test for even values for integral types.
int IsOdd(int x) { return (x & 1); }
int IsEven(int x) { return !(x & 1); }
If the least-significant bit is set, the number is odd. If not, it's even. This simply tests that bit. Just throwing this out there so you can eliminate the modulus operation... it's another option. Not an answer to your question, but I can't comment so...
As we know 0 indicates false-ness, 1 indicates true-ness. And the return part tells the compiler that the function must return the evaluated result to the caller module.
So, a return 1 means signal the caller module about a successful execution of the called module (with the aid of a Non-Zero quantity i.e. 1)
whereas,
return 0 presents a flag showing that there was some error/anomaly that led to the termination of the called module. So, in this case stderr shall be used to give details about such error.
Related
int a = 0;
a = 7 > 2 ? printf("6") : printf("4");
printf ("%d",a);
The ouput of this block is :
61
I tried the code in its expanded form
int a = 0 ;
if(7>2)
{
printf("6");
}
else
{
printf("4");
}
printf("%d",a);
Here I the output was:
60
I would like to get an explanation on why the output differs.
The first statement assigns the return value of printf to a. printf returns the number of bytes that were written. In this case that is 1. In the second expanded version, a is not assigned. Here is an actually equivalent version to the original:
int a = 0;
if(7>2)
{
a = printf("6");
}
else
{
a = printf("4");
}
printf("%d",a);
They are completely different.
To make them identical:
int a = 0 ;
if(7>2)
{
a = printf("6");
}
else
{
a = printf("4");
}
printf("%d",a);
cond?val1:val2 is the ternary operator. It is not supposed to be a control structure (like if, for or while). It is an operator. To build expression (things that have a value) rather than instruction (things that does things).
Frontier is fuzzier in C than in other languages, because instructions have a value (including void) and expression have potential side-effects.
But, well, you use cond?val1:val2 when you want to get the result. As you did, since you assigned the result to a.
And the result here is the result of printf("6"), that is 1, since printf returns the number of printed characters. Note that there is no real doubt, since even if 7 were smaller than 2, result would still have been 1. Since you print that result, it is normal to have a 1 printed after the 6.
(Just to be clear, even if I assume you know that already, what you did is print string "6" and then number 1, which is the result of 1st printf. Exactly as if you did
printf("%d",printf("6"));
which 1st prints "6", then pass the result to the outer printf to print what the inner printf returned, that is 1)
In your second code, you do nothing to change a's value, and you ignore the result of printf.
Your examples aren't equivalent. To be equivalent, the second one should say a=printf(... everywhere. After which a will get assigned the number of characters printed, 1.
The conditional operator (e1 ? e2 : e3) is not a "short version of if condition", although it has some similarities with an if ... else construct. The conditional operator yields a value (which you assign to a in your first example); an if ... else construct does not have a value.
So, your first example assigns a value to a, because it is written in the form of an assignment statement; that value is the 1 returned by the call to the printf function. To get similar behaviour in your second example, as others have said, you need to also assign the value returned by printf inside the if ... else blocks.
Alternatively, to make the first case work like the second, you can skip the assignment and use the conditional operation to determine the argument that is passed to the printf call:
int main(void)
{
int a = 0;
printf(7 > 2 ? "6" : "4");
printf("%d", a);
return 0;
}
I've seen the operator ! being used in multiple places differently and I still don't get how it actually works. My basic understanding is it reverses the value from true to false and vice versa. If it reversed to true the statement triggers. Let's take an example.
int main(void)
{
int a = 5;
if (!(a == 6))
{
printf("unlike\n");
}
if (!(a == 5))
{
printf("like\n");
}
}
In the code above since a is 5 it ends up printing "unlike" because the false statement that a is 6 got reversed. Now let's take another example.
int main(void)
{
string i = "abc";
string j = "cab";
string k = "abc";
if (!strcmp(i, j))
{
printf("unlike\n");
}
if (!strcmp(i, k))
{
printf("like\n");
}
}
The string type has been taken from the cs50.h header and strcmp from string.h. strcmp returns value 0 if the two strings are alike and if unlike depending on the alphabetical order returns a positive or negative value. Now if we follow the logic in the previous example, since i and j are unlike, and false it should be reversed to true and unlike should be the output. But I tried running the code and the result was like.
I am confused. Can anyone please explain this to me clearly? Feel free to use other examples too. I could always get away with not using ! but I just want to learn what it is and how to properly use it.
A boolean in C is an integer with zero for false and non-zero for true.
strcmp returns 0 when the compared strings are identical and a non-zero value depending on the difference otherwise. Therefore, strcmp(i,k) is seen as "false". The ! then changes this to "true", which leads to your current output.
In the first case a = 5. then if (!(a == 6)); here a = 6 is not true (false), so it's something like this. if (!(false)) it means if (true). That's why it prints "unlike".
strcmp(i, j) returns 0 if the strings i and j match; otherwise, it will return a non-zero value. In your case,
(!strcmp(i, j))
Here i and j are not equal so strcmp will return a non-zero value because i != j. So !(1) means not(1) means 0, so the if condition is false because of zero. Therefore it'll not execute the printf("unlike\n") line.
(!strcmp(i, k))
Here i and k are same so strcmp will return 0. !(0) means not(0) = 1 so the if condition is true. It will execute the printf("like\n") line.
Code
#include <stdio.h>
int main() {
int i;
for (i=1; i<=10; i++) {
(i % 2) ? printf("%d is odd\n", i) : printf("%d is even\n", i);
}
}
Result
1 is odd
2 is even
3 is odd
4 is even
5 is odd
6 is even
7 is odd
8 is even
9 is odd
10 is even
In the above C program, why it still works fine even though the conditional expression only states i%2 and not i%2!=0 ?
In C, integers can be used in a Boolean context, and zero represents false while non-zero represents true.
That's why your code works. The expression num % 2 will be 0 (the single false value) for an even number and 1 (one of the many possible true values) for an odd number.
The following expressions would all work for detecting an odd number:
num % 2
(num % 2) != 0
((num % 2) != 0) != 0
... and so on, ad untilyougetboredum (like 'ad infinitum' but with limits).
Having said that, I don't really consider it a good idea to do it this way, code should express intent as much as possible and the intent here should be to choose the path of execution based on a comparison. That means, if you're looking for an odd number, you should use something like (num % 2) == 1.
You also don't need a separate printf call in each of those code paths:
printf("%d is %s\n", num, ((num % 2) == 1) ? "odd" : "even");
You'll notice I've also used num instead of i. This is simply a style thing of mine, related to the afore-mentioned intent. If the variable is only used as an index, I'm happy to use the i-type variables(a) but, the second it gains a semantic property (like a number being checked for oddity), I tend to use more descriptive names.
I have no issue with people using simple variable names, I just prefer more descriptive ones in my own code.
(a) Actually, I'd probably use idx in that case but that's being too CDO(b), even for me :-)
(b) OCD but in the right order :-)
C doesn't have a dedicated boolean type. It uses int value as boolean. That is 0 is considered false and any non zero value is treated as true.
Try printing some conditions
printf("%d",5==5);
printf("%d",1>3);
This will output
1 and 0.
C always uses 1 to denote true. But any other non-zero value would work as well when using in conditions.
if(6+1)
printf("TRUE");
Will print TRUE.
This is also the reason we can use this form of while loop:
int i= 10;
while(i--){
printf("%d",i);
}
Will print 9876543210. Notice it stops when i becomes 0, which is false.
Now back to the question, i%2 would always result in either 0 or 1. In case of 1(true) the first statement is run while in case of 0 (false) the second statement is run.
Will printf("hello") statement in the function fact() will ever get executed? If yes than why it doesn't get printed when call the function fact in main? If not then does this return statement returns the value to the function and statement printf("Hello") is never approached.
#include <stdio.h>
int fact(int n)
{
if (n == 1)
return 1;
else
return (n * fact(n - 1));
printf("Hello");
}
main()
{
printf("%d", fact(6));
}
The Law of Excluded Middle is incredibly useful for formal reasoning about if statements. The two choices that you have in your code are as follows:
n is equal to 1, and
n is not equal to 1.
There is no third "middle" state in this logic.
Now let's go back to your code, and see what happens depending on the value of n. When it is 1, your code returns 1. When n is not one, your code returns a result of some calculation.
In order for printf("Hello") to be reached, n needs to be equal to one and not equal to one at the same time (i.e. n==1 && n!=1 must be true). The law of excluded middle lets you mathematically prove that this expression is false for all values of n, meaning that the printf line is unreachable under any circumstances. Optimizing C compilers will issue a warning, and remove this "dead code" from the executable that they generate.
int fact(int n)
{
if(n==1)
return 1; //statement 1
else
return (n*fact(n-1)); //statement 2
printf("Hello");
}
A function ends with a return statement. The return statement specifies that the function is ending while returning the following information.
whenever the function is called with any value of n, the function always ends execution in either statement 1 or statement 2, and thus never reaches the printf statement
While looking through puzzles and answers in the code golf Q&A section, I came across this solution for the longest and most obscure ways to return 1
Quoting from the answer,
int foo(void) {
return! 0;
}
int bar(void) {
int i=7;
while (i --> 0);
return-i;
}
The --> 'operator' is already well-known :), but I couldn't find any info on return! 0; and return-x; where I'm guessing x could be any variable
Do they really exist, and what do they mean? Does it have anything to do with precedence?
It's really the same idea as with -->. C compilers tokenize program text using a particular algorithm that makes
return-i
parse like
return -i
and
return! 0
parse like
return !0
All the same.
The ! and - are for the "second part of the operator", they don't have anything to do with return.
return-x; just returns the negated value of x.
return! 0; is return (!0);, nothing special.
The notation return! 0 can be interpreted as return (!0) which is basically return 1.
The other notation return -x where x is equal to -1 (as a result of while (x --> 0); is just return 1.
return!0; is the same as return (!0);, and !0 == 1.
For second one, return-i returns 1 because i==-1 at that point (after while loop decrements it to -1), and return-i same as return (-i), or return 1.
The spacing may be throwing you off:
return !0;
is basically making 0 non-0, or "true", 1.
"-->" is not "an" operator, it is 2 operators: decrement&save-later "--" and compare ">"
i-- > 0, or see if i is still greater than 0 then decrement it. What it's usage is doing is decrementing i from 7 until it becomes 0 (and decrements after the compare making a negative number, which the first occurrence would be -1)
return -i;
is just turning that -1 into a positive 1