I have a function in C that I want to output four different values, so rather than using return in my function I decided have four different variables as arguments to the function that would carry their values out of the function back into my main code. I figured if I defined the variables in main and fed them to my other function, they would have whatever value the function gave them after exiting the function. This does not happen though. The variables end up having a value of 0 or close to 0 (like, around 10^-310).
Do I have to declare my variables in a different way/with a different scope to allow them to keep the values they had in a function after exiting the function? Or is there a way to return multiple values in a function?
Here's an excerpt of the relative code:
void PeakShift_FWHM_Finder(double fwhml,double fwhmr,double peak, double max)
{
...//stuff happens to these variables
}
int main()
{
double fwhml,fwhmr,peak,max;
...//other stuff to other variables
PeakShift_FWHM_Finder(fwhml,fwhmr,peak,max)
//These four variables have the right values inside the function
//but once they leave the function they do not keep those values.
...//code continues...
return 0;
}
Use pointers instead.
void PeakShift_FWHM_Finder(double *fwhml,double *fwhmr,double *peak, double *max)
{
...//stuff happens to these variables
// REMEMBER TO DEAL WITH (*var_name) INSTEAD OF var_name!
}
int main()
{
double fwhml,fwhmr,peak,max;
...//other stuff to other variables
PeakShift_FWHM_Finder(&fwhml,&fwhmr,&peak,&max)
//These four variables have the right values inside the function
//but once they leave the function they do not keep those values.
...//code continues...
return 0;
}
What you are looking for is something called Passing by reference
To achieve that, you need to change your declaration to take pointers to the variables. For example
void foo(int * x) {
(*x)++;
}
Then, you can simply invoke that function passing values to it through their address.
int main() {
int i = 10;
foo(&i);
printf("%d", i);
}
What this does is passes the address location of the variable to be modified and the function directly modifies the variable at that address.
Related
I have an assignment that requires the use of a function
void stats(FILE *in, int *count, double *sum); , which is supposed to compute the sum, average, and integer count of each file. We are supposed to call the function by using stats(in, &count, &sum) . I'm confused as to how exactly I'm supposed to send the results back to main if the stats function has a void return type. Any help or explanation would be greatly appreciated! Thanks
Your function signature indicates that each parameter is a pointer argument (they begin with a *). Declare (and possibly initialize) those variables in your main function, then pass the addresses of those variables as indicated in the way you're told to call the function: stats(in, &count, &sum). The function will modify those variables in main scope using the pointers you passed to it, without returning any value. This is an example of pass (or call) by reference.
So overall, your main function will have something like:
int main(void)
{
/* some FILE opening here */
int count = 0;
double sum = 0;
stats(in, &count, &sum);
/* rest of your main function */
return 0;
}
If you want to understand more about what the * and & mean, you should go through how pointers work in C – here is a very basic resource to get you started.
As my topic says, I want to know a method to send a value to a function which is called by another function. For example:
int main(){
int sendingvalue=funtionreturningvalue();
int x=0;
function1(x);
}
function1(int x){
//some code here
function2(x);
}
function2(int y){
//again some code here
function3();
}
function3(){
//here I need the top value sendingvalue
}
It is so useless to explicitly pass that int sendingvalue again and again in all the functions until it reaches function3. So what is the best option to pass this value?
There are 2 options. You either make it a global variable, or you pass it through each function.
To make it a global variable, add the following line outside all of your function definitions:
int sendingvalue;
Then you access modify and read it from any function. If you don't want to use a global variable, you'll have to pass it along the stack.
Why should one change the value of the main variable and NOT the COPY of the variable.
I have a method
int plusInt(int x){
return ++x;
}
When this function is called, a new stack frame is created, with the copy of x and not the original variable. So this changes this copy's value?
Q: If I want to change the value of the original variable I use a pointer to it and then increase a value right? Eg:
int plusIntPointer(int *x){
return ++*x;
}
But what is the use/why would someone want to change the value of the original variable and not the copy?
So this changes this copy's value?
Exactly, as the function has only the copy, and not the original variable, as a local variable.
If I want to change the value of the original variable I use a pointer to it and then increase a value right?
Right again. The reason you use a pointer is to pass the address of the variable to the function.
But what is the use/why would someone want to change the value of the original variable and not the copy?
The reason is that any changes to the copy will be lost after your function ends and you return to the calling function.
For example, let's assume that you want to use a function in order to swap the values of two variables. Then, you have to change the original values. Your function should be like this :
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = *temp;
}
and you should call it like this :
swap(&a, &b);
This way, the changes will remain even when you return to the calling function.
If you just change the copies, the variables will not have swapped values when you return to the calling function!!!
Let's say you want to make a function that swaps two variables. Then you need to do this:
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = *temp;
}
...
void swapwrong(int a, int b) // wont work as intended
{
int temp = a;
a = b;
b = temp;
}
...
int a = 1, b = 2 ;
swap(&a, &b);
printf ("after swap : a=%d b=%d\n", a,b);
swapwrong(&a, &b);
printf ("after swapwrong : a=%d b=%d\n", a,b);
This will print
after swap : a=2 b=1
after swapwrong : a=2 b=1
So this changes this copy's value?
Yes. Only the copy that is local to plusInt
If I want to change the value of the original variable I use a pointer to it and then increase a value right?
Yes. To change a variable in another scope we must preform an indirection. That is achieved by passing the variables address.
But what is the use/why would someone want to change the value of the original variable and not the copy?
The simplest use case one comes across early while learning to program, is when trying to insert a node into the head of a linked list. Your addition function must modify the structure in a calling context.
Well, maybe this is not the simplest. Consider this function
void swap_ints(int l, int r) {
int t = l; l = r; r = t;
}
int main(void) {
int x = 1, y = 2;
swap_ints(x, y);
// Were they swapped?
}
But what is the use/why would someone want to change the value of the
original variable and not the copy?
You can change the copy variable, but this variable will not be available when you code exits the function.
Also, we don't generally call a function just for doing a simple increment. The code
int plusInt(int x){
return ++x;
}
can very well in replace as
x++
instead of calling a function. In optimized mode, compilers may decide to get rid of this function by in-lining the change the code wants to do
We use copy variables in many cases, e.g displaying the value of the variable or in the places where you don't want to reflect any accidental changes
There are many applications of the passing parameters to a function by the pointer. E.g.:
When you pass a parameters to a function, as you mentioned, a space in the stack is allocated and such parameters are copied to this space. This operation may be an expensive, so you may consider to pass such parameters by the pointer. Then the pointer to your data will be passed to your function (i.e., will be copied to the stack). In such case you may consider to put the const with such parameters to prevent an "unexpected" changing of their values (as usually done with the char*).
Sometimes you actually need to change a value of such parameter. Pay your attention to that this will be done "in-place". I.e. there will no a copying operations. In the (modified) your example we may to do something like this:
void increment(int* i)
{
if(i)
++*i;
}
In this example there is no any copying operations (as far of the input parameters, as of the result of the function). Moreover, as you can see, we can to pass the NULL as the value of the i. An algorithm of your function may to handle such the case in a different ways (e.g., to skip this parameter etc).
Using of this method of parameter's passing is suggests itself when you need to change a value of many parameters in one function.
I'm trying to understand the behavior of pointers in C in context of passing them as arguments to function, so I tried messing around and making the following test case:
void function1(int argument)
{
argument=4;
}
and
void function2(int* argument)
{
*argument=5;
}
if I run the following statements:
int var1;
int* var2;
function1(var1);
function1(*var2);
function2(&var1);
function2(var2);
In which cases will changes made to the variables be reflected in the calling function?
I tried running the following sample code but am not able to understand output
#include <stdio.h>
void funone(int arg)
{
arg=5;
}
void funtwo(int* arg)
{
*arg=6;
}
int main(void) {
int var1=0;
int *var2;
var2=(int *)malloc(sizeof(int));
*var2=0;
funone(var1);
printf("%d",var1);
funone(*var2);
printf("%d",*var2);
funtwo(&var1);
printf("%d",var1);
funtwo(var2);
printf("%d",*var2);
return 0;
}
the output I'm getting is
0066
what is the implication of this output?
Your code for function1 changes the value of the variable in the function only. So there are no repercussions of the change outside of the function.
Your function2 works (ie, changes the values it points to) because pointers can point to variables outside of it's scope. But your first function keeps the value inside of it's scope, and once the function returns any changes are lost.
This explanation should be present in any good tutorial about pointers.
Neither of those examples will work as you're simply setting the value of the pointer using those functions. Below you will find a version which achieves the behaviour you wish:
void function2(int* argument)
{
*argument=5;
}
The reason for the asterisk before the argument parameter is because you are dereferencing the value of the pointer (you are getting access to it) and therefore you may, at that point change its value...
I hope this helps...
I'm trying to use a separate function to input data using scanf() (outside of main). This new function is supposed to print a line and then receive input from the user. However something appears to be going awry between the scanf in the function and the printf() function in the main that I am testing it with.
I believe that I am receiving a pointer from the function but certain compiler warning are making me wonder if my assumption about the pointer is even correct.
I am confused by the output of this code:
#include <stdio.h>
void set_Info(void);
int main()
{
int scanNum = 0;
set_Info();
printf("%d", &scanNum);
return 0;
}
void set_Info(void) /* start of function definition */
{
int scanNum;
printf("Scan test, enter a number");
scanf("%d",&scanNum);
}
If I provide a number, say 2, the result of the printf statement in the main() is:
2665560
Now, in so far as I am able to tell that output appears to me like a memory address so what i attempted to do to fix that is dereference the pointer in main like so :
int scanNum = 0;
int scanNumHolder;
set_Info();
scanNumHolder = *scanNum;
printf("%d", &scanNumHolder);
I believe that this code makes scanNum variable to become assigned to the dereferenced value of scanNum. However I get the same output as above when I do this. Which leads me to believe one of two things. Either that I am not correctly dereferencing scanNum, or that scanNum is not in fact a pointer at all in this situation.
The most common error I receive from the compiler is:
error: invalid type argument of unary ‘*’ (have ‘int’)
Which makes sense, I suppose, if I'm attempting to treat an int value as a pointer.
If it is the case that scanNum is not being dereferenced correctly, how can I achieve this?
Thank you for the help
*Update
Thanks for the help.
Just to recap
My set_info function needs to be passed an address parameter. The reason an address parameter has to be used is because the local memory of a function is erased after the function call ends. So in order to do work a variable declared in the main function, I pass the address of the variable in question so that when the function ends the changes are not lost.
Inside the main function, when set_info is called with &scanNum as the argument, it passes a reference tp the variable so that it can be assigned the value generated by the scanf statement in the function.
I realize that what I was doing wrong as correctly pointed out by the awesome people of SO, is that I am trying to call set_info like it returns a value but in fact changes the variable like I actually want.
Thanks again for the help!
This function:
void set_Info(void)
{
int scanNum;
scanf("%d", &scanNum);
}
reads the integral number from the standard input and stores it into scanNum variable, which is local variable with automatic storage duration that exists only within the scope of this function.
And the body of your main:
int scanNum = 0;
set_Info();
printf("%d", &scanNum);
defines a local variable called scanNum, then calls a set_Info() function which doesn't affect scanNum defined in main in any way and then it prints the address of scanNum variable.
This is what you are trying to do:
void set_Info(int* num)
{
// read an integer and store it into int that num points to:
scanf("%d", num);
}
int main()
{
int scanNum = 0;
// pass the address of scanNum to set_Info function so that
// changes to scanNum are visible in the body of main as well:
set_Info(&scanNum);
printf("%d", scanNum);
return 0;
}
I also recommend you spend more time reading some book with C basics before you'll continue programming :)
I would pass in the variable into your set_Info function, so that it knows where to save the data. This would then allow you to scan multiple values, and you would simple increment the pointer. Be sure to pass the variable address into set_Info() using &variableName, since that function expects a pointer
#include <stdio.h>
void set_Info(int *pScanNum);
int main()
{
int scanNum = 0;
set_Info(&scanNum);
printf("%d", scanNum);
return 0;
}
//Pass in the pointer to scanNum
void set_Info(int *pScanNum)
{
printf("Scan test, enter a number");
scanf("%d",pScanNum);
}
Get rid of your ampersand! Printf wants an integer not a pointer.
printf("%d", scanNum);
And as liho said, you need to return scanNum from set_info so you can get at it outside of the function.
int scanNum = set_Info();