I am new to C. Can someone explain me whats the difference between these?
I usually use pointers like this:
int myFunction(int* something) {
...
}
int main() {
int something;
something = 0;
myFunction(&something);
...
}
But I've found code which looks like this:
int myFunction(int& something) {
...
}
int main() {
int something;
something = 0;
myFunction(something);
...
}
It seems like the exactly same thing for me. Is there any difference?
As you mentioned, int myFunction(int& something) { is not valid C. It's a reference, which is used in C++.
C and C++ are different languages, despite the similarity in syntax.
In case, you want to modify the content of something, you need to pass a pointer to it to the called function and operate on the pointer. The pointer itself will be passed by value, but by derefrencing the pointer inside the called function, you can achieve the result of pass by reference.
So your first snippet is valid. You should use that in C.
The former is a pointer, which is valid C.
The latter is a C++ reference, which is not valid C.
The most notable difference is "syntactic sugar". To access the contents of the pointer something, you'll have to type *something. When doing the same to the C++ reference something, you don't need the *.
A more subtle difference is that a pointer can be used for pointer arithmetic. For example, to implement the library function strlen, you could do something like this:
size_t strlen (const char* s)
{
const char* start = s;
while(*s != '\0')
{
s++;
}
return (size_t)(s - start);
}
This wouldn't be possible if s was a reference. You'd have to use separate counters etc.
Note that a C++ reference is 100% functionally equivalent to a read-only pointer:
int* const something // C equivalent of a reference
Related
I have written a C program and I'm compiling with GCC (for an arm MCU).
I have a function that changes the address of void pointer to point to another void,and so on.
The problem is that the Linker/Compiler think that the code is unused and discard it.
I have tried attribute(( used )) but that didn't work.
The voids and code are in separate .h/.c file from the main.h/c but are included in the main.c
Code:
void q2_h(void (*ptr)(uint8_t), uint8_t a) {
if (a == 3) {
ptr = (void*) q3_h;
} else {
ptr = (void*) q22_h;
}
}
Definition:
void q2_h(void (*ptr)(uint8_t), uint8_t a)__attribute__((used));
Input Pointer:
void (*ptr)(void*,uint8_t);
which is not completely right because the (uint8_t) is missing but I'm not sure about the syntax.
So if if you have any idea on how to sol
Problems:
The code changes a local variable, not the function pointer in the calling code. So it is not "seemingly dead", it's truly dead. Instead of fiddling around with attributes, listen to what your compiler is trying to tell you.
Always use typedef when dealing with function pointers, it would have made the bug more obvious.
You cannot cast a function pointer to a void pointer or vice versa. void* is only a generic pointer type for object pointers. You shouldn't need to cast at all, or your code is attempting fishy invalid pointer conversions, which would be a bug.
Corrected code might look something like:
typedef void func_t (uint8_t);
void q2_h(func_t** ptr, uint8_t a) {
if (a == 3) {
*ptr = q3_h;
} else {
*ptr = q22_h;
}
}
I am not great on pointers but I have to learn in the field. If my understanding serves me correct these should all be valid statements below.
int* a;
int b = 10;
a = &b;
(*a) = 20;
(*a) == b; //this should be true
if you have a function like this:
void copy(int* out, int in) {
*out = in;
}
int m_out, m_in;
copy(&m_out, m_in);
m_out == m_in; // this should also be true
but I saw a function like this
create(float& tp, void* form, char* title);
I understand the void pointer, it can be cast to anything, I understand the character pointer which is basically a c style string.
I do not understand the first argument, which is the address of some type, let's say a float but it could be anything, a struct, a int, etc.
What is going on there?
First this
int m_out, m_in;
copy(&m_out, m_in);
is undefined behaviour - you passed uninitialized vaiable m_in to function - and hence trying to make copy of an uninitialized variable.
This:
create(float& tp, void* form, char* title);
doesn't make sense in C. Looks like reference from C++.
The first argument is a reference, it just means that if you modify this field in your function create, the field will still remain modified (even in the function where you called create()) because it points to an address and not a value.
if I have a structure that has a pointer to a function like this
struct str{
int some_element;
char other_element;
int (*my_pointer_to_a_function)(int);
};
struct str my_struct;
int my_function(int);
and I asign values to it
my_struct.some_element = 1;
my_struct.other_element = 'a';
my_struct.my_pointer_to_a_function = my_function;
how do I call the function that the pointer is pointing to (using the pointer)?
My initial guess is this:
my_struct.(*my_pointer_to_a_function)(value);
or should it be
*my_struct.my_pointer_to_a_function(value);
?
Thank you.
Pointers to functions can be used as-is, without any dereference:
my_struct.my_pointer_to_a_function(value)
But if you insist in dereferencing it you have to use parenthesis this way:
(*my_struct.my_pointer_to_a_function)(value)
They both are totally equivalent, so I recommend the first one, that is simpler.
About you first try:
my_struct.(*my_pointer_to_a_function)(value); //Error!
That won't work because the expression in parenthersis has to be evaluated first: *my_pointer_to_a_function, but that alone means nothing.
And your second:
*my_struct.my_pointer_to_a_function(value); //Error!
The operator precedence rules evaluates first the ., then the function call, and lastly the *:
*(my_struct.my_pointer_to_a_function(value)); //Error!
So the function would be called, but the result of the call, an int, would be dereferenced, hence the error.
Suppose you have pointer to function as you struct member like:
struct newtype{
int a;
char c;
int (*f)(struct newtype*);
} var;
int fun(struct newtype* v){
return v->a;
}
You can call it as follows:
int main(){
var.f=fun;
var.f(&var);
// ^.....^..... have to pass `var` as an argument to f() :( :(
}
//Comment: here in var.f(&var); I miss this pointer and C++,
So for your case it should be just my_struct.my_pointer_to_a_function(value);
Additionally points:
Important to note in my example even you wants to access members of same structure variable you have to pass that. (its quite dissimilar than c++ object!)
virtual functions in C++ classes. They are implemented in a similar fashion under the hood.
Here is a project that will help you to use: Function pointers inside structures
Use this:
#define function mystruct.my_pointer_to_a_function
Then you can call the function :
int i = function(value);
I am trying to understand function pointers and am stuggling. I have seen the sorting example in K&R and a few other similar examples. My main problem is with what the computer is actually doing. I created a very simple program to try to see the basics. Please see the following:
#include <stdio.h>
int func0(int*,int*);
int func1(int*,int*);
int main(){
int i = 1;
myfunc(34,23,(int(*)(void*,void*))(i==1?func0:func1));//34 and 23 are arbitrary inputs
}
void myfunc(int x, int y, int(*somefunc)(void *, void *)){
int *xx =&x;
int *yy=&y;
printf("%i",somefunc(xx,yy));
}
int func0(int *x, int *y){
return (*x)*(*y);
}
int func1(int *x, int *y){
return *x+*y;
}
The program either multiplies or adds two numbers depending on some variable (i in the main function - should probably be an argument in the main). fun0 multiplies two ints and func1 adds them.
I know that this example is simple but how is passing a function pointer preferrable to putting a conditional inside the function myfunc?
i.e. in myfunc have the following:
if(i == 1)printf("%i",func0(xx,yy));
else printf("%i",func1(xx,yy));
If I did this the result would be the same but without the use of function pointers.
Your understanding of how function pointers work is just fine. What you're not seeing is how a software system will benefit from using function pointers. They become important when working with components that are not aware of the others.
qsort() is a good example. qsort will let you sort any array and is not actually aware of what makes up the array. So if you have an array of structs, or more likely pointers to structs, you would have to provide a function that could compare the structs.
struct foo {
char * name;
int magnitude;
int something;
};
int cmp_foo(const void *_p1, const void *_p2)
{
p1 = (struct foo*)_p1;
p2 = (struct foo*)_p2;
return p1->magnitude - p2->magnitude;
}
struct foo ** foos;
// init 10 foo structures...
qsort(foos, 10, sizeof(foo *), cmp_foo);
Then the foos array will be sorted based on the magnitude field.
As you can see, this allows you to use qsort for any type -- you only have to provide the comparison function.
Another common usage of function pointers are callbacks, for example in GUI programming. If you want a function to be called when a button is clicked, you would provide a function pointer to the GUI library when setting up the button.
how is passing a function pointer preferrable to putting a conditional inside the function myfunc
Sometimes it is impossible to put a condition there: for example, if you are writing a sorting algorithm, and you do not know what you are sorting ahead of time, you simply cannot put a conditional; function pointer lets you "plug in" a piece of computation into the main algorithm without jumping through hoops.
As far as how the mechanism works, the idea is simple: all your compiled code is located in the program memory, and the CPU executes it starting at a certain address. There are instructions to make CPU jump between addresses, remember the current address and jump, recall the address of a prior jump and go back to it, and so on. When you call a function, one of the things the CPU needs to know is its address in the program memory. The name of the function represents that address. You can supply that address directly, or you can assign it to a pointer for indirect access. This is similar to accessing values through a pointer, except in this case you access the code indirectly, instead of accessing the data.
First of all, you can never typecast a function pointer into a function pointer of a different type. That is undefined behavior in C (C11 6.5.2.2).
A very important advise when dealing with function pointers is to always use typedefs.
So, your code could/should be rewritten as:
typedef int (*func_t)(int*, int*);
int func0(int*,int*);
int func1(int*,int*);
int main(){
int i = 1;
myfunc(34,23, (i==1?func0:func1)); //34 and 23 are arbitrary inputs
}
void myfunc(int x, int y, func_t func){
To answer the question, you want to use function pointers as parameters when you don't know the nature of the function. This is common when writing generic algorithms.
Take the standard C function bsearch() as an example:
void *bsearch (const void *key,
const void *base,
size_t nmemb,
size_t size,
int (*compar)(const void *, const void *));
);
This is a generic binary search algorithm, searching through any form of one-dimensional arrray, containing unknown types of data, such as user-defined types. Here, the "compar" function is comparing two objects of unknown nature for equality, returning a number to indicate this.
"The function shall return an integer less than, equal to, or greater than zero if the key object is considered, respectively, to be less than, to match, or to be greater than the array element."
The function is written by the caller, who knows the nature of the data. In computer science, this is called a "function object" or sometimes "functor". It is commonly encountered in object-oriented design.
An example (pseudo code):
typedef struct // some user-defined type
{
int* ptr;
int x;
int y;
} Something_t;
int compare_Something_t (const void* p1, const void* p2)
{
const Something_t* s1 = (const Something_t*)p1;
const Something_t* s2 = (const Something_t*)p2;
return s1->y - s2->y; // some user-defined comparison relevant to the object
}
...
Something_t search_key = { ... };
Something_t array[] = { ... };
Something_t* result;
result = bsearch(&search_key,
array,
sizeof(array) / sizeof(Something_t), // number of objects
sizeof(Something_t), // size of one object
compare_Something_t // function object
);
Let's say that any C function has a pointer already declared, but not assigned any value yet. We will int for our examples.
int *ptr;
The goal of the function is not to assign ptr any dynamic memory on the heap, so no malloc call. Instead, we want to have it point to an array of fixed size n. I know I could accomplish this like so:
int arr[n];
ptr = arr;
However, the code could get very messy and hard to read if we need to do this many times in a function, ie, a struct of many pointer fields all need to point to an array of fixed length. Is there a better way to accomplish this in one line? I was thinking of something similar to below, but it looks too ambiguous and uncompilable:
int *ptr;
// Many other things happen in between...
ptr[n];
***EDIT***
Here, the below additional information may help guide some more answers (not saying that the current answers are not fine). In my use case, the pointers are declared in a struct and, in a function, I am assigning the pointers to an array. I want to know if there is a simpler way to accomplish this than in the below code (all pointers to point to fixed-length array):
struct foo {
int* a;
short* b;
char* c;
...
};
void func(void) {
struct foo f;
int n = ...;
int tempArr1[n];
f.a = tempArr1;
short tempArr2[n];
f.b = tempArr2;
char tempArr3[n];
f.c = tempArr3;
...
}
You cannot declare an array and assign it to an existing pointer in a single declaration. However, you can assign an array pointer to a newly declared pointer, like this:
int arr[n], *ptr = arr;
If you insist on staying within a single line, you could use an ugly macro, like this:
#define DECL_ASSIGN_INT_ARRAY(name,size,pointer) int name[(size)]; pointer = name;
The clarity of this one-liner is far lower than that of a two-line version from your post, so I would keep your initial version.
EDIT (in response to the edit of the question)
Another option is to create an unused pointer variable in a declaration, and assign your pointer in an initializer, like this:
void func(void) {
struct foo f;
int n = ...;
int tempArr1[n], *tempPtr1 = f.a = tempArr1;
short tempArr2[n], *tempPtr2 = f.b = tempArr2;
char tempArr3[n], *tempPtr3 = f.c = tempArr3;
...
}
This seems like a clear case where you're in need of some refactoring. Take the similar statements, extract them into a new function (by passing a reference to the struct and the data you want the struct fields to point to) and give this new function a meaningful name.
This is probably more maintainable and readable than some fancy pointer arithmetic shortcut that you'll forget about in a few weeks or months.
The difference between ptr and arr in you example is you can change ptr's value. So I guess you want to move ptr through the array.
So how about this:
int arr[n], id=0;
And you change the value of id and use arr+id as ptr.
I guess the way to do this is to use a macro. Something like (untested)
#define autoptr(name,size) int Arrayname[size]; name = Arrayname;
I'm not clear why this is helping I think it might "look ugly" but will be easier to maintain without the macro. In general, hiding what you are actually doing is a bad thing.