How to modify a local variable of one function from other function? - c

int main ()
{
int a, b;
call(&b);
printf("%d, %d",a , b);
}
void call(int *ptr)
{
}
Desired output:
50, 100
How to write the call function so as to modify both the variables to get the desired output??

Not sure where the values 50 and 100 are coming from or exactly what you are asking but maybe this will help with your question.
Since C is pass by value you need to send pointers to actually change the value inside another function.
Since the call function will have pointer values you need to dereference the pointers before changing the value.
Here is an example:
void call(int *a, int *b)
{
*a = 50;
*b = 100;
}
int main()
{
int a, b;
call(&a, &b);
printf("%d, %d\n", a, b);
}

While we are exploring the many ways this output could be achieved, consider that the function could store state in a static variable:
#include <stdio.h>
void call(int *ptr);
int main(void)
{
int a, b;
call(&a);
call(&b);
printf("%d, %d\n",a , b);
}
void call(int *ptr)
{
static int store = 0;
store += 50;
*ptr = store;
}
Program output:
50, 100
Note that you may also be able to do this as follows, without any modifications to main(). But be warned that this method invokes undefined behavior! It is undefined behavior to write to a location past the end of an array object, and in the case of a and b, these are considered to be array objects of size 1. Here we are assuming that this write will work, and that a and b are stored next to each other in memory. We further assume that a has the higher address in memory.
I would say that you should never do this, but I can see no other way to modify a from the function call() without knowing the address of a. You have been warned.
void call(int *ptr)
{
*ptr = 100;
*(ptr + 1) = 50;
}

Try something like this:
void call(int *ptr)
{
*ptr = 100;
}
int main ()
{
int a, b;
a = 50;
call(&b);
printf("%d, %d",a , b);
}
See demo

Maybe you want this:
int main ()
{
int a, b;
call(&a, &b);
printf("%d, %d",a , b);
}
void call(int *ptr1, int *ptr2)
{
*a = 50;
*b = 100;
}

To change a local variable in function a by calling function b you have two options.
1) Let function b return a value that you assign to the variable in function a. Like:
int b() {return 42;}
void a()
{
int x = b();
printf("%d\n", x);
}
This does, however, not seem to be what you are looking for.
2) Pass a pointer to the variable to function b and change the variable through that pointer
void b(int* p) // Notice the * which means the function takes a pointer
// to integer as argument
{
*p = 42; // Notice the * which means that 42 is assigned to the variable
// that p points to
}
void a()
{
int x;
b(&x); // Notice the & which means "address of x" and thereby
// becomes a pointer to the integer x
printf("%d\n", x);
}

int main()
{
int a,b;
call(&b);
printf("%d, %d\n", a,b);
}
int call(int *ptr)
{
int *m;
m = ptr++;
*ptr = 50;
*m = 100;
}

Related

Why does this code won't work? It displays 0

Whenever I compile it displays 0 instead of 11. what is wrong this code? I used a function add. I notice that this works when I'm using an array string.
#include <stdio.h>
#include <stdlib.h>
void add(int result, int a, int b);
int main(void) {
int num1 = 5;
int num2 = 6;
int result1 = 0;
add(result1, num1, num2);
printf("%d", result1);
return 0;
}
void add(int result, int a, int b) {
result = a + b;
}
Arguments of C functions are copies of what are passed, so modifying them in callee will not affect what is passed in caller.
To have functions modify passed things, you should pass pointers to what should be modified.
#include <stdio.h>
void add(int *result, int a, int b); /* add * to make result a pointer */
int main(void) {
int num1 = 5;
int num2 = 6;
int result1 = 0;
add(&result1, num1, num2); /* add & to pass a pointer */
printf("%d", result1);
return 0;
}
void add(int *result, int a, int b) { /* add * to make result a pointer */
*result = a + b; /* add * to dereference the pointer */
}
Because the changes done by the operation performed inside the method add in not visible outside. Those arguments that you have passed are being pass by value
Pass by Value
Pass by Value, means that a copy of the data is made and stored by way
of the name of the parameter. Any changes to the parameter have NO
affect on data in the calling function.
To made those changes visible to the outside you can pass the memory reference of the result variable (i.e., pass-by-reference)
Pass by Reference
A reference parameter "refers" to the original data in the calling
function. Thus any changes made to the parameter are ALSO MADE TO THE
ORIGINAL variable.
For example:
void add(int *result, int a, int b) {
*result = a + b;
}
and call the in the main as follows:
add(&result1, num1, num2);
or return the result of the operation as follows :
int add(int a, int b) {
return a + b;
}
and call it in the main as follows:
result1 = add(num1, num2);

Both call by value and call by reference work?

I thought that calling function by value will never work, and I should always use call by reference, but trying this code...
// call by value
#include<stdio.h>
int Add(int a, int b)
{
int c = a + b ;
return c ;
}
int main()
{
int x = 2 , y = 4 ;
int z = Add(x,y);
printf("%d\n",z);
}
output will be: 6
it works fine in both ways (call by value & call by reference),
// call by reference
#include<stdio.h>
int Add(int* a, int* b)
{
int c = *a + *b ;
return c ;
}
int main()
{
int x = 2 , y = 4 ;
int z = Add(&x,&y);
printf("%d\n",z);
}
output will be: 6
not like the famous swap function example - when calling by value it doesn't swap -
// call by value
#include <stdio.h>
void swap(int a, int b)
{
int temp;
temp = b;
b = a;
a = temp;
}
int main()
{
int x = 1 , y = 2;
printf("x = %d , y = %d\n", x,y);
swap(x, y);
printf("after swapping\n");
printf("x = %d , y = %d\n", x,y);
return 0;
}
.. it only worked calling by reference
// call by reference
#include <stdio.h>
void swap(int *a, int *b)
{
int temp;
temp = *b;
*b = *a;
*a = temp;
}
int main()
{
int x = 1 , y = 2;
printf("x = %d , y = %d\n", x,y);
swap(&x, &y);
printf("after swapping\n");
printf("x = %d , y = %d\n", x,y);
return 0;
}
So How can I judge if "calling by value" going to work or not ?!
So How can I judge that call by value method is valid or not ?!
Well, it depends on what your function is about to do.
In your above example, you only need the values of (x,y) for computing, but you never plan to change their value during your function. While call-by-reference will work in this case, it is unneccessary.
In the other (indirectly given) example you obviously want to change two variable's content (that is - swap it). You can access these variables from the main-function in your Swap-function, but how can you make the change persistent? That's only possible by call-by-reference, because you have to write the changed content into a variable that survives the function.
The following will not work:
// call by value
#include<stdio.h>
void Swap(int a, int b)
{
int c = a;
a = b;
b = c;
// from here on a, b, c will be destroyed
// therefore the change cannot be seen outside the function
}
int main()
{
int x = 2 , y = 4 ;
Swap(x,y);
printf("x: %d --- y: %d\n",x,y);
}
So as a rule to keep in mind:
If you want to make a change that's supposed to survive the function's end, use call-by-reference. If you just work with some data but do not want to (or must not) change their value, use call-by-value.

Initialization makes pointer from integer without a cast - C

Sorry if this post comes off as ignorant, but I'm still very new to C, so I don't have a great understanding of it. Right now I'm trying to figure out pointers.
I made this bit of code to test if I can change the value of b in the change function, and have that carry over back into the main function(without returning) by passing in the pointer.
However, I get an error that says.
Initialization makes pointer from integer without a cast
int *b = 6
From what I understand,
#include <stdio.h>
int change(int * b){
* b = 4;
return 0;
}
int main(){
int * b = 6;
change(b);
printf("%d", b);
return 0;
}
Ill I'm really worried about is fixing this error, but if my understanding of pointers is completely wrong, I wouldn't be opposed to criticism.
To make it work rewrite the code as follows -
#include <stdio.h>
int change(int * b){
* b = 4;
return 0;
}
int main(){
int b = 6; //variable type of b is 'int' not 'int *'
change(&b);//Instead of b the address of b is passed
printf("%d", b);
return 0;
}
The code above will work.
In C, when you wish to change the value of a variable in a function, you "pass the Variable into the function by Reference". You can read more about this here - Pass by Reference
Now the error means that you are trying to store an integer into a variable that is a pointer, without typecasting. You can make this error go away by changing that line as follows (But the program won't work because the logic will still be wrong )
int * b = (int *)6; //This is typecasting int into type (int *)
Maybe you wanted to do this:
#include <stdio.h>
int change( int *b )
{
*b = 4;
return 0;
}
int main( void )
{
int *b;
int myint = 6;
b = &myint;
change( &b );
printf( "%d", b );
return 0;
}
#include <stdio.h>
int change(int * b){
* b = 4;
return 0;
}
int main(){
int b = 6; // <- just int not a pointer to int
change(&b); // address of the int
printf("%d", b);
return 0;
}
Maybe too late, but as a complement to the rest of the answers, just my 2 cents:
void change(int *b, int c)
{
*b = c;
}
int main()
{
int a = 25;
change(&a, 20); --> with an added parameter
printf("%d", a);
return 0;
}
In pointer declarations, you should only assign the address of other variables e.g "&a"..

C: Having an issue with scope

so I'm studying for a final and we are given this block of codeL
#include <stdio.h>
int a;
void addOne(void) {
a++;
printf(“W. a = %d\n”, a);
}
int removeOne(int a) {
int b = a – 1;
printf(“R. b = %d\n”, b);
}
void swap(int a, int *b) {
int temp = a;
a = *b;
*b = temp;
}
int main() {
a = 5;
int b = 20;
if (b > 15) {
int a = 53;
removeOne(b);
addOne(a);
printf(“X. a = %d\n”, a);
}
printf(“Y. a = %d, b = %d\n”, a, b);
swap(a, &b);
printf(“Z. a = %d, b = %d\n”, a, b);
return 0;
}
We are instructed to give the outputs of the program. I'm having trouble with the addone(a) where I came up with 54, the correct answer was 6. Is it 6 because when the function is declared it has the void (don't remember the technical term but the information it takes in to the function) rather than something like int a?
My more direct question is why does the function take the a initialized in the main function rather than the a in the if?
The reason that the answer is 6:
Note at the top that a is declared as a global. Later, in main there is a call to addOne(a) inside of a code block. That code block defines a local variable a as well. The a that is passed in that scope is the local a (53). It is passed into a function that accepts an unnamed void variable. In that function, however, there is a reference to a. Due to scoping, this will be the global a (5), so a++ will result in an output of 6.
That is a horrible exam question.

Memory allocated with malloc does not persist outside function scope?

Hi,
I'm a bit new to C's malloc function, but from what I know it should store the value in the heap, so you can reference it with a pointer from outside the original scope. I created a test program that is supposed to do this but I keep getting the value 0, after running the program. What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
int f1(int *b) {
b = malloc(sizeof(int));
*b = 5;
}
int main(void) {
int *a;
f1(a);
printf("%d\n", a);
return 0;
}
Yes! a is passed by value so the pointer b in function f1 will be local..
either return b,
int *f1() {
int * b = malloc(sizeof(int));
*b = 5;
return b;
}
int main() {
int * a;
a = f1();
printf("%d\n", *a);
// keep it clean :
free(a);
return 0;
}
or pass a's address
int f1(int ** b) {
*b = malloc(sizeof(int));
**b = 5;
}
int main() {
int * a;
f1(&a);
printf("%d\n", *a);
// keep it clean :
free(a);
return 0;
}
It looks like you're misunderstanding a fundamental part of how C works - namely that it is a 'pass-by-value' language. In order for main() to know about the memory you allocated, you have to get it back out. The following code will do you what you want:
int f1(int **b)
{
*b = malloc(sizeof(int));
**b = 5;
}
int main(int argc, char **argv)
{
int *a;
f1(&a);
printf("%d\n", *a);
return 0;
}
There are a couple differences between this code and yours; first, the signature of f1() has changed, so that it can return the result of the malloc() call in the passed in pointer. Next, the call to f1() has been changed to pass the address of a rather than a itself - important if you want it to be 'filled-in' by f1(), so to speak. Finally, the printf() in main() has been changed to print out the pointed-to value rather than the pointer itself.
The memory itself persists, but it leaks because you're not providing the allocated pointer to the caller. Also, you're printing a when you should be printing *a. Finally, you're not returning an int from f1.
Try:
void f1(int **b) {
*b = malloc(sizeof(int));
**b = 5;
}
int main() {
int *a;
f1(&a);
printf("%d\n", *a);
free(a);
return 0;
}
Lets suppose you assign a value of NULL to a before you call function f1. Now the way f1 is defined it takes its argument(pointer to an int) by value. That is b will be another variable of type int * which will be a copy of a. So b too will have a value of NULL. Now in f1 you change the value by b by assigning it the address of memory allocated dynamically using malloc. Lets say that memory address is 0x123. As a result of this assignment, b has changed its value from NULL to 0x123 but a(in main) continues to hold NULL, because changing b will not change a, as they are two separate variables. As a result of this when you return from function f1 a will remain unchanged.
There are 2 ways to solve this. One you can make the function f1 return the value of the changed b and then assign it back to a in main and two, you can pass the a by address so that any changes made in f1 will affect a in main too.
// f1 now returns the value of b.
int* f1() {
int *b = malloc(sizeof(int));
*b = 5;
return b;
}
int main() {
int *a = NULL;
a = f1(); // assign the return value of f1 to a.
printf("%d\n", *a); // prints 5...not its *a not just a.
return 0;
}
.
// f1 now takes the address of a.
void f1(int **b) {
*b = malloc(sizeof(int)); // you are actually altering a indirectly.
**b = 5;
}
int main() {
int *a = NULL;
f1(&a); // now pass the address of a to f1.
printf("%d\n", *a); // prints 5...not its *a not just a.
return 0;
}
The address int *b is deleted when the function return. To save it, you need to use a pointer of a pointer
int f1(int ** b) {
*b = malloc(sizeof(int));
**b = 5;
}
Your problem is actually not related to malloc, but rather the fact that you're passing the value the pointer currently holds, rather than the address of it. Try the following:
int f1(int ** b) {
*b = malloc(sizeof(int));
**b = 5;
}
int main() {
int * a;
f1(&a);
printf("%d\n", *a);
return 0;
}
By passing the pointer value as you were, there was no way for the value malloc created to be stored into the pointer.

Resources