I will try and address the issues at hand while giving you a recursive solution for your problem.
typing: C is a static typed language which requires you to give all variables AND function declarations a type. This lead your first compile errors.
matrix(int B[20][20],int M,int N);
//should have been (though be careful there is another issue addressed later)
void matrix(int B[20][20],int M,int N);
as well as
main() {
//shoud have been
int main() {
counting: as a programmer you should get used to start counting at 0 as most languages do so. An array of size 4 has the elements array[0] array[1] array[2] array[3]
. Trying to access an address above size-1
will lead to undefined behavior.
Therefore every loop you had would have given you unintended behavior
for(i=1; i <= M; i++)
//should have been (as an example)
for(i=0; i < M; i++)
array as a parameter I: if you want to pass an array as a parameter you have give just the variable name as any [X][Y]
would be an access to the array and result in the element stored at that location being passed instead of the intended array.
matrix(B[20][20],--M,--N);
//should have been
matrix(B,--M,--N);
array as a parameter II: if you want a function to take an array as a parameter you have to declare the function head in a specific way. Which is quite counter intuitive. You can read more on that topic here. But in the end
void matrix(int B[20][20],int M,int N);
//should have been
void matrix(int M,int N,int B[][N]);
scope: Local variables just have a limited scope therefore
void matrix(int B[20][20], int M,int N) {
while(M!=0||N!=0) {
for (i=1,j=1; j<=N; j++)
{ /*....*/
cannot work as either i
and j
are unknown in this function. This would be correct:
void matrix(int B[20][20], int M,int N) {
int i,j;
while(M!=0||N!=0) {
for (i=1,j=1; j<=N; j++)
{ /*....*/
while-loop: The while loop will end as soon as the head of the loop evaluates to false
while(M!=0||N!=0)
{
/*stuff*/
}
would have therefore resulted in an endless loop, as neither M
nor N
are changed in the body. Or it would have just never been executed.
recursion: You did write a (theoretically) recursive function, though without any aboard rule. A recursion is nothing but a loop and therefore it carries on until an aboard/break is issued. Basically speaking you have to have something like
if(/*aboard_condition*/) return;
to ensure that your recursion will end at some point .
semicolons: addressing the part of your question
solution.c:23:1: error: expected identifier or '(' before '{' token
you just had a semicolon to much:
matrix(int B[20][20],int M,int N);
{ ....
//should have been (though do not forget about the other issues)
matrix(int B[20][20],int M,int N)
{
as a semicolon seperated the function header from the function block
As your print function was quite broken I used a print_sprial function borrowed from here and turned it into a recursive one by taking the variables m
and n
out of the body and into the header. I further moved the print function in front of the main function to avoid having to give a header declaration.
#include <stdio.h>
void print_matrix(int matrix_y, int matrix_x, int a[matrix_y][matrix_x],int k,int l)
{
int i;
int m = matrix_y;
int n = matrix_x;
/* k - starting row index
m - ending row index
l - starting column index
n - ending column index
i - iterator
*/
while (k < m && l < n)
{
/* Print the first row from the remaining rows */
for (i = l; i < n; ++i)
{
printf("%d ", a[k][i]);
}
k++;
/* Print the last column from the remaining columns */
for (i = k; i < m; ++i)
{
printf("%d ", a[i][n-1]);
}
n--;
/* Print the last row from the remaining rows */
if ( k < m)
{
for (i = n-1; i >= l; --i)
{
printf("%d ", a[m-1][i]);
}
m--;
}
/* Print the first column from the remaining columns */
if (l < n)
{
for (i = m-1; i >= k; --i)
{
printf("%d ", a[i][l]);
}
l++;
}
}
}
int main()
{
int M,N,j,i=1;
scanf("%d %d",&M,&N);
int B[M][N];
for(i=0; i != M; i++)
{
for(j=0; j != N; j++)
{
printf("%d/%d:",i,j);
scanf("%d",&B[i][j]);
}
}
print_matrix(M,N,B,0,0);
return 0;
}