I am new to C, and I have to make a mini calculator program (this is homework, but I'm not looking for the answer, just a little more understanding). Basically, one function must look like this:
int add(double d, double dd, double *result);
It will return a 0 if there are no errors, and -1 if an error occurred (in the case of addition, there wouldn't be many errors - but division for example, divide by 0 would be an error).
A user has to input two numbers into the terminal, those numbers then get used as the parameter values in the add method. What I don't understand is what is result initially when the method is called? Is it just null? And why would I want to return 0 or -1 and not result instead? For example:
double result;
returnValue = add(2.0, 5.0, &result);
Obviously I'll get 7 as the result, but how will I print that out without returning the result? returnValue is 0, so I know there were no errors, so now I need to print result.
C doesn't have pass by reference. You can pass in a pointer, which is what you're doing here, but C only has pass by value.
Now to your actual questions:
What I don't understand is what is result initially when the method is called? Is it just null?
No, the value of result is undefined before the add function is called. You have no guarantees whatsoever if you try to use the value of result before assigning to it, either by assigning to it in the function where it's declared or by assigning to it in add with code like *result = d + dd.
For that matter, a double can never be null. Null is a possible pointer value, not a possible floating-point number.
And why would I want to return 0 or -1 and not result instead?
If you were to return result directly, you'd have to have some kind of distinguished "calculation failed" return value, which is kind of messy and leaves the caller to check the result before using it. This way forces the caller of add to notice that there is status code as the return value, and if the caller wants to ignore it then they can (although you shouldn't ignore status codes).
Obviously I'll get 7 as the result, but how will I print that out without returning the result?
Ed Heal is right to suggest printf. If you're using Linux or Mac OS X, though, I'd also recommend running man printf from the terminal - it's often more convenient than opening a web browser.
Thank you for your honesty. It is refreshing.
The line should read
returnValue = add(2.0, 5.0, &result);
And to print out the result look up printf - That will do the trick.
The code you have written does not assign a value to result when the variable is declared. Thus it contains some random number. It is obviously bad to use this number to do anything, as it will cause your program to have unpredictable results. This would be what is referred to as an uninitialized variable error.
Your code does not refer to the variable before it is assigned, so I am not saying you have a bug. I am simply answering the question of what result contains before it is assigned to. If you want it to have a particular value, you can declare it like this:
double result = 7;
and it would always have some predefined value. Again, there is no need to do this in your case, I'm just saying you could if you wanted an always defined value.
Related
Would this be a valid use of NULL in C or are there other ways to solve this problem that are preferred?
// Send data
// cb_push returns NULL if it is successful
char uart_send(char c) {
void* ret = cb_push(w_buffer, &c);
if (ret != NULL) return c;
SETBIT(UCSR0B, UDRIE0);
return NULL;
}
In Java I would do like this, sort of, but in C I don't know what is good practice.
It's not really defined and there are different approaches depending on the library and/or function you're using. In general, there's no way to differentiate between 0 and NULL (in fact, NULL is usually just a preprocessor macro expanding to 0).
In general, the following possibilities are used, sometimes even matched within one library depending on the usage:
If a pointer is returnd, a return value of 0 usually indicates some kind of error.
Functions with status codes (or main entry points) usually return 0 in case there hasn't been any error.
There are functions returning 0 if something hasn't been successfull (i.e. they return a boolean value).
Some stdlib string functions return an "absurd" value in case there has been an error (or nothing found). For example, std::string::find() will return -1 if the sub string couldn't be found. This is however wrapped/hidden behind a constant named value (std::string::npos) to avoid throwing around "magic values".
Is there a perfect way? I don't think so, but it really depends on the specific use case. If you return a pointer, returning 0 in case of a mistake is just perfect. If you're returning status codes, I'd go with either macros (similar to windows API) or enums. Don't even worry about any specific values - only use the names.
Generally speaking, the C convention is to return 0 on success or a negative number if not.
Also, assuming your function is supposed to return some pointer and it failed to do so, the convention is to return NULL.
NULL is internally defined as #define NULL (void*)0 means a pointer pointing to zeroth location of memory.
What I saw in an if statement was like this.
if((var = someFunc()) == 0){
...
}
Will the statement
(var = someFunc())
always return the final value of var no matter what environment we are in?
That is just a one-line way of assigning to a variable and comparing the returned value at the same time.
You need the parentheses around the assignment because the comparison operators have higher precedence than the assignment operator, otherwise var would be assigned the value of someFunc() == 0.
This is simply wrong. var is assigned, and then its value is overwritten by a constant 0. The return value of the function is therefore lost, and the if always fails. Most compilers would probably issue a warning about that nowadays, both because of the assignment within an if and because of the impossible if that results. The right way to do what was probably intended is
if((var = someFunc()) == 0) {
(Mind you, this might also be malicious code trying to introduce a vulnerability under the guise of a common newbie mistake. There was a case recently where someone tried to smuggle a check into the Linux kernel where they assigned the UID to 0 (i.e., root) while pretending to check for being root. Didn't work, though.)
This is correct, I use it all the time
if ((f=fopen(s,"r"))==NULL)
return(fprintf(stderr,"fopen(%s,r) failed, errno=%d, %s\n",s,errno,strerror(errno)));
/* successfully opened file s, read from FILE *f as you like */
I also use it when I calloc() memory.
You're assigning the return value of someFunc (fopen or calloc in my cases) to a variable AND also testing that return value, it's a semantic shortcut assuming you'll never want to debug the assignment and the test separately.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Error handling in C code
Let's say you have a function:
int MightWork(){
// if it works
return x;
// if it fails
return y;
}
what should x and y be?
because I have another function:
if (MightWork){
// do stuff #1
}else{
// do stuff #2
}
I know for this particular example, using a return value of 1 will take the second code block to "do stuff # 1" and using a return value of 0 will take the second code block to "do stuff #2"
My question is what is preferred style in C to do this? Does a return value of 0 for a function indicate success and any other value indicates failure? Or vice versa? Or values under 0?
I'd like to make sure I'm writing my C code with the current style. Thanks!
For non-pointer success/fail:
0 => success
-1 => fail
For pointer functions:
NULL => fail
everything else => success
Both are used, and it generally depends on if multiple error codes can be returned.
If your function will only "succeed" or "fail" with no additional information, I would recommend you return 0 for failure and 1 for success, because it's simpler and more semantically valid.
If your function may fail with multiple status codes, the only way to go is have 0 for success and other values for failure representing different statuses.
In a conditional context, integers evaluate to "true" if they're non-zero and "false" if zero, so you should return 0 on failure if you want to use the function in that way, and make sure not to return 0 in the successful branch.
There's no one right answer.
If your function is named/documented as evaluation of a predicate of some sort, then it should return a nonzero value (1 if convenient) for "true" and 0 for false.
If your function returns a pointer, 0 (null pointer) is just about the only reasonable way to report failure. Conventions like returning (void *)-1, MAP_FAILED, SEM_FAILED, and such are hideous and should not be copied. If you need to report a reason for failure, add an extra int *errorcode argument and include if (errorcode) *errorcode = reason; at the end of your function to allow callers that don't care about the reason to pass a null pointer.
If your function returns a numeric value such that only certain range values make sense (for instance only non-negative integers, or only finite floating point values) then use out-of-range values for error codes (e.g. negative integers or NaN/infinity) as error codes. If you don't have enough possible codes (for example only NaN) then use the int *errorcode approach described above.
Historically, a return value of 0 usually indicates success, while a return value of -1 indicates failure. You can also use more output values to give the user of the function more detailed information about the return state. It's another tradition to set a global error code variable, see e.g. GetLastError and SetLastError on Windows.
1 = true
0 = false
in general....
sometimes people use -1 for "error"
another way to handle this is with enums and sometimes #defines. Though many times people don't use this unless there is many errors.... and usually multiple errors are handled by various negative numbers.
In my opinion both could work , but in different case.
If you make the function to do some operation , return 0 for success , -1 for failed,
and set errno to appropriate value so that the caller could check it to know the detail of failure.
Sometimes people also use different return values to mean different failures.
If you would like the function to test some condition , you should make it return either
TRUE or FALSE, and use if (XXX() == TRUE) later . The form of if (XXX()) is not recommended, though many people do that to save times of typing keyboard .
TRUE and FALSE is not a built in data type in C , however many programming environments will define it as TRUE = 1 and FALSE = 0, you can do it yourself if you are not working in such an environment.
use #define.
#define TRUE 1
#define FALSE 0
this helps any other person to understand your choice of standard for true and false value.
Also, if the program code gets bigger, keeping track of the constants become difficult and might confuse. Using #define for constants is always a good practice.
Whenever we call a function returning value why it is not required to catch the value?
consider the following C code,
int main()
{
int i;
scanf("%d",&i);
printf("Value of i is: ",i);
return 0;
}
Here scanf() returns value 1, but as it is not catched in anywhere why didn't the error pops up?
What is the reason to allow such programming?
Primarily because expressions in C also yield values. For example: x = 1; yields the value 1. Sometimes you use that for multiple assignment like x = y = 1;, but more often you don't.
In early C, the void return type hadn't been invented either, so every function returned some value, whether it was generally useful or not (for example, your call to printf also returns a value).
The rules of the language don't make this an error (doing so would lose compatibility with virtually existing code) and since this is common and rarely indicates a problem, most compilers don't warning about it either. A few lint tools do, which has led a few misguided programmers to write things like (void)printf("whatever"); (i.e., casting the unused return to void to signal that it really, truly was intentional when it was ignored. This, however, rarely does any good, and frequently does quite a bit of harm, so (thankfully) it's rarely seen.
Functions that return a value have that functionality for the use and convenience of the programmer. If you aren't interested in the return value, then don't use it.
Do you need the return value in this example? NO. So you have not used that in this case. But in another situation the return value might be important. For example if you want to read as long as some integer in available in input stream, then you can do something like this:
while (scanf("%d", &i) == 1) {
// do something
}
If there is an EOF then this loop will break. Here return value is needed.
So the summary is use return value when needed, and don't use when not needed. Such programming is allowed because both scenario is possible.
A lot of library functions return values you might not think about. Imagine having to use the return value of every printf call! (printf returns the number of characters printed.)
Pretty much every native c function returns a int. scanf and printf included. It would be really annoying if you always had to "capture" it to satisfy the compiler; In a large program you would end up creating thousands of variables just for storing return values that you never look at.
The reason is that C has no other established way of handling errors than by return value. These returned values, that is to say those return to report success or failure, should almost always be checked (unless you're just doodling around or you have a proof that the function will not fail).
Now since return values are also used for other things than returning success/failure information there might be, and are, situations where you will not be interested in the value a function returns, but just the side effects of executing it. In this case forcing the programmer to inspect/bind the returned value would become quite tideous.
Simple: if you don't use the return value, you don't use it.
It is not mandated that you do.
(That said, in a case like this, you should: you have no idea at present whether scanf encountered an error.)
It is not the case that everytime a value is evaluated,& it must be stored or returned,because the value you have obtained may be used by some other functions,to evaluate different kind of things.A value may be a measure...for example consider the following simple programm,where we want to check that the number entered is even or not
'int main()
{
int a;
printf("Enter a number");
scanf("%d",&a);
if(a%2==0)
printf("even number");
else
printf("odd no");
return 0;
}'
here the variable 'a' is not necessarily to be returned,because we just want to check that the number is even or odd...no need of returning
I want the function getCategory() to return "invalid" , instead of printing the word "invalid" (i.e instead of using printf ) when input to the function is invalid (i.e.when either height or weight are lower then zero).
please help:
#include<stdio.h>
#include<conio.h>
char getCategory(float height,float weight)
{
char invalid = '\0';
float bmirange;
if(height<=0 || weight<=0)
return invalid;
else
{
height=height*0.01; //1 centimeter = 0.01 meters
bmirange=[weight/(height*height)];
if(bmirange< 15 )
return starvation;
}
}
int main()
{
char Category;
float height,weight;
printf("enter height");
scanf("%f",&height);
printf("enter weight");
scanf("%f",&weight);
Category=getCategory(height,weight);
if(Category == 0)
printf("invalid");
else
printf("%c", Category);
}
NOTE: the original question has been altered many, many times and the code has changed just as often, introducing new errors in each iteration. I leave this answer as it answered the original code, see history. Below this answer there's an update giving advice instead of code, as that seems more appropriate here.
Hmm, astander removed his answer. But perhaps this is what you should actually have:*
char getCategory(float height,float weight)
{
char invalid = '\0';
if(height<=0 || weight<=0)
return invalid;
return 'c'; /* do something for the valid cases */
}
* originally the question contained height || weight <= 0 and no value for variable invalid.
Notes on the code:
With proper indentation, your program flow becomes clearer. I corrected your if-statement, assuming this was your intend, actually. The last line should contain what you currently left out in your question. I added an initialization in the first line, because having a value is better then not having a value (which means: if you don't initialize, it can be anything, really).
In your calling code, you can do this:
Category = getCategory(height, weight);
if(Category == 0)
printf("invalid");
else
printf("%c", Category);
which actually prints the word "invalid" to the output, if that was your intend.
Update: based on new text in the question, it's clear that the asker wants something else, so here's a new answer. I leave the above, it's still valid with the original question.
You're now asking not to print the word "invalid" and not to use a special value for the invalid case. Instead, you ask to return "invalid", which I understand as returning the string with the value "invalid" (which, taken in itself, is still returning a special value).
You cannot do it
In short: you cannot do that. The current function has return type char. I don't know the purpose of your function, but I'm sure you've given it some thought and there's a reason for using a char. A char can only contain one character. And the word "invalid" is multiple characters. You have a few options, choose whichever suits you best:
Other ways
change the return type to be string instead of char, this requires redesign of all code involved;
settle with returning a special value. You don't show the body of your function, but if it would normally never return \0, you can use that value, as in my example above. Of course, you can choose any other char value;
raise an exception and use a try/catch in the body. But you use C, not C++. Here's a link that describes using C++-style exception handling for C, but this may be a bit out-of-bounds, learning C can better be taken on a small step at the time.
What's commonly best practice
In normal situations, it is common to choose either special-case values (typical in older or more basic languages like C or assembler) or exceptions (typical for more structured languages like C++, Java, Python). It's commonly considered bad practice to change a complete function for the purpose of special-cases (like invalid input).
Why
Instead, the caller of the function should deal with these special cases. The reason for this is a very important rule in programming: the function can never know beforehand what users of that function want to do when something bad happens (illegal input). One may choose to print "Illegal input" (for commandline users), another wants to quit the program (for in a library) and yet another wants to ignore and do nothing (for automatic processing). In short: what you are trying to achieve, you should try to achieve differently (see option 2 and 3 above, and my original solution).
Teachers and textbooks
Using this approach is by far the easiest and also best to understand for any (future) co-workers as it follows common computer practices. Of course, I haven't seen your assignment or textbook, so I can't tell in what direction they want a solution, and it won't be the first textbook or teacher to first show you the wrong path, let you tremble, and then show you the right path.
The getCategory method doesn't always return (because of the if statement). Also, not sure about the height in if statement. Add another return invalid at the end of the method.
char getCategory(float height,float weight)
{
char invalid;
if(height<=0 || weight<=0)
return invalid;
return 0
}
you need to (very carefully) pore over your textbook to ascertain the multitude of errors in the above code.
1, your test in getCategory will almost certainly not do what you want it to do.
2, you ARE returning invalid in some cases (but not all, see #1). However, there is no way to know that as invalid has no known value.
3. in other cases, getCategory returns no value at all
You're defining a variable named invalid. Its contents are undefined (it could be anything from -128 to 127). When you return this variable you're returning anything; do you want to assign something to the invalid variable before you return it? e.g.
char invalid;
invalid = 'i';
if ( ... ) {
return invalid;
} else {
return 0;
}
What does invalid should be mapped to? You should have a convention like this:
char invalid_category = '?';
or perhaps:
#define INVALID_CATEGORY '?'
This is better defined outside of the getCategory function so that the calling code can access it.
Also it isn't evident what your code returns when valid arguments are passed to it.
By the way, in your function getCategory, you have a variable that is not used nor declared - starvation. Where does that come from? I doubt that is a global variable.
Also, the variable bmirange does not make sense nor would it compile
bmirange=[weight/(height*height)];
as you can see that is a left hand side expression (LHS) but you have used an array subscript operators on the right hand side of expression (RHS). That is an illegal statement!
What was your intention there? Was that meant to be a pair of parenthesis?
Can you confirm this?
A lot of the answers are confusing because the OP did not make themselves clear on what is the error nor an explanation as to what is going on which is leading others to end up with code posted that does not satisfy the OP.
Hope this helps,
Best regards,
Tom.