Passing number between functions in C - 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);

Related

In this function (in C) that takes an integer as an argument: Why isn't sum = 0 every time the function is called?

Update: Hi, I did not misunderstood the goal of the function. I was just surprised that static int sum = 0 does not execute each time the function is called, so I don't understand that. The goal of the function is correct: to sum the values and give the final value, and it works fine. The question is: Why isn't the sum changing into 0 each time the function is called? I suppose that's how it is set up by convention? That since I put static int sum, it will run only once and make it equal to zero, but then it won't run this line of the code again when the function is called?
In the following code, the only way I could make this function work was when I declared that sum = 0.
I was expecting the output to be 55, 45, 50, since sum is getting value 0 each time it is run! But for some reason, after the second time the function is called, the first line "static int sum = 0;" is skipped. Why? Thanks a lot =)
#include <stdio.h>
int sum (int num)
{
static int sum = 0;
sum = sum + num;
return sum;
}
int main()
{
printf("%d ",sum(55));
printf("%d ",sum(45));
printf("%d ",sum(50));
return 0;
}
Since sum (variable) is getting value 0 each time it (sum function) is run!
No, it's not.
But for some reason, after the second time the function is called, the first line static int sum = 0; is skipped. Why?
It is not skipped. That is just your impression. But the initialization of 0 happens only once prior to program startup.
If the function is called everytime there's a call to sum(), why doesn't sum (variable) gets the value of 0, since it is written in the beginning of the function?
Because sum is qualified with the static storage class specifier, which means that the sum variable is not destroyed after the function has been executed once and it retains its value for the whole entire program execution.
An object whose identifier is declared without the storage-class specifier_Thread_local, and either with external or internal linkage or with the storage-class specifier static, has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.
Source: ISO/IEC 9899:2018 (C18), §6.2.4/3
Omit static at the sum variable and you get your desired result.
Note that the purpose of the sum function is pretty useless in that way. I guess it is just for testing purpose only.
EDIT:
For me it seems that you actually got the function from somewhere else and misunderstood the purpose of the program and the function sum.
The original purpose of the function sum is to sum the input values provided at different function calls to sum() and return the current sum at each function call.
That is the reason, why sum (variable) is qualified with static (to retain its value).
The purpose is not to just pass the input value through, which is what think the purpose of sum() is.

function parameter difference

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.

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;

How does this code that prints 1 to 1000 work in C?

I've seen a C program that prints 1 to 1000 without using any looping structure or conditional statements, but I don't understand how it works. Can anyone go through the code and explain each line?
See live demo here. Why does it result in a runtime error?
#include <stdio.h>
#include <stdlib.h>
int main(int i)
{
printf("%d\n",i);
((void(*[])()){main, exit})[i / 1000](i + 1);
return 0;
}
((void(*[])()){main, exit})[i / 1000](i + 1);
This line create a two-element array of function pointers, with the first element containing the main function, and other element containing the exit function.
It then indexes this array by i / 1000. This either gets the main function if i < 1000 or the exit function when i == 1000.
It then calls the function pointer that it just indexed with i+1 as the argument.
It's a recursive function, with the stopping condition determined with an array index rather than a conditional. I don't think it's valid C however; main's signature is wrong, and the cast to a function pointer removes the return type from the main function.
Breaking down the line that you asked about
((void(*[])()){main, exit})
This is an array literal, which creates an unnamed temp array of two function pointers, and initializes those pointers to point at main and exit
[i / 1000]
This indexes that temp array. Integer division truncates towards 0, so when 0 <= i < 1000, this gets element 0 (the pointer to main) and when 1000 <= i < 1999, it gets element 1 (the pointer to exit)
(i + 1);
This calls the pointed at function with i+1 as an argument.
There are a bunch of things here that are undefined behavior. Declaring main as having a single int argument is illegal according to the standard, though generally will work, getting the number of command line arguments as the single argument. Getting a pointer to main is likewise undefined, as main is a special function that may have a non-standard calling convention.
This code is a good example of how far you can bend C without breaking it. You shouldn't attempt to understand this until you can write understandable C.
Here are the key features and assumptions:
First, assume that the program is called without arguments. The parameter i is in the place usually called argc, so it will have the initial value 1 (the number of elements in the array of arguments, usually called argv).
Next, assume that the single-argument form of main doesn't cause any problems. Officially supported forms of main are with no arguments, 2 arguments (argc, argv), and sometimes 3 arguments (argc, argv, envp).
So the first printf prints 1.
Next we have a compound literal. It might be easier to understand if you look at a simpler one first:
(int[]){10,20}
That's an anonymous array of 2 ints, with values 10 and 20. int[] is the type. It goes in parentheses before a braced list of values. So what's this:
(void(*[])()){main, exit}
void(*[])() is a type. It means array of function pointers with the signature void (*foo)(). The type name in parentheses followed by a braced list is compound literal, just like the (int[]){10,20} example. In this case, it creates an array of 2 function pointers whose elements are main and exit.
Assume that the mismatch between the function pointer type (returns void) and main (returns int) doesn't cause a problem.
This:
((void(*[])()){main, exit})[i / 1000]
is our anonymous array of 2 elements, inside some redundant parentheses, followed by [i / 1000]. That's just normal array indexing syntax. If i/1000 is 0, you get the first element of the array (thearray[0]), which is main. That happens for all i is between 0 and 999. If i/1000 is 1, which happens when i==1000, we're looking at thearray[1], which gets us the second element: exit.
So far, we have an expression taht is equal to main when i<1000 and equal to exit when i==1000.
Now look at the whole statement:
...that_big_thing_that_is_either_main_or_exit...(i + 1)
A function pointer, followed by a parenthesized argument list. That's a function call. Whichever function we chose from the array, now we're going to call it, providing an argument that is equal to the incoming argument (i) plus 1.
So the first call, when i is 1, selects main for the function and i+1 = 1+1 = 2 for the argument. It calls main(2).
main(2) does a printf which prints the 2, and then calls main(3).
main(3) does a printf which prints the 3, and then calls main(4).
...and so on until...
main(999) does a printf which prints the 999, and then calls main(1000).
main(1000) does a printf which prints the 1000, and then calls exit(1001).
None of the calls to main ever return, and the return 0 never happens, because the exit terminates the process. The fact that the process returns an exit code of 1001 rather than 0 appears to be the reason for ideone's "runtime error" message.
The main function is called recursively.
void print_nb(int n)
{
if (n <= 1000)
{
printf("%d\n", n);
print_nb(n + 1);
}
}
Like Sourav Ghosh said, it's prohibited to use with main() recursively, better use another function.

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.

Resources