My question is in general how to use pointers in functions correctly.
if to be more specific I need to write a function the recives 3 values from a user and then retruns it to the main one for further actions.
This is the code I have written so far:
#include <stdio.h>
#include <conio.h>
int inputThree(int, int, int);
int sortTwo(int, int);
int sortThree(int, int);
int main()
{
int a=0, b=0, c=0;
printf("before: func %d \n", b);
inputThree(a,b,c);
printf("after func: %d%d%d \n",a,b,c);
getch();
}
int inputThree(int a, int b, int c)
{
printf("Input three integers values: \n");
scanf("%d%d%d", &a, &b, &c);
return 0;
}
I'm intersted in understanding how to keep the values of scanf via pointers. When I return to the main function they are lost because they aren't global...
Also, I couldn't leave the function inputthree without parameters even though I want it to get them from scanf itself, so I had to put some values for it to run.
thanks in advance!
Pass pointers to the variables from main to inputThree.
Change the function declaration.
int inputThree(int* aPtr, int* bPtr, int* cPtr);
Change the call.
inputThree(&a, &b, &c);
Change the implementation.
int inputThree(int* aPtr, int* bPtr, int* cPtr)
{
printf("Input three integers values: \n");
scanf("%d%d%d", aPtr, bPtr, cPtr);
return 0;
}
You can either return a struct or make a function that handles passed pointers as argument.
#include <stdio.h>
struct Foo{
int x;
int y;
};
//one way
struct Foo do_work();
//or another
void do_work(int *x, int *y);
int main(void) {
return 0;
}
struct Foo do_work(){
//e.g.
struct Foo foo;
foo.x = 1;
foo.y = 2;
return foo;
}
void do_work1(int *x, int *y){
//e.g
*x = 1;
*y = 1;
}
Technically, only 1 thing (or none) can be returned from a function at a time. If you wanted to change the values of two or more variables via a function even after the function ends, you would need to pass into the function's parameters/arguments the memory reference of the variable.
Related
Variables declared as auto variables are local to the blocks in which they are defined in C.
Consider the code below,
#include<stdio.h>
#include<string.h>
char *fun();
int main()
{
char *s;
s= fun();
printf("%s\n", s);
return 0;
}
char *fun()
{
char buffer[30];
strcpy(buffer, "RAM");
return (buffer);
}
This is a code I found on net (it was a MCQ question). The output is unpredictable and so throws error since buffer is an auto array and will die when the control go back to main. Thus s will be pointing to an array , which not exists.
Now consider this code.
#include<stdio.h>
int sum(int x,int y)
{
int c=x+y;
return c;
}
int main()
{
int a=1,b=2;
int c=sum(a,b);
printf("%d",c);
}
In this code, the variable c is also an auto variable declared inside the function sum which means it is local to that function and cannot be accessed outside the function. But how does this code compile successfully without throwing any error. Why?
The difference is that in the first example you're returning a pointer with the address to a variable. This pointer is not valid after the variable goes out of scope. In your second example, you're just copying the value of the variable.
This works:
int sum(int x,int y) {
int c=x+y;
return c;
}
But not this
int *sum(int x,int y) {
int c=x+y;
return &c;
}
However, this does, because it's not an auto variable:
int *sum(int x,int y) {
static int c=x+y;
return &c;
}
I am trying to print an int a before and after calling a set function to set the value of a. I am doing this in C. When I compile it I have no errors but when I attempt to run it, I get a segmentation fault.
Here is what I have so far:
#include <stdio.h>
int main(){
int* a;
printf("%d",*a);
set(10);
printf("%d", *a);
return 0;
}
int set(int*a, int val){
*a = val;
return *a;
}
int main(){
int* a;
printf("%d",*a);
What you have there is a pointer to an int rather than an actual int.
And, while that's the correct way to print the int it points to, unfortunately it points to an arbitrary memory location which is why you're crashing.
You are not allowed to dereference arbitrary pointers, they have to point to something valid, such as if you begin your code with:
int main(){
int target_of_a = 42;
int *a = &target_of_a;
printf ("%d", *a);
In addition, you probably should be calling set with something like:
set (a, 10);
something the compiler would generally warn you about though, in this case, it would probably just say it didn't know about set at the time you called it. If it had known, it could have told you about the parameter mismatch.
One way for you to acheive that is to ensure you have a prototype defined for the function before you call it:
int set(int*,int);
or just move the function to before main. With all those changes (and a bit of a general tidy up), you'd end up with:
#include <stdio.h>
int set (int *a, int val) {
*a = val;
return *a;
}
int main (void) {
int target_of_a = 42;
int *a = &target_of_a;
printf ("%d\n", *a);
set (a, 10);
printf ("%d\n", *a);
return 0;
}
The wisdom of returning the variable you're changing is also debatable but there are situations where that might be useful (such as if you want to us it immediately without another statement: printf ("%d\n", set (a, 10)); for example) so I've left that as is.
I should also mention that it's a little unusual to artificially create a pointer variable in a situation like this.
Now it may be that your code is just a simplification of some more complex scenario where you already have a pointer but, if not, the usual way to do this would be to just have the int itself and just use & to create one on the fly:
#include <stdio.h>
int set (int *a, int val) {
*a = val;
return *a;
}
int main (void) {
int a = 42;
printf ("%d\n", a);
set (&a, 10);
printf ("%d\n", a);
return 0;
}
This code should work:
#include <stdio.h>
#define FIRST_VALUE 20
#define SECOND_VALUE 10
int main(){
int a = FIRST_VALUE; /* Declare a as an int variable. */
printf("Before set: a = %d\n",a); /* Print the first value. */
set(&a, SECOND_VALUE); /* Pass the ADDRESS of a to set. */
printf("After set: a = %d\n", a); /* Print the new value of a. */
return 0;
}
int set(int*a, int val){
*a = val;
return *a;
}
Note that the variable a in main() is not the same as the variable a in set(); you have to pass a pointer to a to set() in order for set() to operate on it.
Try this:
And remember, all functions before the main() (if you're using only one file)
Take a read on value and reference params.
#include <stdio.h>
int set(int* a, int val){
*a = val;
}
int main(){
int a = 2;
printf("%d\n", a);
set(&a, 10);
printf("%d\n", a);
return 0;
}
Basically, why does it not just print the integers that are entered. Right now it just prints garbage value, but I do not know why it cannot access the values stored after it leaves the function. It only seems to get messed up after leaving the getIntegersFromUser function. If I run the for loop in the getIntegers function it does it properly, but why not in the main function?
Thanks in advance for your help.
#include <stdio.h>
#include <stdlib.h>
void getIntegersFromUser(int N, int *userAnswers)
{
int i;
userAnswers =(int *)malloc(N*sizeof(int));
if (userAnswers)
{ printf("Please enter %d integers\n", N);
for (i=0;i<N; i++)
scanf("%d", (userAnswers+i));
}
}
int main()
{
int i, M=5;
int *p;
getIntegersFromUser(M, p);
for (i=0;i<5;i++)
printf ("%d\n", p[i]);
return 0;
}
Also, this is a homework question, but it's a "Bonus Question", so I'm not trying to "cheat" I just want to make sure I understand all the course material, but if you could still try to give a fairly thorough explanation so that I can actually learn the stuff that would be awesome.
Pointers are passed by value. The function is using a copy of your pointer, which is discarded when the function ends. The caller never sees this copy.
To fix it, you could return the pointer.
int *getIntegersFromUser(int N)
{
int *userAnswers = malloc(...);
...
return userAnswers;
}
/* caller: */
int *p = getIntegersFromUser(M);
Or you could pass your pointer by reference so the function is acting on the same pointer, not a copy.
void getIntegersFromUser(int N, int **userAnswers)
{
*userAnswers = (int *) malloc(N*sizeof(int));
...
}
/* caller: */
int *p;
getIntegersFromUser(N, &p);
I have two functions with variable number and types of arguments
double my_func_one(double x, double a, double b, double c) { return x + a + b + c }
double my_func_two(double x, double p[], double c) { return x + p[0] + p[1] + c }
I want to use a pointer to a function to the functions I defined above based on a some condition getting true e.g.
if (condition_1)
pfunc = my_func_one;
else if (condition_2)
pfunc = my_func_two;
// The function that will use the function I passed to it
swap_function(a, b, pfunc);
My question is, for this scenario, Can I at all define a function pointer? If yes, how?
My understanding is that the prototype of function pointer should be the same for all those functions it CAN be pointed to.
typedef double (*pfunction)(int, int);
In my case they are not the same. Is there any other way to do this?
Language
I am developing in C and I am using gcc 4.4.3 compiler/linker
The cleanest way to do it is to use a union:
typedef union {
double (*func_one)(double x, double a, double b, double c);
double (*func_two)(double x, double p[], double c);
} func_one_two;
Then you can initialize an instance of the union, and include information to the swap_function function to say which field is valid:
func_one_two func;
if (condition_1)
func.func_one = my_func_one;
else if (condition_2)
func.func_two = my_func_two;
// The function that will use the function I passed to it
swap_function(a, b, func, condition_1);
This assumes that swap_function can know based on condition_1 being false that it should assume condition_2. Note that the union is passed by value; it's only a function pointer in size after all so that's not more expensive than passing a pointer to it.
My question is, for this scenario, Can I at all define a function pointer?
No. (Other than by dirty typecasting.)
Is there any other way to do this?
Your best bet is to create a wrapper function for one of your existing functions. For example:
double my_func_one_wrapper(double x, double p[], double c) {
return my_func_one(x, p[0], p[1], c);
}
That way, you have two functions with the same signature, and therefore the same function-pointer type.
An old topic but I am facing same issue and finally came with this idea.
If you want the same prototype for each functions you can wrap the parameters in structure like this :
typedef struct {
double a,
b,
c;
}chunk1_t;
typedef struct {
double p[];
double c;
}chunk2_t;
Then your function pointer becomes:
double (*pfunc) (double x, void *args);
which leads to something like this :
pfunc cb;
double swap_function(double x, pfunc cb, void *args);
double my_func_one(double x, void *args) {
chunk1_t *chunk = (chunk1_t*) args;
return x + chunk->a + chunk->b + chunk->c;
}
double my_func_two(double x, void *args) {
chunk2_t *chunk = (chunk2_t*) args;
return x + chunk->p[0] + chunk->p[1] + chunk->c ;
}
int main(){
// declare a, b,...
double a = 1.0f;
//...
// cast for safety
chunk1_t myChunk1 = {(double)a, (double)b, (double)c};
// don't if you like risk
chunk2_t myChunk2 = {p, c};
swap_function(x, cb, &myChunk1);
swap_function(x, cb, &myChunk2);
}
Using function pointer stored in structure:
#define FUNC_ONE_METHOD 1
#define FUNC_TWO_METHOD 2
typedef struct chunk{
double a, b, c;
double p[];
int method;
double (*pfunc) (double x, struct chunk *self);
}chunk_t;
double swap_function(double x, chunk_t *ch){
switch (ch->method)
{
case FUNC_TWO_METHOD:
ch->pfunc = my_func_two;
break;
case FUNC_ONE_METHOD:
ch->pfunc = my_func_one;
break;
default:
return -1; // or throw error
return ch->pfunc(x, ch);
}
chunk c = {.a= 1, .b=3, .c=1, .method=1};
swap_function(x, &c);
Your understanding is true.
The signature of your function-pointer must match the corresponding function(s).
Consider learncpp.com:
Just like it is possible to declare a non-constant pointer to a variable, it’s also possible to >declare a non-constant pointer to a function. The syntax for doing so is one of the ugliest things >you will ever see:
// pFoo is a pointer to a function that takes no arguments and returns an integer
int (*pFoo) ();
The parenthesis around *pFoo are necessary for precedence reasons, as int *pFoo() would be interpreted as a function named pFoo that takes no parameters and returns a pointer to an integer.
In the above snippet, pFoo is a pointer to a function that has no parameters and returns an integer. pFoo can “point” to any function that matches this signature.
...
Note that the signature (parameters and return value) of the function pointer must match the signature of the function.
What you want is possible, but a bit dirty. Function pointers can be cast to one another without losing information. The important thing is that you'd always have to call a function through such a pointer only with a signature that corresponds to its definition. So if you cast back before calling the function(s) and call with the correct arguments, all should be fine.
A sample of Typecasting approach for using a same function pointer for different functions of different prototypes.
<>
#include <stdio.h>
typedef void (*myFuncPtrType) (void);
typedef int (*myFunc2PtrType)(int, int);
typedef int * (*myFunc3PtrType)(int *);
static void myFunc_1 (void);
static int myFunc_2 (int, int);
static int* myFunc_3 (int *);
const myFuncPtrType myFuncPtrA[] = {
(myFuncPtrType)myFunc_1,
(myFuncPtrType)myFunc_2,
(myFuncPtrType)myFunc_3
};
static void myFunc_1 (void)
{
printf("I am in myFunc_1 \n");
}
static int myFunc_2 (int a, int b)
{
printf("I am in myFunc_2\n");
return (a+b);
}
static int* myFunc_3 (int *ptr)
{
printf("I am in myFunc_3\n");
*ptr = ((*ptr) * 2);
return (ptr+1);
}
int main(void) {
// your code goes here
int A[2],C;
int* PTR = A;
(*(myFuncPtrA[0]))();
A[0]=5;
A[1]=6;
C = ((myFunc2PtrType)(*(myFuncPtrA[1])))(A[0],A[1]);
printf("Value of C: %d \n", C);
printf("Value of PTR before myFunc_3: %p \n", PTR);
printf("Value of *PTR before myFunc_3: %d \n", *PTR);
PTR = ((myFunc3PtrType)(*(myFuncPtrA[2])))(&A);
//Lets look how PTR has changed after the myFunc_3 call
printf("Value of PTR after myFunc_3: %p \n", PTR);
printf("Value of *PTR after myFunc_3: %d \n", *PTR);
return 0;
}
I'm new to C and I have a function that calculates a few variables. But for now let's simplify things. What I want is to have a function that "returns" multiple variables. Though as I understand it, you can only return one variable in C. So I was told you can pass the address of a variable and do it that way. This is how far I got and I was wondering I could have a hand. I'm getting a fair bit of errors regarding C90 forbidden stuff etc. I'm almost positive it's my syntax.
Say this is my main function:
void func(int*, int*);
int main()
{
int x, y;
func(&x, &y);
printf("Value of x is: %d\n", x);
printf("Value of y is: %d\n", y);
return 0;
}
void func(int* x, int* y)
{
x = 5;
y = 5;
}
This is essentially the structure that I'm working with. Could anyone give me a hand here?
You should use *variable to refer to what a pointer points to:
*x = 5;
*y = 5;
What you are currently doing is to set the pointer to address 5. You may get away with crappy old compilers, but a good compiler will detect a type mismatch in assigning an int to an int* variable and will not let you do it without an explicit cast.
void function(int *x, int* y) {
*x = 5;
*y = 5;
}
would change the values of the parameters.
In addition to the changes that the other posters have suggested for your function body, change your prototype to void func(int *,int *), and change your function definition (beneath main) to reflect void as well. When you don't specify a return type, the compiler thinks you are trying to imply an int return.
You can't forward declare func(int,int) when in reality it is func(int*, int*). Moreover, what should the return type of func be? Since it doesn't use return, I'd suggest using void func(int*, int*).
You can return a single variable of a struct type.
#include <stdio.h>
#include <string.h>
struct Multi {
int anint;
double adouble;
char astring[200];
};
struct Multi fxfoo(int parm) {
struct Multi retval = {0};
if (parm != 0) {
retval.anint = parm;
retval.adouble = parm;
retval.astring[0] = parm;
}
return retval;
}
int main(void) {
struct Multi xx;
if (fxfoo(0).adouble <= 0) printf("ok\n");
xx = fxfoo(42);
if (strcmp(xx.astring, "\x2a") == 0) printf("ok\n");
return 0;
}