If I wanted to limit the range of values to be assigned to an integer to three different conditions. eg; Must be between 9 and 95 and also be divisible by 5 would this be the correct way to accomplish this?
I've been told that i can have multiple conditions as long as they are separated by && but I am having little success with my code.
if (input >= 5 && input <= 95 && input %5)
Your code seems fine to me, except for this line.
if (input >= 5 && input <= 95 && input %5)
The expression input % 5 returns the remainder of input/5. You want input to be divisible by 5, which happens when input % 5 returns a remainder of 0. Since C interprets 0 as false, and pretty much all other integers as true, this expression will do exactly the opposite of what you want it to do. Try using
if (input >= 5 && input <= 95 && (input % 5 == 0))
That should do what you want it to do.
There are a number of issues with your code as it stands. First, the outright bugs:
The expression input % 5 will give you the remainder when divided by five. This means you will get zero if it is a multiple, non-zero otherwise. Unfortunately, zero is treated as false so this will only be true if input is not a multiple. The correct expression is (input % 5) == 0.
If you enter something that cannot be interpreted as an integer, the scanf will fail and input will be left at whatever value it was beforehand. This should be caught and acted upon, by checking the return value - this gives you the number of items successfully scanned so should be one.
Your code seems to return the value if okay but return nothing if it's invalid.
Next, while not bugs, these things are my personal preferences which can make code easier to read and maintain:
I prefer to explicitly separate sub-expressions so I never have to worry about precedence rules (provided it doesn't make the expression unreadable in the process). To that end, I would make the full if statement if ((input >= 5) && (input <= 95) && ((input % 5 == 0)).
I'm not a big fan of the if (condition) transferControl else ... construct since the else is totally superfluous.
I also prefer error catching to be done in a localised fashion at the start, catching problems early. Only after all checks are passed do you do the success portion.
A function (assuming it is a function, which seems likely) should generally do one thing, such as check if the value is valid. Writing issues to standard output is probably best left to the caller so that the function is truly re-usable. It would be better to have a function do the check and return some value to indicate whether or not there was a failure, along with the value if valid.
It's usually better to use puts("something") rather than printf("something\n"). The printf call is best left to where you actually need to do argument formatting.
Taking that all into account, the code that I would posit would be along the lines of:
#include <stdbool.h>
bool InputValidRangeAndMultiple(
unsigned *pValue,
unsigned minVal,
unsigned maxVal,
unsigned multVal
) {
unsigned input;
// If no unsigned int available, error.
if (scanf("%u", pValue) != 1) return false;
// If value invalid in any way (range or multiple), error.
if ((*pValue < minVal) || (*pValue > maxVal)) return false;
if ((*pValue % multVal) != 0) return false;
// Value is now deemed okay.
return true;
}
Calling that function can be done thus, with the prompts and errors handled outside the "input and check" function:
#include <stdio.h>
unsigned value;
puts("Enter Value.\nValue must be divisible by 5 and within 5 and 95...");
if (! InputValidRangeAndMultiple(&value, 5u, 95u, 5u)) {
puts("Invalid input...");
returnOrDoSomethingIntelligent();
}
// The 'value' variable is now valid.
Related
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.
First of all I'm not even sure whether you call it a member, couldn't think of a better term.
I'm trying to learn basics of debugging and arrays - so I wanted to create something resembling insert-sort from memory (so mistakes would be made) and then debug the program.
void findingsmaller (int *array, int num_inputs){
int a = 0;
int b = 1;
for ( b=1; b == num_inputs-1; b++ ) {
if ( array[a] > array[b] ) {
goleft(array, a, b);
a++;
}
}
}
Let's say we have this in array: 6 5 3 1 8 7 2 4. array[a] should be 6 and array[b] should be 5. 6 > 5 so we should enter the function that would find the first smaller number on the left of the array.
From my debugging session it seems like the condition is FALSE so I don't enter goleft at all. More specifically, Step into ignores it, the testing printf wasn't executed either. I'm assuming the array comparison is not written properly, what's the correction?
WHOLE CODE if somebody wants to see other possible mistakes.
Thank you in advance!
EDIT: <= num_inputs is correct, somehow I thought for has (range1, range2, change) instead of (start, condition, change). Anyway, now the problem seems that my goleft function does its do-while cycle one time too many although it shouldn't get past that condition.
EDIT2: A couple of other mistakes were fixed.
My printing in main is now for( ; i <= num_inputs-1; )
My goleft would do too many iterations due to the condition, fixed into ... while ( a >= 0 && array[a] > array[b] )
My findingsmaller would only operate if the number next is smaller but does nothing when the number is greater. For example for 6 8 the program wouldn't function properly. Added else {a++}
My fixed code for anyone interested in the comparison of the changes.
The for loop is executed as long as the condition is True.
for ( ;Condition; )
{
// body
}
In your for loop, the condition is always False if the input is greater than 1.
Instead of b == num_inputs - 1, you should put b < num_inputs in your for loop condition. Since the equality isn't true on the first iteration of the loop, it is immediately breaking.
I was looking a little bit at your code and i notice something that doesnt work.
while (scanf("%d", &array[i]) != EOF)
As the documentation of the function scanf say :
The return value is EOF for an error
your while condition was making you num_imputs reaching 200 even if there was only 3 inputs. I would replace EOF by '\n'.
while (scanf("%d", &array[i]) != '\n') /* stop when the user input '\n' you
can replace with any character you want to make it stop. */
I did not make a lot of test but this should make your program work fine.
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.
When I wish to check if a value is 0 in C, how is it idiomatically done?
if (!num)
if (num == 0)
While this is a matter of taste, I find it pretty much depends on intention. If the value is to be used as a boolean, ! is alright. If the value is counting something the equality makes more sense.
if (!isVisible) {...}
if (isVisible == 0) {...} // Intention not as clear as line above.
if (numberOfItems == 0) {...}
if (!numberOfItems) {...} // Intention not as clear as line above.
I always prefer the second way:
if (num == 0)
As num == 0 or ptr == NULL evaluates to a boolean which is the intent. The Java compiler enforces this form, but C/C++ compilers don't.
The worst example of this would be:
if (!strcmp(str, "something"))
Which really disguises its intent as the strcmp family of functions don't return boolean, they return positive, zero, or negative (as pointed out by #JoachimPileborg).
However if the int is being used to represent a boolean type, which C does not have a builtin type for, then this form is OK:
if (!b)
But this can be made self documenting by creating a custom type:
typedef int bool;
#define true 1
#define false 0
bool b = true;
if (!b)
{
... etc
}
Whatever the others told you WITH AN EXCEPTION!
Don't do it with float and double. IEEE 754 floats/doubles/long doubles (the most commonly used) often don't contain exact values, so comparing them directly with 0 is foolish (or doing if (!floatValue))
Example: http://ideone.com/PIUflA
float f = 0.3;
f -= 0.2;
f -= 0.1;
if (!f)
{
printf("zero\n");
}
else
{
printf("non zero\n");
}
if (f == 0)
{
printf("zero\n");
}
else
{
printf("non zero\n");
}
With unoptimized compilation can return (on ideone does)
non zero
non zero
(if you enable optimizations, the compiler could pre-compute some values in higher precision and round them to 0)
I think it depends on the context. If the variable refers to a boolean value is better first choice. Otherwise, the second is better.
It's done however you want it to be done, in terms of your style. I don't see it as mattering as long as your consistent and it's clear on what you're trying to do, or if you do it in cases where it may flow better in an English sentence and may put emphasis on what your doing.
For sake of clarity I usually have if (num == 0), since it takes less thinking to understand what I'm doing when I'm going over my code.
!!value will work too if you want to check if value is non-zero.
!value evaluates to 1 when value=0 and 0 when value≠0.
The second ! flips it, making !!value evaluate to 1 when value≠0 and 0 when value=0.
We may argue which way is better, but idiomatic, though for what I can tell by other answers archaic, would be if(!num).
For the compiler, it does not matter, of course. For the human reader it does. Since both forms are used by other human beings, you should get used to them and recognise them. Personally, I prefer the shortest form, which takes less time (less tokens, especially parenthesis) to read and understand. Especially:
if (!ptr) {}
if (!strcmp(a,b)) {}
are easyer to read than
if (ptr != NULL) {}
if (strcmp(a,b) == 0) {}
if (0 == strcmp()) {}
The last form makes me physically sick.
When I use a debugger I can tell the exit is not exiting the function. Am I using the exit function wrong? (i must be) how do I fix this?
int is_prime(int x,char array[]){
int divider = (x-1);
float test;
while(x>-1){
test = isdigit((x % divider)); //isdigit returns !0 if digit
if(divider == '1'){
return(1); //if divider reaches 1 then the number is prime
exit;
}
if(test == '0'){
return (0);//not prime
exit;
}
divider--;
}
}
The name of a function by itself (with no parenthesis after it) just gives you the address of a function without calling it. In C the most basic statement is an expression which is evaluated for its side effects, with the resulting value of the expression ignored. So a statement like exit; or 3; which has no side effects is legal but doesn't actually do anything and might as well be deleted. Some compilers will give you warnings about such meaningless statements, though you may have to turn on extra diagnostic warnings to get them. Using such options (such as -Wall for gcc) is a very good idea and will help you avoid some pitfalls like this.
You must call it:
exit(0);
Also, if you put it after return, it will never be called, since return returns from the function.
EDIT: And, as others have said, exit exits the program, so you probably don't want to use exit here.
Besides the bugs of returnand exit you have a bug also in the way you use ints and characters. isdigit is a function that is only applied to characters, giving true if a character is between '0' and '9', but one should know that the character notation in C is only a fancy way of writing a codepoint (ASCII most of the time). So when you write '1' in a C program, the compiler will see 49, if you write 'a' the compiler sees in reality 97. This means that isdigit return true for the values 48 to 57, probably not what you intended. In the line where you compare divider with '1', in reality you're comparing it with 49 (except on IBM mainframe, where '1' is 241)
Your loop is infinite, it depends on the value of x, but x isn't changed in the loop, so the condition in the while can never change.
EDIT: Here the corrected code
int is_prime(uint_t x)
{
uint_t divider;
if(x <= 3)
return 1;
for(divider = x-1; ; divider--) {
if(x % divider == 0)
return 0; //not prime
if(divider == 1)
return 1; //if divider reaches 1 then the number is prime
}
}
Read exit(3)'s manual.
The statement:
exit;
gives the following warning with GCC:
C:\temp\test.c:71: warning: statement with no effect
What happening is that you have an expression that evaluates to the address of the exit() function - but that expression doesn't actually do anything with that address. it's similar to if you had a statement like:
1 + 2;
It's valid C, but it has no effect on anything.
To call the function, as Thomas Padron-McCarth said, you have to have the argument list (even if they're empty for some functions):
exit(0);
exit exits the process, not the function. You want return.