Hey all. I'm working on a project for school where I need to pass a few parameters by reference through multiple functions. I understand how I can pass by reference from where the variables are declared to another function, like this:
main() {
int x = 0;
int y = 0;
int z = 0;
foo_function(&x, &y, &z);
}
int foo_function(int* x, int* y, int* z) {
*x = *y * *z;
return 0;
}
However, how would I pass x, y, and z from foo function to another function? Something like this gives me all kinds of compiler warnings.
int foo_function(int* x, int* y, int* z) {
*x = *y * *z;
bar(&x, &y, &z);
return 0;
}
int bar(int* x, int* y, int* z) {
//some stuff
}
Just use:
bar(x, y, z);
X, Y, and Z are already pointers - just pass them directly.
Remember - a pointer is a location in memory. The location doesn't change. When you dereference the pointer (using *x = ...), you are setting the value at that location. But when you pass it into a function, you are just passing the location in memory. You can pass that same location into another function, and it works fine.
You don't need to do anything, they're already references.
int foo_function(int* x, int* y, int* z) {
bar(x, y, z);
return 0;
}
int bar(int* x, int* y, int* z) {
//some stuff
}
In foo_function x y and z are already pointers (int*), so you can do bar(x, y, z).
int foo_function(int* x, int* y, int* z) {
*x = *y * *z;
/* x, y and z are pointers to int
&x, &y and &z are pointers to pointer to int
bar expects pointers to int, so call bar as:
*/
bar(x, y, z);
return 0;
}
C has no notion of passing by reference. Parameters are always passed by value. However, when using pointers, this value is actually a pointer to your actual value.
But what you are doing with
foo_function(&x, &y, &z);
is actually trying to get an address of the pointer, which is essentially meaningless (you would pass an int** instead of an int*).
So,
foo_function(x, y, z);
would be the correct call, as x, y and z are already pointers and you don't need to make the pointing chain any longer :)
Related
I wrote a function pointer that has all void* so that it can be used for any numeric value
int
float
double.
But it is working only for the int addition function
For float and double addition functions, it throws compile time error.
Why is that so ?
If you uncomment the last two printf lines, you would receive error
#include<stdio.h>
int int_add(int x, int y) {
return x + y;
}
float float_add(float x, float y) {
return x + y;
}
double double_add(double x, double y) {
return x + y;
}
void* do_operation(void* (*op)(void*, void*), void* x, void* y) {
return op(x, y);
}
void main(void) {
printf("Sum= %d\n",(int*) do_operation(int_add, 1, 2));
/*printf("Sum= %f\n",(float*) do_operation(float_add, 1.20, 2.50));*/
/*printf("Sum= %lf\n",(double*) do_operation(double_add, 1.20, 2.50));*/
}
void * is a pointer type. You're not passing pointers, you're passing values, so that's not going to compile. It accidentally "works" for int because pointers themselves are represented as integers by most C compilers.
If you pass pointers to int, float, and double instead of the int, float, and double themselves, you will avoid that compiler error. You'd also need to change int_add and friends to take pointers, and you'd have to make sure you dereferenced the pointers before using them. You'll also have to return pointers, which means you'll have to malloc some memory on the heap, because the stack memory assigned to your local variables will be invalid once your function exits. You'll then have to free it all later... in the end, this is going to result in something considerably more complicated than the problem it appears you are trying to solve.
I have to ask why you are trying to do this? C is really not the best language for this type of pattern. I'd suggest just calling the int_add, float_add, etc. functions directly instead of trying to abstract them in this way.
So as per #charles-srstka suggestion I rewrote the code and then it worked as I wanted
#include<stdio.h>
#include<stdlib.h>
int* int_add(int *x, int *y) {
int *c = (int *)malloc(sizeof(int));
*c = *(int*)x + *(int*)y;
return c;
}
float* float_add(float *x, float *y) {
float *c = (float*)malloc(sizeof(float));
*c = *(float*)x + *(float*)y;
return c;
}
void* do_operation(void* (*op)(void*, void*), void* x, void* y) {
return op(x, y);
}
void main(void) {
int a = 1;
int b = 2;
int *c;
c = do_operation(int_add, &a, &b);
printf("%d\n",*c);
free(c);
float x = 1.1;
float y = 2.2;
float *z;
z = do_operation(float_add, &x, &y);
printf("%f\n",*z);
free(z);
}
Can someone please explain me the purpose of func(&_) and void? I am not sure how the whole program works.
void func(int *xp);
int
main(void)
{
int x, y;
x = 5;
func(&x);
y = x-3;
func(&y);
printf("%4d%4d\n", x, y);
return(0);
}
void
func(int *xp)
{
int y;
y = *xp * 2;
*xp = y - 3;
}
Your function demands a pointer argument. If you want to pass a non-pointer variable to that function call, you must provide it's address, using the & notation.
Does anyone know of a way I can change the values of variables that are defined locally?
#include <stdio.h>
int change(int x, int y);
int main()
{
int x = 10;
int y = 20;
change(x,y);
printf("x:%d y:%d\n", x, y);
}
int change(int x, int y)
{
x = 20;
y = 30;
return(x);
return(y);
}
I want x and y to print 20 and 30 in main().
I tried returning the values, but that didn't work. Is there another method I might be able to use? I was thinking pointers, but I don't know where to begin.
Use pointers:
void change(int *x, int *y)
{
*x = 20;
*y = 30;
}
and call the function like: change(&x, &y); For readability you may want to use different names than x and y for the change parameters as they are not of the same type as the x and y variables declared in main.
Some options:
1) Pass by refernce: int change(int &x, int &y);
2) Return an array and change current values:
int* temp = new int[2];
temp[0]=x+10;
temp[1]=y+10;
return temp;
3) Return to printf directly:
printf("x:%d y:%d\n", change(x,y)[0], change(x,y)[1]);
yes it's very easy
just pass the parameters by reference to the change function
so instead of
int change(int x, int y) >
int change(int& x, int& y)
and it will works fine
how to pass array as arguments in C?
int a,b,c[10];
void Name1(int x, int y, int *z)
{
a = x;
b = y;
c = z;
}
I try to pass it as argument, but it does not build, how to fix it?
And is the declaration of void Name1(int x, int y, int *z); is the same as void Name1(int x, int y, int z[])? does the void Name1(int x, int y, int z[]) will be treated as void Name1(int x, int y, int *z); by compiler?
When you pass array as an argument to function it decays as an pointer to its first element.
So,
void Name1(int x, int y, int *z)
will work.
But arrays are not assignable so:
c = z;
does not work, you will need to explicitly copy each array element from source to destination.
Doing c = z;, you're assigning to a non l-value, which is not allowed. It's like doing &c[0] = &z[0];.
There are a couple of answers here, but I don't think any of them are completely sufficient, so...
basically you can either copy the array or use the pointer, but either way you will need to keep track of the length.
int a,b, *c, len;
void Name1(int x, int y, int *z, int z_len)
{
a = x;
b = y;
c = z;
len = z_len;
}
//usage:
int arr[5];
Name1(1,2,arr /* or &arr[0] ,*/, sizeof(arr )/ sizeof (int));
if you never need to add items this will be sufficient... If you do it gets more complicated...
it is important to keep the length around so that you know how many elements you have, even if you are going to copy them.
c=z; is invalid
c pointer doesnt have memory to save the z address.
you can say:
int a,b,*c;
c=(int *)calloc(10,sizeof(int) );
void Name1(int x, int y, int *z)
{
a = x;
b = y;
c = z;
}
In C if you have the following code:
for (size_t x, y = someValue; y > 0; y -= x, ptr1 += x, ptr2 += x)
{
// do stuff
}
Will the variable y also be of the type size_t or would it be an int?
a declaration of
int a,b,c;
size_t x,y,z;
means that all of a,b,c are same type (int) as are x,y,z (size_t)
The declaration inside a for-loop is no different -- and in your example both x and y are of type size_t
however in your example x is not initialized (only y is set to somevalue) -- and unless the body of the loops set it to something you will find that y -= x is going to give you random undefined results.
It's just the same as if you do:
size_t x, y = someValue;
In such situation both x and y are size_t and y = someValue.
y would be the same time as x, size_t, just as it would with the same expression outside of a for loop:
size_t x, y = someValue;
One simple way to find out is to just print the size of the variables for yourself, as long as sizeof(size_t) != sizeof(int) (if it is, just change size_t to char to make the difference evident).
In your example yes; x and y are both of type size_t. However, to add to your confusing, consider declaration:
int *x, y;
In this case x is a pointer to int, but y is just a int.
for (size_t x, y = someValue; y > 0; y -= x, ptr1 += x, ptr2 += x)
{
// do stuff
}
x and y are both "size_t" (usually 4 bytes on most platforms)
y is initialized to "someValue".
x, however, is UNINITIALIZED.
int
main (int argc, char *argv[])
{
size_t x, y = 1;
printf ("x=%d, y=%d, sizeof(x)=%d...\n",
x, y, sizeof (x));
return 0;
}
x=4201366, y=1, sizeof(x)=4...