0

In C I learnt that the name of array is a pointer to the first index, but why I can't write the following:

int mat[5][4];
*mat=1;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335

3 Answers3

4

In C I learnt that the name of array is a pointer to the first index

This is not exactly so.

According to the C Standard (6.3.2.1 Lvalues, arrays, and function designators)

3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

This declaration

int mat[5][4];

declares a two-dimensional array. So the array designator used in expressions (with rare exceptions listed in the quote) is implicitly converted to pointer to its first element that is to pointer of the type int ( * )[4].

Dereferencing the pointer like in this statement

*mat=1;

you will get an array lvalue of the type int[4]. And as a result you are trying to assign a one-dimensional array with the scalar integer value 1. But arrays do not have the assignment operator. They are non-modifiable lvalues.

Instead you could write for example

**mat = 1;

In this case the expression **mat yields a scalar lvalue of the type int (the first scalar element of the type int of the first "row"/element of the array m).

Here is a demonstrative program.

#include <stdio.h>

int main(void) 
{
    int mat[5][4];
    **mat = 1;
    
    printf( "**mat is equal to %d and equivalent to mat[0][0] that is also equal to %d\n",
            **mat, mat[0][0] );
}           

Its output is

**mat is equal to 1 and equivalent to mat[0][0] that is also equal to 1

In fact all these expressions used in the printf calls

printf( "%d\n", **mat );            
printf( "%d\n", ( *mat )[0] );
printf( "%d\n", *mat[0] );          
printf( "%d\n", mat[0][0] );

yield the same element of the array.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
3

2D arrays are essentially 1D arrays of 1D arrays. *mat is equivalent to mat[0] and gives you the first element of the array, which is itself a 1D array (int[4]).

You can't assign a number to an array.


name of array is a pointer to the first index

I often see this explanation, but the difference between "array" and "name of array" is moot.

A better explanation is that an array can be automatically converted to the pointer to its first element.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • To make things clear, are matrices in c an array of arrays or one block of memory (Like one line)? –  Jul 15 '20 at 11:49
  • @BigSur There's no contradiction here. They're arrays of arrays, and the sub-arrays are contiguous in memory. – HolyBlackCat Jul 15 '20 at 11:50
  • @HolyBlackCat I understood how my answer could be misunderstood. I deleted it. Take my upvote. – Maxime B. Jul 15 '20 at 12:03
1

You can use the array name as a pointer to the first element of your array (even though there are more elegant solutions).

In your case the first element of your array is another array, so *mat has the type int[4] (int array with 4 elements) and you can't assign 1 (integer) to it.

If you want to set the first integer of your two dimensional array, you could use

**mat = 1;

But I would highly recommend using explicit indexes like

mat[0][0] = 1;
izlin
  • 2,129
  • 24
  • 30