i have some fix arrays defined that i need to write with a common function:
uint8 myArray_A[3][5];
uint8 myArray_B[3][5];
void doThings(uint8 * in)
{
*in[0][0] = someValue_0
*in[0][1] = someValue_1
}
This function i will call in another function and give the needed Array to it:
void main(void)
{
doThings(myArray_A);
}
Is this the way to do it? Will it work?
Your function takes a pointer to an integer, that is the location of a single integer in your memory space.
It means that as you pass the pointer to your array (that is the address of the 1st element in your array - &myArray_A[0][0]) you lose the structural information that was contained in the definition of myArray_A - the size of the array.
This can, however, be fixed by specifying the array parameters in the function declaration.
This can be either done by defining your array type with typedef int[3][5] my_array_t or by specifying the array size in the parameter void doThings(uint8[3][] in)
Bonus: #define your array sizes so that you can update the size in only a single location and have the change propagate across your code.
do this instead.
uint8 myArray_A[3][5];
uint8 myArray_B[3][5];
void doThings(uint8 in[][5])
{
in[0][0] = someValue_0
in[0][1] = someValue_1
}
If the size of the dimensions varies, then you would need to pass that in somehow, and do your own matrix arithmetic, which is frankly machine-dependent so not a good idea:
void doThings(uint8 * in, int dim1, int dim2)
{
in[0*dim2+0] = someValue_0
in[0*dim2+1] = someValue_1
}
Related
I'm trying to pass an three dimensional array to a function like this:
void example( double*** bar ) {
// Stuff
}
int main() {
double[3][2][3] foo;
// Initialize foo
example( foo );
return 0;
}
This causes the gcc to give me "Invalid pointer type". How am I supposed to be doing this? I could just make the entire argument a one-dimensional array and arrange my data to fit with that, but is there a more elegant solution to this?
edit:
In addition, I can't always specify the length of each sub-array, because they may be different sizes. e.g.:
int* foo[] = { { 3, 2, 1 }, { 2, 1 }, { 1 } };
If it helps at all, I'm trying to batch pass inputs for Neurons in a Neural Network. Each Neuron has a different number of inputs.
just use double*. A multidimensional array is stored contiguously in memory so you are quite welcome to give it your own stride. This is how bitmaps are passed on OpenGL.
A one-dimensional int array decays into an int pointer when passing it to a function. A multi-dimensional array decays into a pointer to an array of the next lowest dimension, which is
void example(double (*bar)[2][3]);
This syntax can be a bit baffling, so you might chose the equivalent syntax:
void example(double bar[][2][3]) {
// Stuff
}
int main() {
double foo[3][2][3];
example(foo);
return 0;
}
The first dimension does not have to be given, it's that part that is "decaying". (Note that the dimensions of arrays are not given on the type as in Java, but on the array name.)
This syntax works for variable-length arrays (VLAs) as well, as long as you pass the dimensions before the array:
void example(int x, int y, double (*bar)[x][y]) {
// Stuff
}
int main() {
double foo[3][2][3];
example(2, 3, foo);
return 0;
}
This feature requires C99 and is not compatible with C++.
If the array size is fixed, you can use:
void example(double bar[][2][3]) {
}
Otherwise, you can pass the size along with the array into the function:
void example(size_t x, size_t y, size_t z, double bar[x][y][z]) {
}
That can't be done in C the way you're thinking of. If you need a function that operates on variable-size multidimensional arrays, you'll either have to pass the sizes (all but one) explicitly to the function, or make a structure and pass that. I generally always make a structure when a 2D or 3D array is called for, even if they're of fixed size. I think it's just cleaner that way, since the structure documents itself.
I've just started to work with C, and never had to deal with pointers in previous languages I used, so I was wondering what method is better if just modifying a string.
pointerstring vs normal.
Also if you want to provide more information about when to use pointers that would be great. I was shocked when I found out that the function "normal" would even modify the string passed, and update in the main function without a return value.
#include <stdio.h>
void pointerstring(char *s);
void normal(char s[]);
int main() {
char string[20];
pointerstring(string);
printf("\nPointer: %s\n",string);
normal(string);
printf("Normal: %s\n",string);
}
void pointerstring(char *s) {
sprintf(s,"Hello");
}
void normal(char s[]) {
sprintf(s,"World");
}
Output:
Pointer: Hello
Normal: World
In a function declaration, char [] and char * are equivalent. Function parameters with outer-level array type are transformed to the equivalent pointer type; this affects calling code and the function body itself.
Because of this, it's better to use the char * syntax as otherwise you could be confused and attempt e.g. to take the sizeof of an outer-level fixed-length array type parameter:
void foo(char s[10]) {
printf("%z\n", sizeof(s)); // prints 4 (or 8), not 10
}
When you pass a parameter declared as a pointer to a function (and the pointer parameter is not declared const), you are explicitly giving the function permission to modify the object or array the pointer points to.
One of the problems in C is that arrays are second-class citizens. In almost all useful circumstances, among them when passing them to a function, arrays decay to pointers (thereby losing their size information).
Therefore, it makes no difference whether you take an array as T* arg or T arg[] — the latter is a mere synonym for the former. Both are pointers to the first character of the string variable defined in main(), so both have access to the original data and can modify it.
Note: C always passes arguments per copy. This is also true in this case. However, when you pass a pointer (or an array decaying to a pointer), what is copied is the address, so that the object referred to is accessible through two different copies of its address.
With pointer Vs Without pointer
1) We can directly pass a local variable reference(address) to the new function to process and update the values, instead of sending the values to the function and returning the values from the function.
With pointers
...
int a = 10;
func(&a);
...
void func(int *x);
{
//do something with the value *x(10)
*x = 5;
}
Without pointers
...
int a = 10;
a = func(a);
...
int func(int x);
{
//do something with the value x(10)
x = 5;
return x;
}
2) Global or static variable has life time scope and local variable has scope only to a function. If we want to create a user defined scope variable means pointer is requried. That means if we want to create a variable which should have scope in some n number of functions means, create a dynamic memory for that variable in first function and pass it to all the function, finally free the memory in nth function.
3) If we want to keep member function also in sturucture along with member variables then we can go for function pointers.
struct data;
struct data
{
int no1, no2, ans;
void (*pfAdd)(struct data*);
void (*pfSub)(struct data*);
void (*pfMul)(struct data*);
void (*pfDiv)(struct data*);
};
void add(struct data* x)
{
x.ans = x.no1, x.no2;
}
...
struct data a;
a.no1 = 10;
a.no1 = 5;
a.pfAdd = add;
...
a.pfAdd(&a);
printf("Addition is %d\n", a.ans);
...
4) Consider a structure data which size s is very big. If we want to send a variable of this structure to another function better to send as reference. Because this will reduce the activation record(in stack) size created for the new function.
With Pointers - It will requires only 4bytes (in 32 bit m/c) or 8 bytes (in 64 bit m/c) in activation record(in stack) of function func
...
struct data a;
func(&a);
...
Without Pointers - It will requires s bytes in activation record(in stack) of function func. Conside the s is sizeof(struct data) which is very big value.
...
struct data a;
func(a);
...
5) We can change a value of a constant variable with pointers.
...
const int a = 10;
int *p = NULL;
p = (int *)&a;
*p = 5;
printf("%d", a); //This will print 5
...
in addition to the other answers, my comment about "string"-manipulating functions (string = zero terminated char array): always return the string parameter as a return value.
So you can use the function procedural or functional, like in printf("Dear %s, ", normal(buf));
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
);
I have an array/pointer related problem.
I created an int array myArray of size 3. Using a function I want to fill this array.
So I'm calling this function giving her the adress &myArray of the array.
Is the syntax correct for the function declaration`? I'm handing over the pointer to the array, so the function can fill the array elements one by one.
But somehow my array is not filled with the correct values.
In Java I could just give an array to a method and have an array returned.
Any help is appreciated! Thanks!
#include <stdio.h>
int myArray[3];
void getSmth(int *anArray[]);
int main(void)
{
getSmth(&myArray);
}
void getSmth(int *anArray[])
{
for(i=0...)
{
*anArray[i] = tmpVal[i];
}
}
Remove one level of indirection:
#include <stdio.h>
int myArray[3];
void getSmth(int anArray[]);
int main(void)
{
getSmth(myArray);
}
void getSmth(int anArray[])
{
for(i=0...)
{
anArray[i] = tmpVal[i];
}
}
Also, as others have suggested, it would be a good idea to pass the size of the array into getSmth().
No, the syntax is not correct. You have an extra *, making the argument into an array of pointers.
In general, it's better to use:
void getSmth(int *array, size_t length);
since then the function can work on data from more sources, and the length becomes available which is very handy for iterating over the data as you seem to want to be doing.
You'd then call it like so:
int main(void)
{
int a[12], b[53];
getSmth(a, sizeof a / sizeof a[0]);
getSmth(b, sizeof b / sizeof b[0]);
}
Note the use of sizeof to compute (at compile-time) the number of elements. This is better than repeating the numbers from the definitions of the variables.
Right now, your function accepts an int *anArray[] parameter, which is an array of pointers to int. Remove the unneccessary * and your function signature should look simply like this:
void getSmth(int anArray[]); // array of int
or
void getSmth(int *anArray); // pointer to first array element of type int
You should use either int anArray[] or int *anArray (which is effectively the same, because array decays to pointer). You should also make sure that the function knows how big your array is either by agreement or passing it as a parameter for it can not use sizeof for the purpose.
For my program I need to pass a 2D array of pointers to a function in a separate file. I've written a similarly-syntaxed file below:
#include <stdlib.h>
#include <stdio.h>
typedef struct {
int state;
int design;
} card_t;
card_t *cardSet[5][5];
void setFirst(card_t *cards[][]) { // <- Error: Array has incomplete element type
cards[0][0]->state = 1;
}
int main() {
setFirst(cardSet); // <- Error: Type of formal parameter 1 is incomplete
return 0;
}
When I change the code to all 1D arrays it compiles fine, but for a 2D array I get the errors shown above. What is the difference between the two cases?
Thanks!
Cameron
if you pass an array to a function, you have to specify the size of the inner array, in your case, instead of void setFirst(card_t *cards[][]), you should specify void setFirst(card_t *cards[][5]).
Why do you need to specify it and not the size of the first dimension?
Since cards is an array of array of card_t pointers, if you want to get to cards[1][0], the compiler will need to know how much to add to the pointer cards - cards is declared: card_t *cards[5][4] it will need to add 4 * sizeof(*card_t) to get to cards[1][0], but if cards is declared: card_t *cards[5][5] it will need to add 5 * sizeof(*card_t) to get to cards[1][0].
As has been mentioned, to pass a 2d array to a function, you need to have every dimension but the first declared.
However, you can also just pass the pointer, as follows. Note that you should always (unless the array dimension is completely fixed and the function that operates on the array only operates within the array's dimension) pass the length of each array, too.
void setFirst(card_t ***cards, size_t n, size_t m) {
if (n > 0 && m > 0) {
cards[0][0]->state = 1;
}
}
Because referencing an array via code[0][0] is the same as *(*(code+0)+0*m), you can pass two pointers instead of array dimensions.
Only the first index is optional. You should definitely mention the second index, because a two dimensional array decays to a pointer to 1d array.
void setFirst(card_t *cards[][5]) {
// ^ Newly added
// ..
}
Also make sure that the pointers are pointing to valid memory locations. Else dereferencing leads to segmentation faults. BTW, is there any reason to have a two dimensional array with pointers. I think you are just complicating the program.
To achieve something similar to what you are trying C99 has variable length arrays. These come particularly handy in function definitions:
void setFirst(size_t n, size_t m, card_t *cards[n][m]) {
...
}
Observe that you have to have the size parameters known at the moment of the array declaration, so you'd have to put them in front.