function parameter difference - c

Here are two same codes but with different function parameters, but they seem to be outputting same things.
void get_rate_drop_factor(int *rate_ml, int *drop, int *drop_per_min)
{
printf("Enter rate in ml/hr=> ");
scanf("%d", rate_ml);
printf("Enter tubin's drop factor(drop/ml)=> ");
scanf("%d",drop);
*drop_per_min = (*rate_ml / 60) * *drop;
printf("The drop rate per minute is: %d\n\n", *drop_per_min);
}
from what I learned, those variables with '*' in the parameters are output parameters.
void get_rate_drop_factor(int *drop_per_min)
{
int rate_ml, drop;
printf("Enter rate in ml/hr=> ");
scanf("%d", &rate_ml);
printf("Enter tubin's drop factor(drop/ml)=> ");
scanf("%d",&drop);
*drop_per_min = (rate_ml / 60) * drop;
printf("The drop rate per minute is: %d\n\n", *drop_per_min);
}
when I call the function, those two codes seem to be outputting the same thing. So what exactly is the '*' doing for the parameters?
I don't think I'm completely understanding the concept of parameters.
Please explain nicely because I really want to learn this and It's been really frustrating.

from what I learned, those variables with '*' in the parameters are
output parameters.
You correctly pointed out that such parameters are output parameters.
So in the first function all three parameters are output parameters.
In the second function there is only one output parameter. So the caller of the function can not get values of rate_ml and drop entered by the user in the function.
So if the caller of the function needs to get all three values he should use the first function declaration. If he needs only the value of the result calculation he should use the second function declaration.

The function parameters are also basically local variables for the function, so you can use them as such as the first example show this. int *drop for example can be overwritten in the function as it is happen in your example and that is why there is no declaration like int rate_ml, drop;, since it use the 2nd and 3rd parameter as local variables.
But this is not the normal use of them. The normal use case is to be able to give values to a function as arguments to work with. Your first function ignores these incoming values and overwrites them with the result of scanf thus using them as local variables basically. That is why the the function essentially behave the same. But this is a not the way it should be used. The second form is the more clear and logical and expected.
Also note if you would do this for the first function header:
void get_rate_drop_factor(int *rate_ml, int const *drop, int const *drop_per_min)
Then it would not work anymore and also this is usually a good practice to declare function arguments as const to not overwrite them accidentally, because most of the time you just want to read them.

Related

Usefulness of return value not depending on all (exclusively call-by-value) parameters

I have one question:
int swapnum( int x, int y )
{
int tempnum ;
tempnum = x ;
x = y ;
y = tempnum ;
return tempnum;
}
int swapnum(int, int);
int main( )
{
int x = 35, y = 45 ;
printf("Before swapping: %d, %d", x, y);
swapnum(x, y);
printf("\nAfter swapping: %d, %d", x, y);
return 0;
}
I have found this example in internet which demonstrates how call by value works. I understand everything except one thing. For what do we need call by value if we do not get changed result in main? I understood idea of call by reference; we will receive changed result but for what do we need call by value if result is changed only locally (in upper part of this code) and main stays unchanged (printf("\nAfter swapping: %d, %d", x, y);)? And if you write your example too to demonstrate it would be great.
There are even functions which do not return anything.
They have a prototype like
void useTwoNums(int, int);
They illustrate even better than your example that it is not necessary to return anything, even less something which somehow uses the two input parameters and/or depends on them.
The concept which you seem to be missing is the difference between "functions" in mathematical context and "functions" in programming. In programming a function might well do something without returning something. One example is a function which just nicely prints the input values, compare printf(),
http://en.cppreference.com/w/c/io/fprintf
Its return value can be handled inside the return-value-free function to illustrate.
The extreme case would be a function with neither parameters nor return value:
void DoSomethingInFreespace(void);. Functions like that can achieve the data to process e.g. via other input channels. Or they are simply refactored pieces of code, e.g. for reuse, which have a sufficiently rich context, e.g. global or file local variables.
To make the answer more complete, I will integrate some points from comments (including the one by OP, which focuses on return values):
With call-by-value functions are more close to mathematical functions, and are then much more easily composed. (Jean-Baptiste Yunès).
and
it allows you to send values without worrying that some function will change them. It's very convenient. (njzk2)
Both (and other, too) stress that a mathematical function does not alter the parameters; this is something of a "promise" which programmers appreciate.
Turning it around:
when using call by value if you want that [a value in the context outside of the function, e.g.] main be changed we must return the result (OP)
Different angle:
when using call by reference, we don't need to return; it [the parameter] itself changes [outside of the context of the called function and can be used as a] result (OP)
I have found this example in internet which demonstrates how works call by value. I understand everything except one thing: for what do we need call by value?
You don't need call-by-value. But call-by-value is how C works, and most programming languages actually, so you would do well to learn it.
I understood idea of call by reference, we will receive changed result but for what do we need call by value if result is changed only locally
Call-by-value is used in most programming languages because it makes it easier to think about the code. When you see doStuff(x, y); you know that x and y won't change. They can only change if you write doStuff(&x, &y); or x = doStuff(y); or something like that. You don't need go and look up the DoStuff Manual to find out whether doStuff is supposed to change them.
and if you write your example too to demonstrate it would be great.
There's really nothing to demonstrate; the point of call-by-value is that nothing happens. Do you want a demonstration of nothing happening?
The return value is useful when you have formulas.
If you want to calculate the hypotenus from the cathetus and you pass the value of the latters, you do not want theit value modified.

Variable Initialization in Function

I'm fairly new to coding and am currently learning C. In my C programming class, my instructor gave us the assignment of writing a program that uses a function which inputs five integers and prints the largest. The program is fairly simple even for me, but I'm facing some problems and was hoping to get some advice.
#include <stdio.h>
int largest(int x);
int main(void) {
int integer1;
largest(integer1);
return 0;
}
int largest(int x) {
int i;
for (i = 0; i < 5; i++) {
printf("Enter an integer: ");
scanf_s("%d", &x);
}
return x;
}
This is the code that I have written. The main problem that I am having is that in my main method, the IDE tells me to initialize the value of integer1. However, I'm not really sure how to do that because I'm supposed to input the value within the largest() method via the scanf_s function. How may I solve this?
The problem is here, the warning message is to warn you about the potential pitfall of using the value of an uninitialized automatic local variable. You made the call like
largest(integer1);
but you ignore the return value, so the integer1 remains uninitialized.
Remember, in view of largest(), x is a local copy of the actual argument passed to that function, any changes made to x won't be reflecting to the caller.
That said, your code is nowhere near your requirement, sorry to say. A brief idea to get there would be
Create a function.
Create a variable (say, result) and initialize with minimum possible integer value, INT_MIN
Loop over 5 times, take user input, compare to the result value, if entered value found greater, store that into result, continue otherwise.
return result.
I know that normally help for assignments shouldn't be given but I have to say that you might need to rethink what you want to do.
You are inputting an integer to the function named largest. But why are you only inputting a single integer to a function that should return the largest value. You can't do much with a single number in that case.
You should instead be inputting say an array of 5 values(as said in your assignment) to the function and let it return the largest.
The order would then be:
Read 5 values and save to an array
Call the function largest with the array as input
Let the function do it's work and return the largest value
Do what ever you want with the largest value
But if you only want to remove the warning simply type
int integer1 = 0;

Passing number between functions in C

I'm very new to C, and am writing a few programs to try and understand how variables can be passed and changed in between functions. I wrote a simple program below:
int number;
int test( int number ) {
number = 3;
return(number);
}
int main () {
printf ("\nPlease enter in any number between (10 - 99,999)!\n");
scanf("%d", &number);
test(number);
printf ("\nYour number probably wasn't: %d\n", number);
}
The point was to enter in a number, but no matter what you enter that number would be changed to 3. For some reason though when i call test on that number, it will not change to 3 but instead be whatever the user entered. Note that I am trying to change the variable number, and not have any other variable hardcoded as 3.
How come this does not work?
Change
test(number);
to
number = test(number);
Otherwise the value returned by test will be discarded and you will get the number you entered, not 3.
Another way to get the desired effect is to pass the pointer to number:
void test( int *number ){..}
and call the function as
test(&number);
Some answers suggested that to use number as global variable. I advice you that do not use global variable when it is unnecessary.
You are changing a local variable in the function test, not the actual variable. You want number = test(number); as the second to last line in your main() function.
Your function test doesn't deal with the original number that you passed to it. Instead, it gets a copy of this variable and plays around with it locally. Any changes you make to number in this function will get lost (unless you pass in a reference, which you will learn about later, presumably). The correct way to get around this is, as you have already done, return the value of number. However, you don't use that returned value at all. When you say number = test(number);, you are telling the computer to take that returned value and assign it to the original number (the one in your main), which is what you want.
int number; //a
int test( int number ) { //b
number = 3;
return(number);
}
Within test, there are actually two variables named number,
a (which is the number used in main too), and b which has priority.
You´re changing the parameter b to 3.
However, the parameter is only a copy of the original passed value in main
(as usual in C and C++), and gets discarded and the end of test.
Furthermore, you´re not using the return value in main, so 3 is gone.
Perhaps you misunderstand the idea of 'variable scope'.
int number;
The first occurrence of the variable 'number' is declared outside of all functions (and braces). Hence, it has "global" scope.
int test( int number ) {
The variable 'number' defined as an argument to test() has a limited scope. Its life, and visibility, is limited to the braces of the test() function. Outside these braces, this 'number' variable does not exist.
The 'global' variable 'number' and the 'test()' variable 'number' are distinct from each other, each with its own unique value.
Being they are named the same, the 'global' variable 'number' becomes inaccessible inside the 'test()' braces. Hence, any manipulation of the 'number' within the braces of 'test()' does not have any effect on the 'global' variable 'number'.
number = 3;
The above has no effect on the 'global' variable 'number'. Rather it only initializes the 'local' variable 'number' to 3.
return(number);
The above will return the value of the 'local' variable 'number' (3).
}
int main () {
printf ("\nPlease enter in any number between (10 - 99,999)!\n");
scanf("%d", &number);
The line above sets the 'global' variable 'number' to a value entered by the user.
test(number);
The line above passes the value of the 'global' variable 'number' to test. It does not capture the 'return' value (3) returned by test. If desired, the above line could be rewritten:
number=test(number);
The above line would set the 'global' variable 'number' to the return value of test (3).
printf ("\nYour number probably wasn't: %d\n", number);
}
All answers so far seem to ignore the fact that you are trying something which does not make much sense. You are returning what is basically a constant from your function, but using a passed value as some intermediate storage while that is completely unnecessary. Either of those two will work:
void test( int& number ) {//We don't need to return anything, because we pass number by reference, and so changes made to it will persist outside this functions scope
number = 3;
}
int test(){
return 3; //We just return 3, we don't need any arguments passed to the functions in this version
}
Now in the first case you call the functions as
test(number); //number will be changed by test because it's passed by reference
in the second case you call the functions as
number = test(); //Here test just returns 3 and we assign that value to number.
Edit:
Just for completeness sake I will add the third version that you can use:
void test(int* number){//Here we pass a pointer to an integer to test
*number = 3;//and change the value pointed to be number to 3. Read * as 'value pointed at by'. So this says 'value pointed at by number = 3'
}
in this case you call the function as
test(&number)//read & as 'pointer to'. So now we pass 'pointer to a' to test.
Note that this version is basically a less elegant and more error prone version of the first version I mentioned (at least in this specific scenario). Their usage and effects are more or less equal, but in the first version you do not need to concern yourself with dereferencing and the general fact that you are working with pointers.
Your code never does anything with the value test returns. Your code would be easier to understand if you didn't call both variables (the one in main and the one in test) number.
You have 2 options. One is
number = test(number);
Second is refer Pointers in C. Pass by address would do the trick for you.
It doesn't work because you're doing a pass by value instead of a pass by reference. If you want the value of number to be always 3 without doing an assign when you call the function, then you should do something like:
void test(int *number){
*number = 3;
}
and call like:
test(&number);

Call an expression multiple times in an expression

I'm a student and new to C. One of the questions for my homework reads as follows:
max is a function that accepts two int parameters and returns the
value of the larger one. Four int variables, population1 ,
population2 , population3 , and population4 have already been
declared and initialized. Write an expression (not a statement!)
whose value is the largest of population1 , population2 ,
population3 , and population4 by calling max . (HINT: you will need
to call max three times and you will need to pass the return values
of two of those calls as arguments to max . REMEMBER: write an
expression, not a statement.)
I understand the logic of it:
Call the function max with the first two variables, the function will return the larger of the two and then take that value (somehow pass it without assigning to a fifth declared variable) and compare it to the third variable's value. Take the larger of the second pairing (again passing it without the benefit of a new variable - remember it's an expression, not a statement) and compare it to the forth value. However I haven't been able to write the correct syntax.
Also, understand that this is a 100 level class. So anything higher level will not be accepted for this particular question. No libraries to be #include(d).
Well you seem to understand how to do it, and yes the question seems to ask you to not assign returned values to new varibles. You can basically chuck in a max() as a parameter to another max(), and the return of the inner max() will be the int for the outer max() parameter.
Since c is strict, it won't compile unless the return type for the function is the same as the parameter (in this case, both are int, so it's fine)
max(2, max(3, 4)); // inner returns 4, which puts 4 into the outer max, and compares 2 to 4
Function calls can be nested. Here's a hint:
max(population1, max(...))
Can you come up with the correct code for the ...?
A function which returns something different that nothing (void) can be used inside an expression freely. An expression is defined recursively since it is made by sub-expressions until you reach terminal symbols (as constants or function calls).
So there is nothing strange in understanding the syntax, a call to max is synctatically equivalent to a numeric constant.
int x = 5;
int y = max(5,10);
int z = 5 + 10;
int k = max(5,10) + 3;
int j = max(3 + 2, 8);
These are all legal. Of course the assignment is just for clarity, as as assignment is a statement, not just an expression anymore.

I am learning C and can't figure out why this is giving me an error

So I am trying to write a function that receives a float value, returns a float value, and is displayed in main with printf. I keep getting the same errors:
markup2.c:58: error: conflicting types for ‘GetPrice’
markup2.c:46: error: previous implicit declaration of ‘GetPrice’ was here
Where am I making the mistake? I've tried typecasting everything that touches GetPrice but still no luck. Can someone please explain what I am doing wrong?
#include<stdio.h>
// define the constant MARKUP as float value 0.1
#define MARKUP 0.1
int main()
{
// declare variables
char proceed;
float value;
float markupValue;
// display welcome message to user and inform them of markup rate
printf("\nThank you for using Chad Hammond's markup calculator.\n");
printf("The current markup rate is %.1f%c.\n",MARKUP*100,'%');
// ask user if they want to perform a markup
printf("Would you like to markup an item? y/n:\n");
scanf("%c", &proceed);
// if yes, proceed to next step
if(proceed == 'y')
{
// prompt user for the price of item to be marked up
printf("Please enter a wholesale value to markup: ");
scanf("%f", &value);
// display input back to user
printf("The wholesale value you entered was: %c%.2f\n",'$', value);
markupValue = (value*MARKUP);
// display amount of increase
printf("The dollar amount of this increase will be: %c%.2f\n",'$', markupValue);
// display total price after increse
printf("The price for this item after markup is: %c%.2f\n",'$', (float)GetPrice(value));
}else
// if user did not want to markup an item, belittle them with sarcasm
printf("Well, if you didn't want to markup an item you should have just used a Ti-83 and left me alone!\n\n");
// display exit message
printf("Thank you for using HammondInstruments Markup Calculator, goodbye.\n");
// return that program has completed
return 0;
}
float GetPrice(float value)
{
float output;
value += value*MARKUP;
output = value;
return (float)output;
}
You will need to either declare or define GetPrice before your main.
C expects to see its functions before you can use them (forward declaration). You've used GetPrice in main before declaring it (the function definition is after main).
When your compiler sees the use of GetPrice, it assumes that it's a function it hasn't seen yet and generates an implicit declaration, which looks like int GetPrice(). Later on, when it sees the function declaration, it sees that the real function signature differs from the implicit declaration, and throws an error.
The solution, therefore, is to either define GetPrice before main, or use a forward declaration of the form float GetPrice(float); before main. The forward declaration (like what is actually found in the various header files you #include) tells the compiler the function exists, but leaves its definition to later (or even to another file).
Shouldn't you first declare GetPrice ? And then main ?
Your main issue is that since you didn't declare one before main, the compiler is giving you a default declaration of GetPrice that doesn't match yours, thus the conflict. You should add a prototype before main, or move the entire function there:
float GetPrice(float);
//main
float GetPrice(float value){...}
or
float GetPrice(float value){...}
//main

Resources