Function with bidimensional array as parameter - c

I read that to declare a function with a bidimensional array as parameter, I need to specify the number of columns of the array, but if I don't know the size of the matrix I need to use double pointer. However, I can't understand this process very well, can someone give me some short and simple example of this type of function?
Thank you
Also, I tried to write a program but it gives me some warning.
#include<stdio.h>
int diagonal(int**,int );--->first note
int main(){
int N;
scanf("%d",&N);
int array[N][N];
int i;
int j;
printf("Insert the numbers:\n");
for(i=0;i<N;i++){
for(j=0;j<N;j++){
scanf("%d",&array[i][i]);
}
}
diagonal(&array[N][N],N); ---->second warning
}
int diagonal(int**A,int N){
int i;
int condition=0;
for(i=0;i<N-1;i++){
if(A[0][0]!=A[i+1][i+1]){
return -1;
}else{
condition=1;
}
}
if(condition==1){
int val=A[i][i];
int sum= N*val;
return sum;
}
}
Compiler output:
3|note: expected 'int **' but argument is of type 'int *'|
17|warning: passing argument 1 of 'diagonal' from incompatible pointer type|
||=== Build finished: 0 error(s), 1 warning(s) (0 minute(s), 0 second(s)) ===|
The program should scan a matrix and return the sum of elements on the main diagonal if the elements on the diagonal have the same value
return -1 if not.

If you want to use a variable size array as an argument, you need to specify the size first, then use that parameter as the array size in the array argument:
int diagonal(int N, int A[N][N] );
int main() {
...
diagonal(N, array);
}
int diagonal(int N, int A[N][N]){
...
}

You are passing your array wrong. You should pass array instead of &array[N][N]. When you do &array[N][N] you just get address of [N][N] array's element and pass it, it is invalid address.
diagonal(array, N);
Also, when you do scanf, you, probably wanted to get [i][j] element, but you do [i][i] two times.
scanf("%d", &array[i][j]);

17|warning: passing argument 1 of 'diagonal' from incompatible pointer type|
diagonal(&array[N][N],N); //---->warning
here &array[N][N] is of the type int* but your function definition:
int diagonal(int**,int );
has first argument type as int** so you are sending wrong type as an argument. that's the reason why you are get this warning.

Related

Its saying segmentation fault when i call in the `inputmatrix` function. I made sure the array of pointers pointed to a valid memory space

Im getting an error when i input the first matrix using the inputmatrix function. Am i passing the arguments incorrectly ?
#include <stdio.h>
void inputmatrix(int *a[10],int m,int n)
{
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",(*(a+i) + j));
}
}
}
void multiplymatrix(int *a[10],int *b[10],int *c[10],int m1,int n2)
{
int i,j,k,sum=0;
for(i=0;i<m1;i++)
{
for(j=0;j<n2;j++)
{
for(k=0;k<n2;k++)
sum += *(*(a+i)+k) * *(*(b+k)+i);
}
*(*(c+i)+j)=sum;
}
}
void outputmatrix(int *c[10],int m1,int n2)
{
int i,j;
for(i=0;i<m1;i++)
{
for(j=0;j<n2;j++)
{
printf("%d ",(*(c+i) + j));
}
}
printf("\n");
}
int main()
{
int a[10][10],b[10][10],c[10][10],m1,m2,n1,n2;
printf("Enter the order of the first matrix : ");
scanf("%d%d",&m1,&n1);
printf("Enter the order of the second matrix : ");
scanf("%d%d",&m2,&n2);
if(n1==n2)
{
printf("Enter the first matrix : ");
inputmatrix(a,m1,n1);
printf("Enter the second matrix : ");
inputmatrix(b,m2,n2);
multiplymatrix(a,b,c,m1,n2);
outputmatrix(c,m1,n2);
}
}
You declared the parameter a to your inputmatrix function as an array of 10 pointers to int – but you have not assigned any pointer values to it. As a result you're using random, unknown values of pointers, pointing anywhere, thus you triggered Undefined Behavior.
You're lucky the pointer you use apparently points to a not accessible area of memory, hence a Segmentation Violation. Otherwise your program could pretend it works correctly, and then spectacularly crash somewhere else...
EDIT
The actual error, however, is not missing the pointer initialization but rather ignoring the compiler's warning about passing an argument of incompatible type and, consequently, forcing a program to interpret as pointers data which were not pointers. I have tested the call line in the online GDB compiler at https://www.onlinegdb.com/ and it said:
main.c:12:6: note: expected ‘int **’ but argument is of type ‘int (*)[10]’
The a variable in main() is an array 10 by 10, which is 100 int values stored in a contiguous block of memory. OTOH inputmatrix expects an array of 10 pointers, each pointing somewhere else to an int (or a block of int values).
The actual type of parameter passed to the function is not 'a 10-elements array of pointers to int', as you declared by int *a[10], but rather 'a pointer to a 10-elements array of integers', which should be declared as int (*a)[10].

Array has incomplete element type. What does this mean? [duplicate]

This question already has answers here:
Why do we need to specify the column size when passing a 2D array as a parameter?
(8 answers)
Closed 2 years ago.
I want to create an array that has that stores the multiplication values of any integer n. After that, I would like to pass that array into another function and print out the array. However, I get the following error:
My code:
This is my .c file:
#include "multiplication.h"
#include <stdio.h>
int main(){
int num;
int arr=multiplication(4);
printArray(arr);
}
int mulitpication(int num){
/* initialize array and build*/
int arr[num][num];
for(int i=0; i<num;i++){
printf("row number: %d ",i);
for(int j=0;j<num;j++){
printf("column number: %d", j);
arr[i][j]= (i+1)*(j+1);
}
}
return arr;
}
void printArray(int arr[][]){
int i;
for(i=0;i<sizeof(arr);i++){
for(int j=0;j<sizeof(arr);j++){
printf("%d ",arr[i][j]);
}
}
This is my header file:
void multiplication(int num);
void print(int arr[][]);
The Error:
multiplication.h:4:19: error: array has incomplete element type 'int []'
void print(int arr[][]);
^
First of all, you don't include the source files into one another, you compile and link them together to form the binary.
That said, the actual problem is in the code you did not show (multiplication.h file), but from the error message we can see
void print(int arr[][]);
is not a valid syntax. You can only leave the outer(-most) index as empty, all other index(es) must have a proper value. Something like
void print(int arr[ ][10]);
^^---------- inner index
^^^------------- outer index
or, for more dimensions
void print(int arr[ ][5][10][15]);
The analogy behind this is, for function declarators,
"A declaration of a parameter as ''array of type'' shall be adjusted to ''qualified pointer to type'',...."
So, to have that adjustment, the type should be known to compiler at compile-time.
In case of a declaration like
void print(int arr[][10]);
the type is int[10], but if a syntax like
void print(int arr[][]);
is allowed , the type cannot be known. Hence the error.
Other issues: You seem to have many other issues, like
The function definition is
int mulitpication(int num){ // returning an int
but actually you do
return arr; //where arr is an array of size int[num][num], defined locally
this is invalid because of two things
an int and an int[num][num] are not the same type.
the scope of a VLA i.e., arr is limited to the function block, you cannot have the array return the address to the caller and expect something meaningful as the returned address will not be valid anymore.
I believe, you're better off using allocated memory (malloc() and family) and keeping track of your index/ count of elements manually.
To fix the printArray function you will need to include the array dimensions. In C, arrays are simply a block of elements, there is no length stored anywhere. The programmer would need to keep track of the length by some method.
For example:
// header
void printArray(int num, int arr[num][num]);
// source file
void printArray(int num, int arr[num][num])
{
for(int i=0;i<num;i++){
for(int j=0;j<num;j++){
printf("%d ",arr[i][j]);
}
For the multiplication function you will need to do something similar, the caller should allocate the array (e.g. int arr[num][num];) and then the function should fill in the values for the array cells.

Array not being passed to Function Method

I'm currently trying to pass an array of (values[3]) which it's first 3 values contain user input. However, I'm getting the error "expected int* but argument is type of int". I've tried to pass to method1, without the iteration of 'i', using the first three positions in the values array, but that's as far as I managed to attempt to fix it, any help would be much appreciated!
int main(void)
{
int i;
int values[3];
printf("Enter three consecutive numbers (With spaces between)");
scanf("%d %d %d",&values[0],&values[1],&values[2]);
for(i=0;i<3;i++)
method1(values[i]);
}
int method1(int values[3])
{
}
You cannot pass an array to a function as an array - it "decays" to a pointer. There are two issues with your code:
There is no forward declaration of method1 visible at the point of invocation, and
You are passing values[i], a scalar value in place of an array.
A forward declaration is necessary because otherwise the compiler would assume that method1 takes an returns an int, which is not true. Add this line before main
int method1(int values[]);
You could also move method1 above main to fix this without providing a forward declaration. Also, 3 inside square brackets is not necessary, because the array is passed like a pointer anyway.
If you want to pass the entire array, pass values. Of course, i becomes unnecessary:
int res = method1(values);
#include <stdio.h>
int main(void)
{
int i;
int values[3];
printf("Enter three consecutive numbers (With spaces between)");
scanf("%d %d %d",&values[0],&values[1],&values[2]);
method1(values, 3);
getchar();
getchar();
return 0;
}
int method1(int* values, int size)
{
int i;
for(i=0; i<size; i++){
printf("%d ", values[i]);
}
return 1;
}
In C, arrays are passed by reference, you can see method1's first argument is int* that refers first element of array, and second argument is size of this array.

Modifying an array from another function in C

Here is my main function:
main(){
int *seats[50] = {0};
char x;
do{
printf("A-Add Reservation\tC-Cancel Reservation\n");
scanf("%c", &x);
} while(x != 'a' && x != 'c');
switch(x){
case 'a':
addRes(&seats);
break;
default:
break;
}
}
I am trying to pass seats[] into the addRes() function so I can modify it within addRes(). Here is the function:
void addRes(int **seats[]){
int s, i, scount=0, j=0, k=0, yourseats[]={0};
printf("How many seats do you require? ");
scanf("%i\n", &s);
for(i=0;i<=sizeof(*seats);i++){
if(*seats[i] == 0)
scount++;
}
if(scount >= s){
for(i=0;i<=s;){
if(*seats[i] == 0){
yourseats[j]=i;
*seats[i]=1;
i++; j++;
}
else i++;
}
printf("Your seat numbers are: \n");
while(k < j){
printf("%i\n", yourseats[k]);
k++;
}
}
else {
printf("Sorry, there are not enough seats available.\n");
}
}
It compiles with the warnings:
Line 15 (*seats[i]=1;) Assignment makes pointer from integer without a cast.
Line 53: (addRes(&seats);) Passing argument 1 of 'addRes' from incompatible pointer type.
Line 3: (void addRes(int ** seats[]){) Expected 'int ***' but argument is of type 'int *(*)[50]'.
On running the program it gets to
How many seats do you require?
and does nothing after entering a value.
Any help would be much appreciated!
Declaration int **seats[] in function parameter is == int ***seats, and this means type of *seats[i] is int* and you are assigning a number to it, that is incompatible type error:
*seats[i] = 1;
^ ^ int
|
int*
incompatible types
Next in addRes(&seats);
seats in array of pointer its type if int*[50] that &seat is pointer of array and type of &seat is int*(*)[50] Where as function argument type is int ***, so again type incompatible error.
Notice you are also getting a reasonable error message from compiler: Expected 'int ***' but argument is of type 'int * (*)[50]'.
Suggestion:
As I can see in your code, you don't allocate memory for seats[i] in your function addRes() and So as I understand you not need to declare seat[] array as array of pointers but you need simple array of int.
Change declaration in main():
int *seats[50] = {0};
should be just:
int seats[50] = {0};
// removed * before seats
Next just pass seats[] array's name to addRes() function where declaration of function should be
addRes(int* seats)
or addRes(int seats[])
it make your work pretty simple in function addRes() you can access its elements as seats[i] ( and it no need to use extra * operator).
Length of array:
One more conceptional problem in your code that you are using sizeof(*seats) to know the length of array. Its wrong! because in addRes() function seats is not more an array but a pointer so it will give you the size of address ( but not array length).
And yes to inform about size of seats[] in addRes() function send an extra parameter called length, so finally declare addRes() as follows (read comments):
void addRes(int seats[], int length){
// access seat as
// seat[i] = 10;
// where i < length
}
Call this function from main() as follows:
addRes(seats, 50);
// no need to use &
One more problem that presently you are not facing but you will encounter soon as you will run you code that scanf() need extra enter in function addRes(). To resolve it change: scanf("%i\n", &s); as scanf("%i", &s); no need of extra \n in format string in scanf().
int *seats[50] = {0};
This is an array of integer pointers, all you need is an actual array so drop the * resulting in int seats[50] = {0};.
Also your function signature for an array is wrong, void addRes(int seats[]) will do fine.
Finally, to pass an array to that new signature, you can pass the array directly without any unary address-of operators (arrays will decay to a pointer when passed as an argument to a function):
addRes(seats);
Also as pointed out, when assigning to an array element, you need to drop the *:
seats[i]=1;
Is more than enough. Same goes for the if statements and the like where you do a comparison against an array element.
Regarding your addRes function:
for(i=0;i<=sizeof(*seats);i++)
You will only get the size of the pointer this way, which on a 32bit machine is 4. This trick will not work on an array passed to a function. You will need to pass the array separately.
You can fix it in the following way:
Change the function signature of address to this:
void addRes(int seats[], int size)
Pass the size in one of the following ways in main:
Directly: addRes(seats, 50);
Indirectly: addRes(seats, sizeof(seats)/sizeof(int));
Note that the above only works on local to the scope of this function arrays, it won't work on an array you've obtained as an argument to a function (or dynamically allocated arrays).
Another issue is to do with scanf, you should drop the \n. Use scanf("%i", &s);

Passing arrays into functions

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, )

Resources