I'm wondering something like this is possible:
// declaration
void func();
int main()
{
int ar[] = { 1, 2, 3 };
func(ar); // call with parameter
return 1;
}
void func() // no parameters
{
// do something
}
Can someone explain me this and especially how can I access ar in func()?
In C (not C++), a function declared as func() is treated as having an unspecified number of untyped parameters. A function with no parameters should be explicitly declared as func(void).
A hack would be to exploit the GCC calling convention.
For x86, parameters are pushed into stack. Local variables are also in the stack.
So
void func()
{
int local_var;
int *ar;
uintptr_t *ptr = &local_var;
ptr += sizeof(int *);
ar = (int *)ptr;
May give you the array address in ar in x86.
For x86_64, the first parameter is stored in rdi register.
void func()
{
uintptr_t *ptr;
int *ar;
asm (
"movq %%rdi, %0"
:"=r"(*ptr)
:
:"rdi");
ar = (int *)ptr;
May give you the array address in ar in x86_64.
I have not tested these code myself and you may be to fine tune the offsets yourself.
But I am just showing one possible hack.
If you want to use any function with no parameters with any return type, it should be declared as (In C)
return_type func(void). It is only generic way of function declaration.
But any how, for your question , it possible to access but not generic..Try this program...
#include<stdio.h>
int *p;
void func();
int main()
{
int ar[] = { 1, 2, 3 };
p=ar;
printf("In main %d\n",ar[0]);
func(ar); // call with parameter
printf("In main %d\n",ar[0]);
return 1;
}
void func() // no parameters
{
printf("In func %d \n",*p);
*p=20;
}
Even this program works fine, it is not generic way and also is undefined.
if you declare function like void func (void) ,it will not work.
You can't access ar in func(), since you dont have a reference to it in func().
It would be possible if ar would be a global var or you have a pointer on it.
So that you can do something with func(), you need to pass it the input data you'll work with.
First you must declare the function properly :
// declaration
void func(int []);
The define it :
void func( int a[] )
{
// do something
printf ("a[0] = %d\n", a[0]);
}
Full code :
#include <stdio.h>
// declaration
void func(int []);
int main()
{
int ar[] = { 1, 2, 3 };
func(ar); // call with parameter
return 1;
}
void func( int a[] )
{
// do something
printf ("a[0] = %d\n", a[0]);
}
This will display :
a[0] = 1
You can implement something like this.
void func(int *p, int n);
int main()
{
int ar[] = { 1, 2, 3 };
func(ar, sizeof (ar)/sizeof(ar[0]) ); // call with parameter
return 1;
}
void func(int *p, int n) // added 2 parameters
{
int i=0;
for (i=0; i<n; ++i){
printf ("%d ", p[i]);
}
}
Related
I am new to C language somehow and I am trying here to call a function "func" in main function but it gives me compiling error. I tried to search for examples similar to this situation in Google but stil getting errors.
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
struct str {
int value;
uint32_t ptr_next;
};
void func(int arg, char* arr[]);
int main() {
int Arg;
char* Arr[1];
func(Arg, *Arr[1]);
return 0;
}
void func(int arg, char* arr[]) {
int list;
struct str r;
FILE* file = fopen(arr[1], "rb");
do {
list = fread(&r, sizeof(struct str), 1, file);
if (list > 0)
printf("%d ", r.value);
fseek(file, r.ptr_next, 0);
}
while ((r.ptr_next != 0) && (list > 0));
}
The question is how can I call functions by value in C language?
C only supports calling functions by value, calling by reference was added in C++ and uses the & symbol.
The value you are passing to the function is a location in memory, a pointer. If you want to hand to the function a copy of the data at that memory location you'll need to make a copy for it.
// Assuming that Arg and Arr are initialized.
char* Arr2[]; // Make a storage place for the char**.
Arr2 = malloc(Arg*sizeof(char*)); // Make the right number of char*s in it
for(int e=0; e<Arg; e++) { // For each elem in the main array:
Arr2[e]=malloc(sizeof(char)*strlen(Arr[e])); // Make space for the chars,
strcpy(Arr2[e],Arr[e]); // And copy them.
}
Side note
You haven't initialized Arg or Arr in main. I suspect that you might have meant the command line parameters.
int main(int Arg, char* Arr[])
Let's say I have a pointer inside function1, I need to pass it to function2, and function2 needs to pass it to function3, function3 needs to update that pointer. How do you correctly do this?
Do you use triple stars? If so, what's the correct way to pass the pointer inside function2?
function1(void){
char *pointer;
function2(&pointer)
}
function2(char **pointer){
function3(&(*pointer));
}
function3(char ***pointer)}
/*update pointer*/
}
My question is specifically about this situation only (3 functions), I don't want to remove function2, even if it does nothing.
Just keep two levels of pointer.
#include <stdio.h>
static int b = 42;
void foo(int **a) {
*a = &b;
}
void bar(int **a) {
foo(a);
printf("%d\n", **a);
**a = 21;
}
int main()
{
int *a = NULL;
bar(&a);
printf("%d\n", *a);
}
Output:
42
21
#include<stdio.h>
void f(int *p) {
static int data = 5;
p=&data;
}
int main(void) {
int *ip=NULL;
f(ip);
printf("%d\n", *ip);
return 0;
}
if it is possible.
what is cause error?
how can I fix the code?
In this way you end up changing the value of a local pointer, you need to pass a pointer to pointer (&) from main and use the dereference operator (*) in the function:
#include <stdio.h>
void f(int **p) {
static int data = 5;
*p = &data;
}
int main(void) {
int *ip = NULL;
f(&ip);
printf("%d\n", *ip);
return 0;
}
But usually we prefer to work with the same level of indirection returning the address from the function, this is easier to read (at least for me):
#include <stdio.h>
int *f(void) {
static int data = 5;
return &data;
}
int main(void) {
int *ip = f();
printf("%d\n", *ip);
return 0;
}
You have to pass a pointer to the pointer to change the value of the actual pointer:
void some_fun(int **p)
{
static int i = 10;
*p = &i;
}
That being said, it is not necessarily advisable to do that. The only direct use I could think of is to delay the execution of the initialization of a global until its first use.
I have p like:
typedef int (*p)();
Let's say the function to which I want to declare a pointer is int foo().
I wanna declare a new pointer to function foo using variable p to make use of typedef statement like:
typedef int emp[10];
emp p;// so now p is an array of size 10 of type int
p is:
typedef int (*p) ();
foo() is:
int foo(){
}
p type variable is f:
p f = &foo;
how to call using pointer:
(*f)();
Example code:
#include<stdio.h>
int foo(){
printf("\n In FOO\n");
return 4;
}
typedef int(*p)();
int main(){
p f = &foo;
int i = (*f)();
printf("\n i = %d\n", i);
return 1;
}
you can find it is working on codepad.
note: you can simply assign like p f = foo; and call like f() the second form you can find here on codepad
Edit: As #Akash commented:
it compiles and runs like:
~$ gcc x.c -Wall
~$ ./a.out
In FOO
i = 4
Here is a project to help explain the usefulness of function pointers.
int foo()
{
// do something
}
typedef int (*p)();
int main( int argc, char** argv )
{
int result;
p funcPtr = foo;
result = funcPtr();
return 0;
}
With a typedef:
typdef int (*FunctionPtr)();
int foo()
{
return 4; // chosen by fair dice roll, should be random
}
FunctionPtr fptr = foo; // or &foo
Without a typedef:
int (*fptr)() = foo; // or &foo
From this post: convert C function array to c++ functions pointer array?
#include <stdio.h>
void f1() {printf("helo\n");}
void f2() {printf("world\n");}
typedef struct func
{
void (*f)();
}func;
int main()
{
func a[] = {{f1}, {f2}};
a[0].f();
return 0;
}
I think it would be easier to use function pointers if I created a typedef for a function pointer, but I seem to be getting myself tripped up on some syntax or usage or something about typedef for function pointers, and I could use some help.
I've got
int foo(int i){ return i + 1;}
typedef <???> g;
int hvar;
hvar = g(3)
That's basically what I'm trying to accomplish I'm a rather new C programmer and this is throwing me too much. What replaces <???> ?
Your question isn't clear, but I think you might want something like this:
int foo(int i){ return i + 1;}
typedef int (*g)(int); // Declare typedef
g func = &foo; // Define function-pointer variable, and initialise
int hvar = func(3); // Call function through pointer
You are right. The function pointer can be conveniently used to point to the different functions of the same return type and taking same number of arguments.
The argument types should match the declaration of the function pointer arguments.
In your case you could define your function pointer g as:
typedef int (*g)(int); // typedef of the function pointer.
g is a function pointer for the function returning int value and taking one int argument.
The usage of function pointer could be illustrated by a simple program below:
#include<stdio.h>
typedef int (*pointer_to_function)(int first_parameter_of_type_int, int second_parameter_of_type_int);
int my_function_returning_int_and_taking_two_int_arguments(int par1, int par2)
{
int result = par1 + par2;
return result;
}
int my_mul_function(int par1, int par2)
{
int result = par1 * par2;
return result;
}
int main()
{
int res; // returning result will be here
pointer_to_function my_fun_pointer; // declare function pointer variable;
my_fun_pointer = my_function_returning_int_and_taking_two_int_arguments; // function pointer points to `my_function_returning_int_and_taking_two_int_arguments` function
res = my_fun_pointer(2,3); // Call function through pointer
printf(" result of `my_function_returning_int_and_taking_two_int_arguments` = %d \n", res);
my_fun_pointer = my_mul_function; // now function pointer points to another function: `my_mul_function`
res = my_fun_pointer(2,3); // Call function through pointer
printf(" result of `my_mul_function` = %d \n", res);
return 0;
}
OUTPUT:
result of `my_function_returning_int_and_taking_two_int_arguments` = 5
result of `my_mul_function` = 6
The original way of writing the function returning function pointer is
int (* call(void) ) (int,int);
Here call is a function which takes nothing but returns a function pointer which takes 2 arguments and returns an integer value. Pay attention to the brackets, they are absolutely necessary.
Here is the code:
#include<stdio.h>
int sum(int a,int b) //sum is the function returned by call
{
return a+b;
}
int (*call(void) ) (int ,int);
int main() {
int (*p)(int,int); // way to declare a function pointer
p=call();
printf("%d\n",(*p)(8,3));
}
int( *call(void) )(int,int) {
return sum;
}