I've a function like this (in a file file_name.c):
char function_name(multi_array[][10])
{
/*change some character of multi_array*/
return multi_array;
}
That takes multi_array, a multidimensional array of characters, changes some characters of the given parameter, and than returns multi_array modified.
In main.c, i call the function like this:
multi_array_in_main = function_name(multi_array_in_main);
But the compiler gives me an error "icompatible type char[10][10] from type char"
What should i do? I'm not very confident with C so i don't know..!
You don't need to return anything.
Change:
char function_name(multi_array[][10])
To:
void function_name(multi_array[][10])
And your code should work fine (function_name will update whatever array it receives as an argument, as long as the dimensions are correct).
Change the function to return void and remove the return statement. The array is actually passed as a pointer to it's first element, so any changes you make to it inside your function actually change the original object in the caller.
void function_name(multi_array[][10])
{
/*change some character of multi_array*/
}
In your function header you declare function to return "char" type, but you return variable of char [][10], which is different type from the one in declaration (first line of your code).
Solution depends on what you really want to do. If you want to return that multiarray, change your function declaration. Also you defined parameter to be array of arrays, but it must be "array of array of char". Long story short, your declaration line should probably look like this:
char[][] function_name(char multi_array[][10])
Also, the changes made in multi_array made by this function will change multi_array even "outside" of the function and therefore you dont really need to return it. So you probably want to write this:
void function_name(char multi_array[][10])
As said, you do not need to return anything. The array is not copied, it is passed to your function as a pointer to the first element of the array. So, any element you change inside the function will be changed also outside because there is only one unique array.
Also if you insist, theoretically, it is possible to define a function returning a pointer to an array which is the closest thing to your original post. The declaration would be:
char (*function_name(char multi_array[][10]))[10] {
...
return(multi_array);
}
It is so ugly, that you will probably prefer to define a new type for it:
typedef char (*multi_array_t)[10];
multi_array_t function_name(multi_array_t multi_array) {
...
}
Related
Say you have a several function like this:
void Inventory(int index, char input[], int qty)
void AddItem(){
int index = Inventory(index);
if (int i = 0; i < index; i++){
...
}
}
But it gave me an error 'A value of type "Void" cannot be used to initialize an entity of type "int"'
Can someone explain to me in detail since im new to programming too.
You're trying to initialize index as an int whose value is returned by calling Inventory(index). But the Inventory function you provided has a return type of void, not the expected int, so there's no way to get that value.
Also, your call to Inventory is missing an argument to the chat input[] and int qty parameters. Additionally, index is uninitialized at the time that you're trying to use it (within the definition of index).
The function Inventory does not return anything (which is void) and you are trying to affect 'nothing' to a variable of type int. That's why the compiler is complaining.
The solution is to have your Inventory function return an int value instead of void.
First of all, your question and code snippet that you have provided are misleading.
Secondly, You are getting this error because the return type of function Inventory is Void, which means it returns nothing. And you are trying to assign nothing to variable index, which is of type int.
And, if you are trying to call multi-argument function without having to pass all arguments, make rest of the argument optional.
void foo(/.../) means that the function foo does not return anything. So you cant assign nothing to something.
In C you need to pass all the parameters. In other languages (like C++) some parameters might have default values and you do not have to pass them when call the function. But it is not possible in the C language and you need to pass all the parameters (arguments)
Is there a way to define an array inside a function argument in C? Something like this:
void arraysomething(double vec[2]){
//do something...
}
int main(){
arraysomething({1.,2.});
return 0;
}
I searched all over the place and found nothing.
What you're looking for is called a compound literal:
arraysomething((double []){1.,2.});
The syntax looks like an initializer for an array or struct preceeded by what looks like a cast to the type in question.
Because you want to pass in array, the typename given should be double [], which means an array of unspecified size. The actual size isn't needed because it is inferred from the number of elements in the literal.
I'm trying to learn c, so I tried reading some source code.
But I have no idea what this might mean:
static const char*(*const functab[])(void)={
ram,date
};
The first part, static const char* is fine, as it seems to be a function (has an argument of type void), static should mean that it is only visible in this file and const char* should mean that the value cannot be changed but the address can be changed.
But in that case, it doesn't make sense after the last part following the function name, as it was the case with
static const char * date(void);
static const char * ram(void);
Instead of the function name there is (*const functab[]), a const array called functab containing addresses?
Is this some kind of wrapping function containing the functions ram and date? Some alternative way of declaring arrays?
functab is an array of function pointers (array of const function pointers, to be exact), which returns const char* and accepts no arguments.
Later,
... = { ram, date };
is a brace-enclosed initializer list which serves as the initializer for the array.
This is the way to define array of function pointers in C. So instead of calling function as ram(), using this array you can call it by (* functab[1]).
Below discussion has good examples of array of function pointer:
How can I use an array of function pointers?
Short answer: Here functab is an array of function pointers, and the array is initialized with pointers to functions ram and date. This also explains the name functab which is likely from "FUNCtion TABle".
Long answer: In C you can get a pointer to a function and save it to a variable. A variable used in this fashion is known as a function pointer.
For example, funcptr variable below will contain the address of do_stuff's entry point:
int do_stuff(const char* x) { ...do stuff.. }
...
ftype_t funcptr = &do_stuff;
...
(*funcptr)("now"); // calls do_stuff()
This will only work if you have already defined the type of funcptr, which is ftype_t here. The type definition should take this form:
typedef int (*ftype_t)(const char*);
In English, this means ftype_t is being defined as a type of function that takes const char* as its only argument and returns int.
If you didn't want to typedef only for this, you could have achieved the same thing by doing below:
int (*funcptr)(const char*) = &do_stuff;
This works, but its syntax is confusing. Also it gets quite ugly if you attempt to do something like building an array of function pointers, which is exactly what your code does.
Shown below is equivalent code, which is much easier to understand:
typedef static const char*(*myfn_t)(void);
const myfn_t functab[] = { &ram, &date };
(The & (address of) is usually optional, but recommended. )
Complex variable declarations need to be read inside out in C:
functab is the identifier of the variable, so we start reading here...
functab[] it is an array...
*const functab[] of constant pointers...
(*const functab[])(...) to functions...
(*const functab[])(void) that take no arguments...
const char*(*const functab[])(void) but return a const char*.
The meaning of static depends on whether it's outside or inside of a function. If it's outside, the static means that functab is declared with file scope (i.e. a global variable that's only visible inside a single .c file). If it's inside a function, it means that functab is a global variable that's only visible inside that function.
The = { ram, date } initialize the array with two members. Both ram and date should be functions that are declared as const char* ram(void).
The effect of this declaration is, that the following function calls are equivalent:
const char* result = ram();
const char* result = functab[0]();
I am new to C language and I am having a problem that I really don't understand. I am trying to get an array from another function but when I try to extract the information, it gives me the following warning:
Implicit declaration of function 'getk_vector_calculation' is invalid in C99
Array initializer must be an initializer list or string literal
Here is the code:
int k_vector_calculation(int krec[3])
{
...
krec [0] = l*u[0]+m*v[0]+o*[0] ;
krec [1] = l*u[1]+m*v[1]+o*[1] ;
krec [2] = l*u[2]+m*v[2]+o*[2] ;
return k_vector_calculation( &krec[3] )
}
int main ()
{
char krec[3] = getk_vector_calculation(&krec[3]);
...
}
in your main() the function you called is getk_vector_calculation() [which is not k_vector_calculation()] and which is not declared or defined before the usage.
To resolve this,
either #include the header file containg the declaration of getk_vector_calculation() in your sorce file. [Considering getk_vector_calculation() is in some other file]
or, add a forward declaration of getk_vector_calculation() before main() and define getk_vector_calculation() somewhere.
To know more about implicit declaration, you can check this question.
EDIT:
As others have pointed out, there are many more problems in your code snippet. But since the question title is limited to implicit declaration error, IMO, this answer should do the needful. The remaining error(s) is(are) altogether a different aspect.
In older versions of C, functions that had not been declared yet were still able to be called, and it was assumed that they returned int and took an unspecified number of arguments. Strictly speaking, in C99, it is not permitted to call a function without declaring it first.
In your case however, you are trying to call a function called getk_vector_calculation but you have defined a function called k_vector_calculation (no get at the beginning).
You are also trying to initialise an array using a function, which is not permitted (in C, functions cannot return arrays). Simply declare the array and call k_vector_calculation as a separate statement, e.g.:
int krec[3] = {0};
k_vector_calculation(krec);
Don't use &krec[3] as this points to an invalid location. Use &krec[0] to provide the address of the first element in the array, or equivalently just krec will do. N.b. also that you declare an array of type char, but your function accepts a pointer to int, and these types are not compatible. Your function also calls itself unconditionally so there is a guaranteed infinite recursion if the snipped out code does not conditionally return. If your function doesn't need to call itself, and it doesn't return a value of any importance, change the return type to void to indicate it has no return value.
Since you are using C99, you can take advantage of using the static keyword in your function's parameter declaration:
void k_vector_calculation(int krec[static 3])
{
// ... other code here ...
krec[0] = l*u[0]+m*v[0]+o*[0];
krec[1] = l*u[1]+m*v[1]+o*[1];
krec[2] = l*u[2]+m*v[2]+o*[2];
}
The above code declares a function that takes as an argument an array of at least 3 int.
Several issues, here:
As Sourav Ghosh pointed out, you define k_vector_calculation(), but then try to call getk_vector_calculation(). You have to use the right names.
You say you want to "get an array from another function" - you just can't do this in C.
You don't show all your code for k_vector_calculation(), but as shown, this function will call itself forever, because the last thing it does is to unconditionally call itself again. If you have a recursive function, you need to give it a way to terminate.
&krec[3] is the address of the fourth element of the array k, which is not want you want to be doing, here, especially since your array only contains 3 elements. To refer to the array itself, just use krec.
char krec[3] = getk_vector_calculation(&krec[3]); is invalid for numerous reasons. One, you can't initialize arrays in this way in C. Two, see point (4) for your argument. Three, even if you could initialize arrays this way in C, you'd be trying to pass an uninitialized array to a function, initialize it in there, and then try to initialize your original array with the result. It just makes no sense.
You also write your functions to work with an array of int, but declare krec in main() as an array of char.
It's not clear what you want k_vector_calculation() to do, but you just can't return arrays in C like that. Probably what you want to do is just pass the array to the function, have the function work on in, and return nothing. For instance:
#include <stdio.h>
void k_vector_calculation(int kvec[])
{
kvec[0] = 1;
kvec[1] = 2;
kvec[2] = 3;
}
int main(void)
{
int kvec[3];
k_vector_calculation(kvec);
for ( int i = 0; i < 3; ++i ) {
printf("kvec[%d] is %d.\n", i, kvec[i]);
}
return 0;
}
I need to declare an array of pointers to functions like so:
extern void function1(void);
extern void function2(void);
...
void (*MESSAGE_HANDLERS[])(void) = {
function1,
function2,
...
};
However, I want the the array to be declared as constant -- both the data in the array and the pointer to the data. Unfortunately, I do not recall where to place the const key-word(s).
I'm assuming the actual pointer, MESSAGE_HANDLERS in this case, is already constant because it is declared as an array. On the otherhand, couldn't the function pointers within the array be change at runtime if it is declared as shown?
There is a technique to remember how to build such type. First try to read pointers starting from their name and read from right to left.
How to declare that stuff without help?
Arrays
T t[5];
is an array of 5 T. To make T a function type, you write the return-type to the left, and the parameters to the right:
void t[5](void);
would be an array of 5 functions returning void and taking no parameters. But functions itself can't be stuffed in arrays! They are not objects. Only pointers to them can.
What about
void * t[5](void);
That's still wrong as it would just change the return-type to be a pointer to void. You have to use parentheses:
void (*t[5])(void);
and this will actually work. t is an array of 5 pointers to functions returning void and taking no parameters.
Great! What about an array of pointers to arras? That's very similar. The element type appears at the left, and the dimension at the right. Again, parentheses are needed because otherwise the array would become a multidimensional array of integer pointers:
int (*t[5])[3];
That's it! An array of 5 pointers to arrays of 3 int.
What about functions?
What we have just learned is true about functions too. Let's declare a function taking an int that returns a pointer to another function taking no parameter and returning void:
void (*f(int))(void);
we need parentheses again for he same reason as above. We could now call it, and call the returned function pointed to again.
f(10)();
Returning a pointer to function returning another pointer to function
What about this?
f(10)(true)(3.4);
? In other words, how would a function taking int returning a pointer to a function taking bool returning a pointer to a function taking double and returning void would look like? The answer is that you just nest them:
void (*(*f(int))(bool))(double);
You could do so endless times. Indeed, you can also return a pointer to an array just like you can a pointer to a function:
int (*(*f(int))(bool))[3];
This is a function taking int returning a pointer to a function taking bool returning a pointer to an array of 3 int
What does it have to do with const?
Now that the above explained how to build up complexer types from fundamental types, you can put const at places where you now know where they belong to. Just consider:
T c * c * c ... * c name;
The T is the basic type that we end up pointing to at the end. The c stands for either const or not const. For example
int const * const * name;
will declare name to have the type pointer to a constant pointer to a constant int. You can change name, but you cannot change *name, which would be of type
int const * const
and neither **name, which would be of type
int const
Let's apply this to a function pointer of above:
void (* const t[5])(void);
This would actually declare the array to contain constant pointers. So after creating (and initializing) the array, the pointers are const, because the const appeared after the star. Note that we cannot put a const before the star in this case, since there are no pointers to constant functions. Functions simply can't be const as that would not make sense. So the following is not valid:
void (const * t[5])(void);
Conclusion
The C++ and C way of declaring functions and arrays actually is actually a bit confusing. You have to get your head around it first, but if you understand it, you can write very compact function declarations using it.
In situations like this, do a typedef to name your function signature, that makes it far simpler:
typedef void MESSAGE_HANDLER(void);
with that in place, it should be just:
MESSAGE_HANDLER * const handlers[] = { function1, function2 };
To get the actual content of the array constant.
EDIT: Removed pointer part from the typedef, this really is better (live and learn).
cdecl says:
cdecl> explain void (* const foo[])(void)
declare foo as array of const pointer to function (void) returning void
Is it what you need?
With VisualStudio 2008, I get:
void (* const MESSAGE_HANDLERS[])(void) = {
NULL,
NULL
};
int main ()
{
/* Gives error
'=' : left operand must be l-value
*/
MESSAGE_HANDLERS = NULL;
/* Gives error
l-value specifies const object
*/
MESSAGE_HANDLERS[0] = NULL;
}
I am not sure if this will work in 'C'. it does work in 'C++':
First define MESSAGE_HANDLERS as a type:
typedef void (*MESSAGE_HANDLER)();
Then, use the type definition to declare your array a constant:
MESSAGE_HANDLER const handlers[] = {function1, function2};
The trick is in the typedef, if you can do the same semantically in 'C', it should work too.