hi I'm attempting to create a program that accepts a 7 element array as an argument and returns the third through fifth element of that array to a smaller array however i'm currently getting this error
assign8p7.c: In function 'main':
assign8p7.c:18:2: warning: passing argument 1 of 'copysect' makes pointer from
integer without a cast [enabled by default]
assign8p7.c:3:6: note: expected 'int *' but argument is of type 'int'
from what i can tell the warning has a problem with me passing it an array in the arguments does anyone know how i might fix this? also any other advice for my code is welcome.
#include <stdio.h>
int *copysect(int ar[],int start,int end)
{
int i;
static int retar[3];
for(i = 0; i<3;i++)
{
retar[i+start]=ar[i+start];
}
return retar;
}
int main(int argc, char const *argv[])
{
int arry[7] = {1,2,3,4,5,6,7};
int miniarry[3];
miniarry[0] = *copysect(arry[0],3,5);
return 0;
}
int *copysect(int ar[],int start,int end)
Okay, copysect takes as its first parameter an array of integers.
miniarry[0] = *copysect(arry[0],3,5);
Oops, you passed it a single integer instead of an array.
You are calling the function copysect with the first element in the array, not the pointer to the array. The correct call is:
copysect(arry,3,5);
You could calculate the difference of the array dynamically. Now the caller of copysect function has to know that the difference between start and end is 2.
int retar[end - start + 1]
The assignment in the for loop is wrong. You are dereferencing a value that is out of scope of retar array
retar[i]=ar[i+start];
When calling the copysect function, you are assigning only the first element in the miniarry by dereferencing the array that the function returns, instead of the whole array.
It's not the best idea to have a static array in a function (that would be problematic if you called the function more than once, etc). Instead, you could declare the smaller array elswhere and pass it as a parameter to the function.
void copysect(int ar[], int retar[], int start,int end, )
Related
I started learning C language a week ago.
Just for the test I decided to write a tictactoe game.
I have a field.
int field[3][3];
And a function printField
void printField(int field[3][3]){
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
printf("%i", field[i][j]);
}
printf("\n");
}}
It's working in main like this:
int main(){
printField(field);}
BUT if I change
void printField(int field){...}
or
void printField(int field[][]){...}
It gives me a bunch of errors:
subscripted value is neither array nor pointer nor vector
passing argument 1 of ‘printField’ makes integer from pointer without a cast
note: expected ‘int’ but argument is of type ‘int (*)[3]’
Why can't I pass the array like this?
Are there any more ways to pass it?
The function is independent of any call to the function. So the function cannot guess from the rest of the program what the array size is. In the function body you have to have constants or variables to represent all dimensions.
You can use variables for this instead of fixed size:
void printField(int r, int c, int field[r][c])
{
for(int i = 0; i < r; i++)
for(int j = 0; j < c; j++)
printf("%i", field[i][j]);
printf("\n");
}
And to call the function:
printField(3, 3, field);
You can compute the dimensions from the array's name. Using a macro confines the ugly syntax:
#define printField(a) printField( sizeof(a)/sizeof((a)[0]), sizeof((a)[0]) / sizeof((a)[0][0]), (a) )
int f1[3][3] = { 0 };
printField(f1);
int f2[4][5] = { 0 };
printField(f2);
When you write an array as a function, the compiler will silently "adjust" that array and replace it with a pointer to the first element. So when you write void func (int x[3]) the compiler silently replaces this with void func (int* x) where the pointer points at the first item of the array.
The reason why C was designed this way is not avoid having large arrays getting pushed on the stack, which would be slow and memory-consuming.
In your case, the function void printField(int field[3][3]) gets silently adjusted behind the lines to
void printField(int (*field)[3])
which is an array pointer pointing at the first element, which is a int[3] array. Which can still be used as field[i][j], so all is well. You can pretend that it is an array inside the function.
void printField(int field) obviously doesn't make any sense. This is not an array but a single item. You can't use [] on a plain int and that's what the compiler is telling you: "subscripted value is neither array nor pointer nor vector".
void printField(int field[][]){...} doesn't work either, because an empty [] means "declare an array of incomplete type". It can't be used before the array size is defined.
In case of void printField(int field[]) this happens to work because of the above mentioned "array adjustment" rule of functions. The compiler doesn't have to know the array size, because it just replaces the array with int* anyway.
But in the case with two unknown dimensions, the compiler tries to adjust int field[][] to int (*field)[]. This is a pointer to an array of incomplete type and can't be used by the function.
You could however do int field[][3] and it will work just fine.
In C You can pass you array like this
void printField(int **field){...}
it's much better to work with pointeur than to work with static array :)
I understand why this does not work:
int main(int argc, char *argv[]) {
char *names[] = {"name1", "name2", "name3", "name4"};
int i = 0;
while (i++ <= 3) {
printf("%s\n", *names++);
}
}
Error:
a.c: In function 'main':
a.c:16: error: wrong type argument to increment
shell returned 1
It's because I am trying to increment an array variable (and NOT a pointer). Please don't mind the line number in the error message, I have lot's of commented code above and below what I have put up here.
However, I do not understand why this piece of code works:
void myfunc(char *names[]) {
int i = 0;
while (i++ <= 3) {
printf("%s\n", *names++);
}
}
int main(int argc, char *argv[]) {
char *names[] = {"name1", "name2", "name3", "name4"};
myfunc(names);
}
How can we increment names in myfunc()? It's still a local array variable in myfunc().
Could someone please help?
Thanks.
In the 1st example names is an array. Arrays cannot be incremented.
In the 2nd example names is a pointer. Pointers can be incremented.
Background to why the 2nd example compiles:
A [] in a variable definition in a function declaration is the same as (another) *.
So this
void myfunc(char * names[]);
is equivalent to
void myfunc(char ** names);
The latter makes it obvious that here names is not an array but a pointer.
When you pass an array as a function argument, it turns it into a pointer to the first element in the array. This means that when you declare an array and attempt to increment it directly, you are trying to increment an array. When you pass the array as an argument, on the other hand, it is passed as a pointer, so you can increment it.
If you wish to pass the array as an array, and not as a pointer, you might consider using std::array, which is a fixed size container.
EDIT: I apologise. std::array is only available in C++.
When you pass array to a function it decays into pointer.
Refer here to know about array-decaying
I'm having difficulty passing a 2D array of structs. The size of the 2D array is dynamic (depends on given input parameters). I get the error:
maze_array.c:76:14: error: incompatible types when assigning to type ‘BlockNode {aka struct BlockNode}’ from type ‘BlockNode * {aka struct BlockNode *}’
Maze[i][j]=myBlockNode;
Here is my code:
int main(int argc, char *argv[]){
int MazeWidth=1;
int MazeHeight=1;
int NumOfAvatars=1;
BlockNode* Maze[MazeWidth][MazeHeight];
InitializeArray(Maze[0],MazeWidth,MazeHeight,NumOfAvatars);
return 1;
}
int InitializeArray(BlockNode** Maze,int MazeWidth, int MazeHeight, int NumOfAvatars){
for (int i=0; i<MazeWidth;i++)
{
for (int j=0; j<MazeHeight;j++)
{
//Initialize a BlockNode
printf("HERE1\n");
BlockNode *myBlockNode;
myBlockNode=calloc(1,sizeof(BlockNode));
myBlockNode->North=0;
myBlockNode->South=0;
myBlockNode->East=0;
myBlockNode->West=0;
int myArray[NumOfAvatars];
memset(myArray,0,sizeof(myArray));
memcpy(myBlockNode->AvatarVisited,myArray,sizeof(myArray));
//Place BlockNode in the Maze
Maze[i][j]=myBlockNode;
}
}
/*
printf("North %d\n", Maze[0][0]->North);
printf("AvatarVisted %d\n", Maze[0][0]->AvatarVisited[0]);
*/
return 1;
}
You should take into account that a 2D array is not equal to pointer to pointer, for example, if you try to compile...
int array[10][10];
int** p=array;
...you would get a similar error.
If you want to pass a 2D array of pointers and use it like AnArray[i][j] = something, you should change the function declaration to...
int InitializeArray( BlockNode* Maze[][MazeHeight]
, int MazeWidth
, int MazeHeight
, int NumOfAvatars )
...or...
int InitializeArray( BlockNode* (*Maze)[MazeHeight]
, int MazeWidth
, int MazeHeight
, int NumOfAvatars )
...and call it like...
InitializeArray( Maze
, MazeWidth
, MazeHeight
, NumOfAvatars );
Also, read this.
You haven't actually asked a question, but I will assume you are seeking an explanation of the compiler error.
Within your function, Maze[i][j] will be of type BlockNode, since it is dereferencing a BlockNode ** (pointer to a pointer to a Blocknode) twice. myBlockNode is of type BlockNode *. That is the cause of the compiler error - there is no valid assignment of the form some_BlockNode = some_pointer_to_BlockNode.
The real problem, however, is that you don't properly understand the difference between pointers and arrays. You'll need to read up on such topics before anyone will be able to offer useful (that will make sense to you) advice on how to do what you want.
Please let me know how can I pass a pointer to the array of structures in C as a function argument.
Below is my code.
#include <stdio.h>
#include<strings.h>
typedef struct _Alert
{
char MerchantNo[21];
time_t last_update;
} Alert;
typedef Alert *PALERT;
int set(PALERT palertMerch[5], int *merchnoIndex, char * txnMerchant)
{
strcpy(palertMerch[*merchnoIndex]->MerchantNo, txnMerchant);
*(merchnoIndex) = *(merchnoIndex) + 1 ;
return 0;
}
int main()
{
Alert alert[5];
for(int i =0; i<5;i++)
{
memset(alert[i].MerchantNo, 0x00, 21);
alert[i].last_update = (time_t)0;
}
char *p = "SACHIN";
int index = 0;
set(alert[5], index, p);
}
Error message
"3.c", line 34: argument #1 is incompatible with prototype:
prototype: pointer to pointer to struct _Alert {array[21] of char MerchantNo, long last_update} : "3.c", line 14
argument : struct _Alert {array[21] of char MerchantNo, long last_update}
"3.c", line 34: warning: improper pointer/integer combination: arg #2
cc: acomp failed for 3.c
You just pass the array, it'll get decayed to the pointer to the first array element:
set( alert, &index, p );
Note that I also corrected your second error of passing integer as a pointer for the second argument.
Edit 0:
I missed the declaration of PALERT - your function definition is wrong, it should be something like:
int set( PALERT palertMerch, int* merchnoIndex, const char* txnMerchant )
{
assert( *merchnoIndex >= 0 && *merchnoIndex < 5 );
strcpy( palertMerch[*merchnoIndex].MerchantNo, txnMerchant );
...
}
I know, arrays and pointers are a bit confusing in C, and you were trying to jump to arrays of pointers already :)
You actually cannot pass an array to a function. What happens when you do, is that a pointer to the first element in an array is passed in instead. (That proccess is often described as "an array decays into a pointer").
That is,
set(alert, index, p);
Is just the same as:
set(&alert[0], index, p);
(Note that you called it as set(alert[5], index, p); , this just passes in the 6. element of your array , which btw is invalid, as your array only have room for 5 elements.)
So, what you do when you want to pass an array to a function is you
Pass a pointer to the first element in the array (which can be done by just writing name_of_array or &name_of_array[0]
Add another argument that is the length of the array. You might need this as if your array can have different sizes, and you cannot know how many elements an array have, if all you got is a pointer to its first element:
Let's skip item 2. above for now, you can just do:
//PALERT is already a pointer, otherwise specify the first argument as:
//ALERT *palertMerch
int set(PALERT palertMerch, int *merchnoIndex, char * txnMerchant)
{
strcpy(palertMerch[*merchnoIndex]->MerchantNo, txnMerchant);
*(merchnoIndex) = *(merchnoIndex) + 1 ;
return 0;
}
And call it like:
char *p = "SACHIN";
int index = 0;
set(alert, index, p);
btw, unless you have a good reason, try not to hide a pointer in a typedef as you do in typedef Alert *PALERT; doing so often gets confusing.
remove the array brackets and it should work.
The reason for this is that array notation is an easier way to represent sequences of items in memory. For example, in an array a[5], you can access the third element as a[3] or *(a+3).
Your function takes type PALERT *[5]. You are passing in Alert[5] instead. There are other problems with your code that need fixing before it will successfully run.
Hi
I'm new to c language i hava a problem :
i want to send a 2-d array to a function via pointer.
The function should return pointer to 2-d array.
I wrote the following code for this :
#include<stdio.h>
int* put(int *b);
int main()
{
int a[2][3],i,j;
system("clear");
put(a);
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("\na[%d][%d]= %d",i,j,a[i][j]);
}
}
return 0;
}
int* put(int *b)
{
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
b[i][j]=i;
}
}
return b;
}
when i compile it with gcc2de.c it shows following errors :
2de.c: In function ‘main’:
2de.c:9: warning: passing argument 1 of ‘put’ from incompatible pointer type
2de.c:3: note: expected ‘int *’ but argument is of type ‘int (*)[3]’
2de.c: In function ‘put’:
2de.c:28: error: subscripted value is neither array nor pointer
2de.c: In function ‘main’:
2de.c:32: error: expected declaration or statement at end of input
Than i just change the code of function which is following :
#include<stdio.h>
int* put(int **b);
int main()
{
int a[2][3],i,j;
system("clear");
put(a);
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("\na[%d][%d]= %d",i,j,a[i][j]);
}
}
return 0;
}
int* put(int **b)
{
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
b[i][j]=i;
}
}
return b;
}
when i complie it i got following errors:
2de.c: In function ‘main’:
2de.c:9: warning: passing argument 1 of ‘put’ from incompatible pointer type
2de.c:3: note: expected ‘int **’ but argument is of type ‘int (*)[3]’
2de.c: In function ‘put’:
2de.c:31: warning: return from incompatible pointer type
2de.c: In function ‘main’:
2de.c:32: error: expected declaration or statement at end of input
2de.c: In function ‘main’:
2de.c:9: warning: passing argument 1 of ‘put’ from incompatible pointer type
2de.c:3: note: expected ‘int **’ but argument is of type ‘int (*)[3]’
2de.c: In function ‘put’:
2de.c:31: warning: return from incompatible pointer type
2de.c: In function ‘main’:
2de.c:32: error: expected declaration or statement at end of input
what I'm doing wrong ?
can anybody tell me what is the way to pass 2d-array via pointers to a function ?
can anybody tell me how to return two d array via pointer in a function
The first error that you have is that you are not passing a correct type as declared by your function. So to clean up your code with the least amount of corrections, it would probably look something like this:
#include<stdio.h>
void put(int *b);
int main()
{
int a[2][3],i,j;
put(&a[0][0]);
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("\na[%d][%d]= %d", i, j, a[i][j]);
}
}
printf("\n\n");
system("PAUSE"); // Not recommended, but works for now
return 0;
}
void put(int *b)
{
int count = 1;
int i, j;
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
//b[i][j]=i;
*(b + ((i*3) + j)) = count++;
}
}
}
The two major corrections are:
You pass in the start address of your 2-D array explicitly by addressing it as &a[0][0].
Also, note the pointer arithmetic that you'll have to use when you use an int *b as well.
Note also that since you're passing in a pointer, you're modifying the value at that address location. Thus there is no need to return a pointer back at all.
Hope it helps. Cheers!
where are you storing the return value from put ?
the declaration should be int** put( int **) according yo your code.
The first error you have is that you are trying to define a function inside another function. The simplest thing to do is to just define put where you declare it:
int put()
{
/* definition of put */
}
int main()
{
/* body calls put */
}
The second problem is that in neither code snippet are you passing a compatible parameter to put.
If you want to pass a to a function then you should note that arrays as arguments always decay to a pointer to their first element.
a has type int [2][3], i.e. an array of 2 arrays of 3 ints. This will decay to a pointer to an array of 3 ints or int (*)[3]. This should explain the compile error that you are getting. You should declare put either as:
void put(int (*b)[3]);
or as the completely equivalent:
void put(int b[][3]);
Because you cannot pass arrays by value the compiler will automatically convert a function declaration which takes an array parameter to one which takes the equivalent pointer parameter.
I've changed the return type to void as you don't use or need the return value as you are passing the parameter by pointer. You should remove return b; from your definition of put.
Hint: Don't think of int[2][3] as a 2-d array but as an array of arrays.
You can not return a 2d-array from a function in C, you can only return a 1d-array of pointers to the first elements of a 2d-array.
Maybe you could find useful this:
Pass 2d array to function in C?
or this:
C++ Returning multidimension array from function
1.you should declare or define the function before use it,it's different with other popular luanguage.
2.you do not need to return the pointer in the function put ,the data in array has be changed
3.you needed to notice the type ,the type of int array[][] is int **