2

Edit: Ok returning the matrix bit is now ok but still can't get entering rows of values down. It still only gives one value.

Quite new to C so apologies for the long read and terrible coding.

This is for a homework hence why it has to be so specific but the homework reads as:

Prompt for the size of the multiplier, which may be no bigger than ten in either dimension. Read the elements by row, one row per line of input. If the actual input matrix has different number of row or column as specified in the former step, print an error message and end the program.

So it needs to read in

1 0 0

1 0 0

1 0 0

and see if thats the size as declared earlier. It needs to do this for two separate matrices hence why I'm using a function, and then it will multiply the two matrices. What I currently have is

void matrix(int x, int y)
{
    int i, j;
    char c;

    i = 0;
    j = 0;

    while (j < x)
    {
        while (c != '\n')
        {
            scanf("%d%c", &input[i][j], &c);
        }
        ++j;
        c = 0;
    }
}

Where x and y are the size of the matrix and input[10][10] is a global array which I'm using to transfer the values out of the function to main.

Is there a way to do this with pointers? I know there are ways of doing it but my problem is that cause its for a homework we can only use what we "know" so I can only use scanf to read in variables.

Another problem I'm having is reading in the row elements, it only accepts the last element I input (which it takes as the first element) and leaves the rest blank.

2 Answers2

1

Best way to do this is to pass the array as a parameter to the function, rather than try to return it.

C's treatment of arrays is special. Except when it is the operand of the sizeof or unary & operators, or is a string literal used to initialize a character array in a declaration, an expression of type "N-element array of T" is converted ("decays") to an expression of type "pointer to T" and the value of the expression is the location of the first element of the array1.

For example, let's assume the following code:

int main( void )
{
  int arr[10]; // start with a 1D array for now

  foo( arr );
  return 0;
}

In the function call foo( arr ), the expression arr has type "10-element array of int" (int [10]). Since it's not the operand of the sizeof or unary & operators, it "decays" to an expression of type "pointer to int" (int *), and the value of the expression is the address of arr[0].

Thus, the definition of foo would look like this:

void foo( int *a ) { ... }

What foo receives is a pointer value, not an array. C allows you to write that prototype as

void foo( int a[] ) { ... }

or even

void foo( int a[10] ) { ... }

But, in the context of a function parameter declaration, T a[] and T a[N] are interpreted as T *a; they declare a as a pointer to T, not an array of T.

The subscript operator [] is defined in terms of pointer arithmetic - a[i] == *(a + i). This means that the [] operator can be applied to pointer expressions as well as array expressions; thus, a[i] will work2 whether a is an array of T or a pointer to T.

So, applying that to your code:

int main( void )
{
  int a, b;
  int input[10][10]; // make input local to main
  ...
  matrix( a, b, input );
  ...
}

void matrix( int x, int y, int (*input)[10] ) // or input[][10], or input[10][10]
{
  ...
  scanf( "%d%c", &input[i][j], &c );
  ...
}

Having said that, you will want to send an extra parameter specifying the number of rows in the array:

matrix( a, b, rows, input );

void matrix( int x, int y, size_t rows, int (*input)[10] )
{
  ...
}

A pointer to an N-element array is a different type than a pointer to a M-element array (where N != M), so you can't pass anything but an N x 10-element array to matrix. However, there's no way for you to know the value of N unless you pass it as a separate parameter.

A note on syntax

A pointer to an array has the form T (*p)[N]. The parens are required since the postfix [] operator has a higher precedence than the unary * operator. *p[N] is parsed as *(p[N]) - IOW, index into p and dereference the result. (*p)[N] will first dereference p, then index into the result.

An expression of type T [N][M] will "decay" to type T (*)[M].


  1. If you're curious why this is the case, check out this paper by Ritchie describing the development of C.
  2. Assuming i doesn't fall outside the bounds of the array or sequence being pointed to.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • Any particular reason why you would do `void matrix( int x, int y, int (*input)[10] )` instead of `void matrix( int x, int y, int input[x][y])`? Or if you will, the pedantic version of the same, `void matrix( size_t x, size_t y, int input[static x][y])`. – Lundin Feb 22 '17 at 15:31
  • @Lundin: Arrays and pointers are different animals, and I would rather accurately represent the type of the argument as a pointer than to pretend it's an array. I honestly think it was a mistake to allow array-like syntax for pointers in parameter declarations. – John Bode Feb 22 '17 at 15:42
  • Once upon a time before C99 it was perhaps a mistake. But with VLAs, the array-like syntax can give increased type safety. And even prior C99 you could also get increased type safety if using some form of static analysis on the code. `void f (int* x)` could accept anything, but `void f (int x[5])` clearly expects an array of size 5. The C compiler will treat them the same, but more pedantic tools such as static analysers may perform array bounds-checking on the latter form. – Lundin Feb 22 '17 at 15:48
  • Anyway, I was mostly curious if you had some other type safety reason for choosing an array pointer, such as in [this case](http://stackoverflow.com/questions/36199473/const-correctness-for-array-pointers). – Lundin Feb 22 '17 at 15:50
0

This isn't rocket science.

void matrix(int x, int y, int input[x][y])
{
   ... // fill up input[i][j] here
}

This is possible since arrays, whenever passed to functions, decay into a pointer to the first element. So with this function you will change the contents of the original array.

Lundin
  • 195,001
  • 40
  • 254
  • 396