Changing value of a variable in C - c

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.

Related

why does this program work??returning local struct variables

I have the below program
#include <stdio.h>
#include<stdlib.h>
typedef struct point{
int x;
int y;
}point;
point add(int a, int b){
int c;
point p1;
c= a+b;
p1.x =c;
p1.y =c;
return(p1);
}
int main()
{
int a=20,b=65;
point k;
k = add(a,b);
printf("k.x=%d,k.y=%d\n",k.x,k.y);
return 0;
}
program o/p:
k.x=85,k.y=85
In the function add, I'm creating a temporary variable p1 and assigning it values then returning it.In the main function I use the returned value to print the structure members.
My question is how is this possible ?? once I exit the function add, isn't my local variable p1 destroyed? if yes then how am I still able to see the correct values i.e values assigned to p1 ?? what am I missing??
return p1; takes a value copy of p1 that can be used at the calling site. (For a large struct, that can be quite expensive computationally but I wouldn't worry about that here - if you are in any doubt profile the performance.)
You are correct in saying that the p1 declared in the function is destroyed, but that happens after the copy.
(I've intentionally removed the parentheses around the return variable as keeping them is poor style.)
In your add(int a, int b) method, you are returning a struct variable. In your main method, you are storing the same returned value in another point variable(k). which copies your struct value in k. Hence, you are able to access the values in your printf function.
You are not returning the local variable from add() . Instead, you are copying the local variable into k.
The copy of point p1 is returned and not the point p1 itself

Using entered value in another function

This is my problem:
I need to enter a value X (a number) in the main function and then use this scanned value in other function. This is a short part of my code but I think it's enough to understand what I mean here.
I think it's solvable by using something like this int main(int argc, char *argv[], int Z) and the same thing in void function or using pointers but it didn't work for me when I tried. Maybe someone can explain and show how to do it properly?
int main(int argc, char *argv[]) {
int Z;
.... // rest of the code
printf("Enter Z value:");
Z = scanf("%d", &Z);
}
void function1(float array[100]){
int i, Z, A=0;
for(i=0; i<100;i++){
if(array[i]>Z){
A++;
}
}
You have used the scanf in wrong way. You are overwriting the value read to with scanf with the value returned by scanf.
int Z;
...
if( scanf("%d",&Z) == 1)
// Z is inputted correctly
Now you want to pass it , there are different ways to do that.
Is there any chance that you may change the value of Z in other function to which you passed it as argument and want to retain the changed value in the callee function?
If yes, then you pass the address of it using pointer and then derefrence it to access the original variable.
someFun( &Z );
Then in someFun()
void someFun( int * pZ){
//read it
printf("%d", *pZ);
// write over it
if( scanf("%d",pz) == 1){ /**/ }
*pZ = 2017;
}
If answer was no, then you can simply pass the copy of the variable.
someFun1(Z);
void someFun1(int ZZ){
// read it
printf("%d", *pZ);
//write it
Z = 2017;
//But this change won't be reflected on the `main()` or callee function
}
One thing that might bother you at first is both pZ and ZZ are local variable in the functions someFun() and someFun1() respectively. But their content is different.
In the first case, pZ is a local variable containing the address of the variable Z and ZZ is also a local variable containing the same value as Z. Then you may ask, why is there a difference?
Because in first case by going to the address (de-referrencing it) you are making change to the actual variable local to the main() whose address you passed.
In second case you are not getting the address, you are making chnages to the local variable of someFun1 and that chnage is happening in a completely different place than the original variable's. That's why it isn't reflected in main().
Quoting the standard the scanf returns
ยง7.21.6.4
The scanf function returns the value of the macro EOF if an input
failure occurs before the first conversion (if any) has completed.
Otherwise, the scanf function returns the number of input items
assigned$, which can be fewer than provided for, or even zero, in the
event of an early matching failure.
$: input items successfully matched and assigned

Pass by value-doesn't execute as I want it [duplicate]

This question already has answers here:
What's the difference between passing by reference vs. passing by value?
(18 answers)
Closed 7 years ago.
I do not understand the concept of pass by value in C. Here is my function:
void add(int x){
x = x+1;
}
and when I call the function:
int y=3;
add(y);
but when I compile, I still get 3. I've been told it has something to do with pass-by-value but I still do not understand? Can anyone explain why?
Pass by value creates a copy of the argument. It is this copy that is changed in the function
void add(int x){
x = x+1;
}
Thus the change you make is made to the copy and not the variable in your main scope (that you are expecting to see changed).
If you want to change a variable within a function by passing it as a parameter you cannot pass by value. You could change your function to pass by pointer like this
void add(int* x){
*x = *x + 1;
}
and pass the address of an integer to the function like this
int y=3;
add(&y);
within main()
The pointer is still passed by value so it is a copy of the pointer that is being acted on, but this doesn't matter as you are not changing the pointer itself, you are changing the value of the variable it points to.
This function:
void add(int x) {
x = x + 1;
}
Essentially says this: create a function named add, that returns nothing (void), and takes a single integer argument x. Then you call the function:
y = 3;
add(y);
This says "Set the variable named y to 3. Now call the add() function passing as an argument the current value of y, namely 3. This is no different from
add(3);
The argument x is entirely local to the function add(). It exists only inside the function, and does not affect anything outside it.
So your function dutifully adds 1 to the number you gave it, and then throws it away. Just like you told it to.
C has no "pass by reference" like other languages, where you can tell a function to act on a variable itself rather than its current value. It does, however, have pointers, which can accomplish similar things.
All function arguments in C are passed by value. That means that the parameter (in this case, x defined in add) is initialized to a copy of the value of the argument (in this case, y, which has the value 3).
Since x is a local variable, executing
x = x + 1;
changes the value of x, but that change has no effect after the function returns and x no longer exists.
Note that the argument doesn't have to be the name of a variable. You can legally call your function like this:
add(42);
x is initialized to 42 -- but x = x + 1 certainly isn't going to change the value of 42.
If you want to modify the value, you can have the function return the new value:
int add(int x) {
return x + 1;
}
The caller can do anything it likes with the result, including assigning it back to the variable:
int y = 3;
y = add(y);
Or you can pass the address of the object you want to modify:
int add(int *x) {
*x = *x + 1;
}
and then the caller can do this:
int y = 3;
add(&y);
This is still pass-by-value, but the value being passed is a pointer value, the address of x. It's how we can emulate pass-by-reference in C.
You can solve above by using the code :
int add(int x)
{ x=x+1;
return x;}
then use
a new variable like
k= add(y);
and then print k.

simple pointers to pointers

I know why this works:
#include <stdio.h>
void cool_number(int **number) {
int value = 42;
int *p = &value;
*number = p;
}
int main () {
int *number;
cool_number(&number);
printf("number is %d\n", *number);
return 0;
}
What I don't understand is why this doesn't (in my machine it prints 3700 or something like that).
#include <stdio.h>
void cool_number(int **number) {
int value = 42;
int *p = &value;
int **x = &p;
number = x;
}
int main () {
int *number;
cool_number(&number);
printf("number is %d\n", *number);
return 0;
}
Why aren't both equivalent?
both are evil as they capture the address of a stack variable.
Second one doesn't do what you expect because you are assigning directly to the parameter number, which is only temporary, the first one changes something the parameter number pointers to, which is the same thing as number in main points to.
I assume they're not equivalent because number is passed by value, on the stack, as is standard for function parameters. Any changes that you make directly to number inside of cool_number() are modifying the local copy on the stack, and are not reflected in the value of number in main().
You get around this in the first example by dereferencing number, which tells the computer to modify some specific location in memory that you also happen to have a pointer to back in main(). You don't have this in the second example, so all that happens is that you make the local number pointer point to somewhere else, without actually updating any memory location being referred to back in main(). Thus nothing you do shows up once you get back to main().
And since value is local to the cool_number() function, setting a reference to it that will be accessed after cool_number() returns isn't guaranteed to work and certainly shouldn't be used in any code outside of a trivial/toy example. But in this specific instance it's not really related to why you're seeing different results between the two pieces of code.
As I understand, in both cases, your code is wrong.
In the first case, you are returning an address to a variable allocated on stack, which will be deallocated as soon as the function returns.
In the second case, the error of the first case exists, plus you are passing number by value, so an updation to number will not get reflected in the caller function.
In 'C', arguments are always passed by value. So, you cannot update the argument passed as it is. For Ex:
int func(int a)
{
a = 5; // In this case the value 5 will not be reflected in the caller as what is updated is the local copy of a on the stack
}
int func(int *a)
{
*a = 5; // This update will show in caller as you are directly updating the memory pointed to by a
a = malloc(4); //This update will not show in caller as again you are updating the local copy of stack
}
#include <stdio.h>
void cool_number(int **number) {
int value = 42; /* this "value" hold 42 value,
and it lifetime is only in this function */
int *p = &value; /* here we get the address of "value" in memory */
*number = p;
}
int main () {
int *number;
cool_number(&number); /* after this function the "value" in memory had been recyled
and may be used by other program */
printf("number is %d\n", *number); /* so when we print value here it will be
a unpredictable value, somehow may be crash */
return 0;
}
both the same principle

Understanding functions and pointers in C

This is a very simple question but what does the following function prototype mean?
int square( int y, size_t* x )
what dose the size_t* mean? I know size_t is a data type (int >=0). But how do I read the * attached to it? Is it a pointer to the memory location for x? In general I'm having trouble with this stuff, and if anybody could provide a handy reference, I'd appreciate it.
Thanks everybody. I understand what a pointer is, but I guess I have a hard hard time understanding the relationship between pointers and functions. When I see a function prototype defined as int sq(int x, int y), then it is perfectly clear to me what is going on. However, when I see something like int sq( int x, int* y), then I cannot--for the life of me--understand what the second parameter really means. On some level I understand it means "passing a pointer" but I don't understand things well enough to manipulate it on my own.
How about a tutorial on understanding pointers?
In this case however, the pointer is probably used to modify/return the value. In C, there are two basic mechanisms in which a function can return a value (please forgive the dumb example):
It can return the value directly:
float square_root( float x )
{
if ( x >= 0 )
return sqrt( x );
return 0;
}
Or it can return by a pointer:
int square_root( float x, float* result )
{
if ( x >= 0 )
{
*result = sqrt( result );
return 1;
}
return 0;
}
The first one is called:
float a = square_root( 12.0 );
... while the latter:
float b;
square_root( 12.00, &b );
Note that the latter example will also allow you to check whether the value returned was real -- this mechanism is widely used in C libraries, where the return value of a function usually denotes success (or the lack of it) while the values themselves are returned via parameters.
Hence with the latter you could write:
float sqresult;
if ( !square_root( myvar, &sqresult ) )
{
// signal error
}
else
{
// value is good, continue using sqresult!
}
*x means that x is a pointer to a memory location of type size_t.
You can set the location with x = &y;
or set the value were x points to with: *x = 0;
If you need further information take a look at: Pointers
The prototype means that the function takes one integer arg and one arg which is a pointer to a size_t type. size_t is a type defined in a header file, usually to be an unsigned int, but the reason for not just using "unsigned int* x" is to give compiler writers flexibility to use something else.
A pointer is a value that holds a memory address. If I write
int x = 42;
then the compiler will allocate 4 bytes in memory and remember the location any time I use x. If I want to pass that location explicitly, I can create a pointer and assign to it the address of x:
int* ptr = &x;
Now I can pass around ptr to functions that expect a int* for an argument, and I can use ptr by dereferencing:
cout << *ptr + 1;
will print out 43.
There are a number of reasons you might want to use pointers instead of values. 1) you avoid copy-constructing structs and classes when you pass to a function 2) you can have more than one handle to a variable 3) it is the only way to manipulate variables on the heap 4) you can use them to pass results out of a function by writing to the location pointed to by an arg
Pointer Basics
Pointers And Memory
In response to your last comment, I'll try and explain.
You know that variables hold a value, and the type of the variable tells you what kind of values it can hold. So an int type variable can hold an integer number that falls within a certain range. If I declare a function like:
int sq(int x);
...then that means that the sq function needs you to supply a value which is an integer number, and it will return a value that is also an integer number.
If a variable is declared with a pointer type, it means that the value of that variable itself is "the location of another variable". So an int * type variable can hold as its value, "the location of another variable, and that other variable has int type". Then we can extend that to functions:
int sqp(int * x);
That means that the sqp function needs to you to supply a value which is itself the location of an int type variable. That means I could call it like so:
int p;
int q;
p = sqp(&q);
(&q just means "give me the location of q, not its value"). Within sqp, I could use that pointer like this:
int sqp(int * x)
{
*x = 10;
return 20;
}
(*x means "act on the variable at the location given by x, not x itself").
size_t *x means you are passing a pointer to a size_t 'instance'.
There are a couple of reasons you want to pass a pointer.
So that the function can modify the caller's variable. C uses pass-by-value so that modifying a parameter inside a function does not modify the original variable.
For performance reasons. If a parameter is a structure, pass-by-value means you have to copy the struct. If the struct is big enough this could cause a performance hit.
There's a further interpretation given this is a parameter to a function.
When you use pointers (something*) in a function's argument and you pass a variable you are not passing a value, you are passing a reference (a "pointer") to a value. Any changes made to the variable inside the function are done to the variable to which it refers, i.e. the variable outside the function.
You still have to pass the correct type - there are two ways to do this; either use a pointer in the calling routine or use the & (addressof) operator.
I've just written this quickly to demonstrate:
#include <stdio.h>
void add(int one, int* two)
{
*two += one;
}
int main()
{
int x = 5;
int y = 7;
add(x,&y);
printf("%d %d\n", x, y);
return 0;
}
This is how things like scanf work.
int square( int y, size_t* x );
This declares a function that takes two arguments - an integer, and a pointer to unsigned (probably large) integer, and returns an integer.
size_t is unsigned integer type (usually a typedef) returned by sizeof() operator.
* (star) signals pointer type (e.g. int* ptr; makes ptr to be pointer to integer) when used in declarations (and casts), or dereference of a pointer when used at lvalue or rvalue (*ptr = 10; assigns ten to memory pointed to by ptr). It's just our luck that the same symbol is used for multiplication (Pascal, for example, uses ^ for pointers).
At the point of function declaration the names of the parameters (x and y here) don't really matter. You can define your function with different parameter names in the .c file. The caller of the function is only interested in the types and number of function parameters, and the return type.
When you define the function, the parameters now name local variables, whose values are assigned by the caller.
Pointer function parameters are used when passing objects by reference or as output parameters where you pass in a pointer to location where the function stores output value.
C is beautiful and simple language :)
U said that u know what int sq(int x, int y) is.It means we are passing two variables x,y as aguements to the function sq.Say sq function is called from main() function as in
main()
{
/*some code*/
x=sr(a,b);
/*some other code*/
}
int sq(int x,int y)
{
/*code*/
}
any operations done on x,y in sq function does not effect the values a,b
while in
main()
{
/*some code*/
x=sq(a,&b);
/*some other code*/
}
int sq(int x,int* y)
{
/*code*/
}
the operations done on y will modify the value of b,because we are referring to b
so, if you want to modify original values, use pointers.
If you want to use those values, then no need of using pointers.
most of the explanation above is quite well explained. I would like to add the application point of view of this kind of argument passing.
1) when a function has to return more than one value it cannot be done by using more than one return type(trivial, and we all know that).In order to achieve that passing pointers to the function as arguments will provide a way to reflect the changes made inside the function being called(eg:sqrt) in the calling function(eg:main)
Eg: silly but gives you a scenario
//a function is used to get two random numbers into x,y in the main function
int main()
{
int x,y;
generate_rand(&x,&y);
//now x,y contain random values generated by the function
}
void generate_rand(int *x,int *y)
{
*x=rand()%100;
*y=rand()%100;
}
2)when passing an object(a class' object or a structure etc) is a costly process (i.e if the size is too huge then memory n other constraints etc)
eg: instead of passing a structure to a function as an argument, the pointer could be handy as the pointer can be used to access the structure but also saves memory as you are not storing the structure in the temporary location(or stack)
just a couple of examples.. hope it helps..
2 years on and still no answer accepted? Alright, I'll try and explain it...
Let's take the two functions you've mentioned in your question:
int sq_A(int x, int y)
You know this - it's a function called sq_A which takes two int parameters. Easy.
int sq_B(int x, int* y)
This is a function called sq_B which takes two parameters:
Parameter 1 is an int
Parameter 2 is a pointer. This is a pointer that points to an int
So, when we call sq_B(), we need to pass a pointer as the second
parameter. We can't just pass any pointer though - it must be a pointer to an int type.
For example:
int sq_B(int x, int* y) {
/* do something with x and y and return a value */
}
int main() {
int t = 6;
int u = 24;
int result;
result = sq_B(t, &u);
return 0;
}
In main(), variable u is an int. To obtain a pointer to u, we
use the & operator - &u. This means "address of u", and is a
pointer.
Because u is an int, &u is a pointer to an int (or int *), which is the type specified by parameter 2 of sq_B().
Any questions?

Resources