Parameter passing in C functions [duplicate] - c

This question already has answers here:
What (actually) happens, when a function with the warning "control reaches end of non-void function" is called?
(7 answers)
Closed 7 years ago.
I am newbie. So please bear with me,
#include<stdio.h>
int abc(int k)
{
k++;
}
int main()
{
int a=1;
printf("%d",abc(a));
return 0;
}
Output of above program is : 1
My question is shouldn't the output should be '2' as the actual parameter is passing the value of '1' to the formal parameter and it has to be incremented by the function abc.
And when I change the function call to
printf("%d",abc(1));
The output is some garbage value.
How does parameter passing work here? Please explain.

The unexpected results you are getting are not resulting from the "parameter passing", but from the fact that the abc function does not return any value. You should use return k; statement to get the output you are expecting. But as for parameter passing, they are passed by value, i.e. the passed value is copied to a temporary location k (visible in the function only), and not modified outside of it.

The code example you have passes a by value. You could think of it as a copy of a. You code modified with comments:
#include<stdio.h>
int abc(int k)
{
// k is a copy of a, it is not a, since k is a copy, it has the
// value of a at the point of the copy. So, k is 1
k++; // k is now 2
return k; // return the computed value to the caller and destroy k
}
int main()
{
int a=1;
// as previously written, without the return statement in abc()
// this function returned nothing. So, the compiler just arranges
// for something to be used from the stack where the return would
// have placed 2. (I'm not terribly familiar
// with assembly and so I'm not sure which register it would use).
// That's why you get non-nonsensical data, whatever is in memory is
// what you get and without the return statement, there's nothing
// meaningful there.
// Also, as I commented above, abc() takes a **copy** of a. Thus,
// the contents of a are unmodified. See how the printf() is
// changed. What does it print?
printf("%d %d",abc(a), a);
return 0;
}

Related

C, pass by value, in Linux [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have a function as follows:
void foo (int *check){
*check= 9;
printf("*check: %d\n",*check);
//when I print "*check" here, the value changes as 9.
}
This is the main function.
void main () {
int check=5;
foo(&check);
printf("check: %d\n",check);
//when I print "check", gives me 5.
}
I want to change the value of "check" variable but it does not work. Where am I making mistake? Thank you!
I am using makefile while running it.
Edit: malloc is deleted now it gives me Segmentation fault (core dumped) error
When you malloc within foo, the dereference now points to the value malloced within the function's scope. This means that the value within the function is changed and not the value outside of the function. To correct this, you don't need to malloc within the function to change the value of check:
void foo (int *check) {
*check= 9;
}
void main () {
int check = 5;
foo(&check); // check is now 9
}
You are doing everything just fine, the only thing that is wrong is trying to malloc the variable you passed to the function , since it is already allocated on stack. In order to do what you're trying to do, you should declare the integer as pointer to integer (int *check) outside the function, and avoid using the & character when calling the function with the pointer as parameter.
To change a variable through a function you need to pass it by reference, not value. Your title and code do not match.
Here is a version with both kinds of arguments, side by side:
#include <stdio.h>
int foo(int *ref, int val) {
*ref = 1122; // by reference
val = 1155; // by value
printf("inside:\n%d %d\n", *ref, val);
return val; // otherwise "val=1155" is lost
}
int main(void) {
int ree = 12; // "referencee"
int v = 15;
printf("main:\n%d\n", foo(&ree, v)); // return value (1155)
printf("%d %d\n", ree, v); // 1122 and 15
}
ree is passed as &ree to ref; this address/pointer gets dereferenced inside the function with *ref to change ree's value.
You passed the variable check to the function foo by reference through a pointer to it
int check=5;
foo(&check);
So dereferencing the pointer you could get a direct access to the variable check and could change it like
*check= 9;
However within the function you reassigned the pointer with a new address of a dynamically allocated memory
check= malloc(sizeof(int));
So now the pointer check doe not point to the original object passed to the function by reference. As a result this statement
*check= 9;
changes the dynamically allocated object of the type int instead of changing the variable passed to the function by reference.
Edit: malloc is deleted now it gives me Segmentation fault (core
dumped) error
It is a bad idea to change such dramatically the code in the question because it will only confuse readers of the question and answers. Neither segmentation fault should occur. It seems the new provided code in the question does not correspond to the actual code that generates a segmentation fault.
Here is a demonstrative program. It compiles and runs successfully.
#include <stdio.h>
void foo ( int *check )
{
*check = 9;
printf( "Inside foo check = %d\n", *check );
}
int main(void)
{
int check = 5;
printf( "Before foo check = %d\n", check );
foo( &check );
printf( "After foo check = %d\n", check );
return 0;
}
The program output is
Before foo check = 5
Inside foo check = 9
After foo check = 9

If a variable is defined previously and is waiting on a function to return a value, what is the value of that variable?

This is for programming in C.
Say I had the follow code in my program:
int fun1(int x);
int main (void)
{
int a = 5;
a = fun1(10);
}
int fun1(int x)
{
\\Program arbitrarily ends here
return x;
}
In my memory diagram what would the value of a be assuming the program terminates before fun1 is able to return a value? Would the value of a be undetermined (??) or would it be 5?
The value of a is already initialized to 5. Now, according to the condition, you want to know the results of that circumstance when the fun1() ends before it could return a value; assume the following:
int fun1(int x)
{
// return x;
}
Here we've supposed the function quits before returning the value.
You'll still get the output 5 before, during or after execution of the program since it returns nothing but the variable a is preassigned to 5 and it can't be changed to 10 unless the function returns 10 and assigns to the variable.
But remember, if you don't assign anything to a, then it may show an unexpected value (I got 4195638 when used printf() for a).

Understanding strange return syntax: return(*scriptFunction[x])(arguments);

I know the title for this is horrendous and for this I am sorry; I honestly had no idea how to ask my question as I am not well educated on this matter. Below there is a small bit of code that my question concerns as I have NO idea what is going on or if it is even valid! Although, I suspect it is valid.
return(*scriptFunction[x])(arguments);
From my understanding, you can only return 1 value in C (you can have multiple return statements but that is different and off topic). What is the above statement actually doing?
The code:
return(*scriptFunction[x])(arguments);
actually is only returning one value.
The variable scriptFunction will be an array of function pointers(1). You look up element number x of that array, and call that function, passing the argument arguments. Then the return value from that function is what you return to your caller.
Other than the function pointer aspect, it's no different to return sqrt(42).
By way of example, the following program demonstrates how this can be done:
#include <stdio.h>
// Two simple functions which add a fixed value.
int fnPlus3 (int n) { return n + 3; }
int fnPlus7 (int n) { return n + 7; }
// An array holding those two functions.
int (*scriptFunction[])(int) = { fnPlus3, fnPlus7 };
int main (void) {
// Call first function in array.
int x = 0;
printf ("%d\n", (*scriptFunction[x])(100));
// Then call second one.
x = 1;
printf ("%d\n", (*scriptFunction[x])(100));
return 0;
}
Although it prints the return value from the function rather than returning it again, it still uses the same expression and you can see it calls a different function based on the value of x:
103
107
(1) Or some form of equivalent, such as a pointer to an array of function pointers, or a pointer to a single function pointer (assuming x is always set to zero in that latter case).
Presumably scriptFunction is an array of pointers to functions. *scriptfunction[x] is then the dereferenced pointer to function (the x-th one). Finally, *scriptfunction[x](arguments) represents the invocation of that function applied to arguments, so the result of that function is what's returned in the end.
Side comment: the * is not really necessary. A pointer to function does not need to be dereferenced to call the function, i.e. you can use
return scriptFunction[x](arguments);
instead.
From the looks of it, it seems the line return (*scriptFunction[x])(arguments); scriptFunction is an array of function pointers, and this is simply invoking the function at position indexed by variable x and sending arguments variable contents as its input.
The return value of this invoked function is what ultimately gets returned.
This working example should be useful:
#include <iostream>
using namespace std;
void func_a(int i)
{
cout << "func_a: " << i << endl;
}
void func_b(int i)
{
cout << "func_b: " << i << endl;
}
int main()
{
void (*funcs[])(int) = { func_a, func_b };
for(int i = 0; i < 2; ++i)
(*funcs[i])(i+1);
return 0;
}
The output is below:
➜ /tmp g++ test.cpp -o test
➜ /tmp ./test
func_a: 1
func_b: 2
Also, for future reference, you should consult: How to ask good questions?

What will be the output of this?

I was doing this question and I have a doubt.
#include <stdio.h>
int main(void)
{
int fun (int);
int i=3;
fun(i=fun(fun(i)));
printf("%d\n",i);
return 0;
}
int fun ( int i )
{
i++;
return(i);
}
I have a doubt when it gets to
fun ( i = 5 )
What happens with this? Will the value of i go to 6 or it will be 5.
According to me, it should be 6. But that is not the correct answer.
In C, parameters are passed by value. The variable i in the main function is actually different from the i inside fun(), because its value is copied when it is passed into the function.
When you call i = fun(fun(i)), 5 is isassigned into i in the main function. However, the call to fun(5) that returns 6 does not assign its result back into i, leaving it unchanged. When the output is printed, i is still 5.
This is related to scope. In the function scope, variables defined in that scope or the parameters pass in does not any effect on outer scope variables, unless it is a pointer. So, the output of fun will be assigned to i in the fun(i = 5) but the internal operations of fun, do not effect the outer scope i. So it stays as it is before fun last call. The output is 5.
The result of the call to fun() is not assigned to i. Therefore 5 is expected, not 6.

De-Referencing a pointer passed from another function to main()

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();

Resources