I know there are similar questions, but I still can't figure this out, even though I've been reading for 2 hours.
struct box
{
char letter;
int occupied; //0 false, 1 true.
};
void fill(struct box**, int, int, char*); //ERROR HERE**
int main(int argc, char** argv)
{
int length=atoi(argv[4]),
width=atoi(argv[5]),
char alphabet[26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
struct box soup[length][width];
fill(soup, length, width, alphabet); //HERE**
}
void fill(struct box soup[][], int length, int width, char*alphabet) //AND HERE**
{
//omitted
}
These are the errors I'm getting when I compile:
warning: passing argument 1 of ‘fill’ from incompatible pointer type [enabled by default]
fill(soup, length, width, alphabet);
^
note: expected ‘struct box **’ but argument is of type ‘struct box (*)[(sizetype)(width)]’
void fill(struct box **, int, int, char*);
^
error: array type has incomplete element type
void fill(struct box soup[][], int length, int width, char*alphabet)
^
I don't get why that fails, while some other functions I have like this one, does work:
void wordsToMemory(char**, char*); //prototype
char* dictionary[Nwords];
wordsToMemory(dictionary, argv[1]); //calling the method
void wordsToMemory(char* dictionary[], char* argv) //function body
{
//omitted
}
This will get it to compile:
void fill(struct box** soup, int length, int width, char* alphabet)
or
void fill(struct box* soup[], int length, int width, char* alphabet)
When using [][] you get an error because there is no conversion from struct box* to struct box.
Array decays into pointers. When you are passing a single dimension array to a function, the function which receives the array can look like this
void fun(char a[10]) void fun(char a[]) void fun(char *a)
{ { {
... OR ... OR ...
} } }
Arrays decays into pointer, not always true...Arrays decay into pointers is not applied recursively...Means, 2D Array decays to pointer to array not to pointer to pointer so that is why you are getting the error.
When you are passing 2D array to function, the function which receives the 2D array should look like this...
void fun(char *a[10])
{
...
}
void fill(struct box**, int, int, char*);
This declaration is wrong because it says that the function's first argument has to be of type pointer to pointer to struct box, while you have no objects of type pointer to struct box in main to refer to, rather you have, as you say, a matrix (a two-dimensional array, an array of arrays) of structs.
So, the prototype
void fill(struct box [][], int, int, char *);
is almost correct, except, only the major (the first) dimension of a matrix declaration can be omitted, so we need to specify at least the width therein, which conveniently is also passed to the function, only the parameters' order has to be changed so that width is defined early enough:
void fill(int length, int width, struct box soup[][width], char *alphabet);
The function call in main is consequently:
fill(length, width, soup, alphabet);
Related
In my main function i create a dynamic 3D array and succesfull alocate it.
int ***board = (int ***)malloc(counter * sizeof(int **));
for(int i = 0; i < counter; i++){
board[i] = (int **) malloc(dimension[i] * dimension[i] * sizeof(int));
}
Then i wan to pass it to a function defined as:
void readPuzzle(int board[][MAX][MAX], int *dimension, int counter,const char *);
I pass it like this:
readPuzzle(board, dimension, counter, argv[1]);
But i keep getting this error, i searched for it but never could fix it!
main.c: In function ‘main’:
main.c:22:13: warning: passing argument 1 of ‘readPuzzle’ from incompatible pointer type [-Wincompatible-pointer-types]
readPuzzle(board, dimension, counter, argv[1]);
^~~~~
In file included from main.c:4:0:
headers.h:7:6: note: expected ‘int (*)[100][100]’ but argument is of type ‘int ***’
void readPuzzle(int board[][MAX][MAX], int *dimension, int counter, const char *);
If your 2D arrays have variable dimensions, you need int ***, but this prototype
void readPuzzle(int board[][MAX][MAX], int *dimension, int counter, const char *);
isn't compatible with board passed as int *** because it required an array of 2D arrays, not a triple pointer.
So fix it like that:
void readPuzzle(int ***board, int *dimension, int counter, const char *);
but you still need to keep track of the dimensions for each "slice".
The alternative, if the 2D arrays have fixed dimensions MAX*MAX is to allocate an array of 2D arrays like this:
int (*board)[MAX][MAX] = malloc(counter*sizeof(*board));
now you can pass board as int board[][MAX][MAX]. Of course, if not all data is used, you still need to keep track of max dimensions somewhere.
My code needs to pass an array to a void pointer (The struct has (void *) that cannot be modified). The two versions of code below produce the same output but the latter has two warnings. My question is which of the two methods is preferred? Is there a way to typecast to remove the warnings?
This version does not have warnings and produces the output as expected:
#include <stdio.h>
void test(void *var_arr, char var_1);
typedef struct {
char chip;
void *buffer;
}test_struct;
int main()
{
int test_array[3] = {3,7,5};
char var_1 = 0x20;
printf("Hello, World!\n");
test(&test_array, var_1);
return 0;
}
void test(void *var_arr, char var_1)
{
int i;
test_struct var_ts;
var_ts.chip = var_1;
var_ts.buffer = var_arr;
for (i=0; i<3; ++i)
printf("\nThe data values are : %X \n\r", *((int *)var_ts.buffer+i));
}
Hello, World!
The data values are : 3
The data values are : 7
The data values are : 5
This version below has two warnings but compiles and produces the output expected:
Warning(s):
source_file.c: In function ‘main’:
source_file.c:17:10: warning: passing argument 1 of ‘test’ from incompatible pointer type
test(&test_array, var_1);
^
source_file.c:3:6: note: expected ‘int ’ but argument is of type ‘int ()[3]’
void test(int *var_arr, char var_1);
#include <stdio.h>
void test(int *var_arr, char var_1);
typedef struct {
char chip;
void *buffer;
}test_struct;
int main()
{
int test_array[3] = {3,7,5};
char var_1 = 0x20;
printf("Hello, World!\n");
test(&test_array, var_1);
return 0;
}
void test(int *var_arr, char var_1)
{
int i;
test_struct var_ts;
var_ts.chip = var_1;
var_ts.buffer = (void *)var_arr;
for (i=0; i<3; ++i)
printf("\nThe data values are : %X \n\r", *((int *)var_ts.buffer+i));
}
The lower version tells you what the problem was in the first one: passing a pointer to the array instead of a pointer to the first element.
Passing a pointer to the array, which has the type int(*)[3]:
test(&test_array, var_1);
Passing a pointer to the first element, which has the type int*:
test(test_array, var_1);
The code happens to work because the two pointers points to the same address, so the pointer to the array appears to work, but the code is still undefined.
Passing a pointer to the first element is correct, as the array test_array, which has the type int[3] decays to type int* when it is passed to the function.
The warnings are shown because the compiler does static analysis on the code and identified a possible cause of bugs.
When using the void pointer the compiler cannot do this static analysis since it does not know what type is used.
If the datatype is known I would always prefer using this type as pointer instead of the void pointer. I would only use the void pointer when it is acceptable that the pointer can point to anything. In the end this is about personal taste and the code guidelines you follow.
I am very new to this topic pointers in C. I have one code as follow.
The output of this code is 0.000000 but i can't understand why so?
void foo(float *);
int main()
{
int i=10,*p=&i;
foo(&i);
}
void foo(float *p)
{
printf("%f",*p);
First check this site to know pointer behavior.
In your code you declare float type parameter but pass integer value.
Try this one:
#include <stdio.h>
void foo(int *p)
{
printf("%d",*p);
}
int main()
{
int i=10,*p=&i;
foo(&i);
return 0;
}
It gives The below warning.
test.c:6:2: warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
Because, you are passing the address to the foo function but expected argument is float *.
Then you are defining the p pointer as a integer type.
The variable p does not points the i.
But in foo function calling, there is no address is passed.
So, It gives warning and 0.0000.
So, change your code like below.
void foo(float *);
int main()
{
flat i=10,*p=&i; //Change the data type
foo(&i);
}
void foo(float *p)
{
printf("%f",*p);
}
Now the output is
10.0000
I am trying to implement a simple swap function using function pointer but when I assign the function's address to a function pointer:
`pointersTofunctionB.c:14:6:warning: assignment from incompatible pointer type [enabled by default].
This is my code:
#include <stdio.h>
void intSwap(int *a,int *b);
void charSwap(char *a,char *b);
void (*swap)(void*,void*);
int main(int argc, char const *argv[])
{
int a=20,b=15;
char c='j',d='H';
swap=&intSwap;// warning here
swap(&a,&b);
printf("%d %d\n",a,b);
swap=&charSwap;// warning here also
swap(&c,&d);
printf("%c %c\n",c,d );
return 0;
}
void intSwap(int *a,int *b)
{
*a=*a+*b;
*b=*a-*b;
*a=*a-*b;
}
void charSwap(char *a,char *b)
{
char temp;
temp=*a;
*a=*b;
*b=temp;
}
How can I solve this warning?
The warnings appear due to the following quote from the C Standard
6.3.2.3 Pointers
8 A pointer to a function of one type may be converted to a pointer to
a function of another type and back again; the result shall compare
equal to the original pointer. If a converted pointer is used to
call a function whose type is not compatible with the referenced type,
the behavior is undefined.
That two functions would be compatible their parameters shall have compatible types
6.7.6.3 Function declarators (including prototypes)
15 For two function types to be compatible, both shall specify
compatible return types.146) Moreover, the parameter type lists, if
both are present, shall agree in the number of parameters and in use
of the ellipsis terminator; corresponding parameters shall have
compatible types.
In your functions parameters are declared as pointers. So that they (pointers) would be compatible they shall be pointers to compatible types
6.7.6.1 Pointer declarators
2 For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.
However types int or char on the one hand and type void on the other hand are not compatible types.
You could define your functions the following way
void intSwap( void *a, void *b )
{
int *x = a;
int *y = b;
*x = *x + *y;
*y = *x - *y;
*x = *x - *y;
}
void charSwap( void *a, void *b )
{
char *c1 = a;
char *c2 = b;
char temp = *c1;
*c1 = *c2;
*c2 = temp;
}
You need to change
swap=&intSwap;
to
swap=intSwap;
Same goes for swap=&charSwap; also.
Again, your function signature(s) does not match the function pointer signature.
Your function is
void intSwap(int *a,int *b);
which is of return type void, two input parameters of int *, whereas, your function pointer signature is
void (*swap)(void*,void*);
which takes two void *s. Same for void charSwap function also.
Either yoou have to change the function signature, or you have to use a different function pointer prototype. Otherwise, the behaviour is undefined. [as mentioned in Vlad's answer].
#include<stdio.h>
using namespace std;
void intSwap(int *a,int *b);
void charSwap(char *a,char *b);
void (*swap)(int*,int*);
void (*swap1)(char*,char*);
int main()
{
int a=20,b=15;
char c='j',d='H';
swap=&intSwap;// warning here
swap(&a,&b);
printf("%d %d\n",a,b);
swap1=&charSwap;// warning here also
swap1(&c,&d);
printf("%c %c\n",c,d );
return 0;
}
void intSwap(int *a,int *b)
{
*a=*a+*b;
*b=*a-*b;
*a=*a-*b;
}
void charSwap(char *a,char *b)
{
char temp;
temp=*a;
*a=*b;
*b=temp;
}
**If you want you can use like it......**
To remove the warning, code this overload:
void (*swap)(int *,int*);
void (*swap)(char *,char*);
I'm trying to modify a multidimensional array. This is my function code -
void rot90(int n,char **a)
{
int i,j;
int b[n][n];
for(i=n-1;i>=0;i--)
{
for(j=0;j<n;j++)
{
a[n-1-i][j]=b[j][i];
}
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
a[i][j]=b[i][j];
}
}
}
And in my main function , I am calling it as -
A is a 2d Array nxn.
rot90(n,A);
which shows the following error on compilation -
warning: passing argument 2 of ‘rot90’ from incompatible pointer type [enabled by default]
note: expected ‘char **’ but argument is of type ‘char (*)[10]’
what is the right way to do it?
Thanks.
If A is an NxN array, and you're using a VLA (which it looks like from your snippet), then the prototype needs to be either
void rot90( int n, char (*a)[n] )
or
void rot90( int n, char a[][n] )
or
void rot90( int n, char a[n][n] )
The second two forms are interpreted the same as the first; a is a pointer to an n-element array of char.