I am struck while reading 2D array in C++ that we can declare in
Such a way:
month=4;. // Initialize value of mont variable
void display(float [ ] [month] ); //declare
I want to know why the function doesn't need the size of fist dimension ?
I ask this question on many forums but only get the way how to declare array like this . But never find the answer of why?
Because arrays when passed to functions are treated like pointers (to the arrays first element).
So an argument declaration like
float month[][X]
is equal to
float (*month)[X]
So month is a pointer to an array of X elements of type float.
This is because a "2d" array is really an array of arrays. C++ doesn't really have multi-dimensional arrays.
Also note that an array of arrays is not the same as a pointer to a pointer. The decay to a pointer only happens for the outer array ("first dimension").
Related
With C++11, we can use
auto carrots{new double[rows][4]}
if we want to allocate dynamic two dimension array. Here I see another way to explicitly declare the pointer like
double (*carrots)[4]{new double[rows][4]}
According to my understanding, double (*carrots)[4] is a pointer to an array of double[4]. I think there should be a mismatch between this and new double[rows][4]. Because I think double[rows][4] represents an array of size rows instead of array of size 4.
As we know the lay out of c++ two dimension array should like this
int test[3][2] {{0,1},{2,3},{4,5}}
is exactly the same as
int test[6]{0,1,2,3,4,5}
When a multidimensional array is passed to a function, why does C++ require all but the first dimension to be specified in parameter li
A better way to ask this is to ask why C++ doesn't require the first dimension to be specified.
The reason is that for all arrays, you can't pass arrays by value to a function. If you try to declare a function taking an array the compiler will adjust the declaration to the corresponding pointer type.
This means that it doesn't matter what dimension you specify as the dimension doesn't form part of the function signature.
For example, these all declare exactly the same function.
void f(int *p);
void f(int p[]);
void f(int p[10]);
void f(int p[100]);
When navigating the array pointed to by p in the function, the only information that the copmiler needs is the size of the array elements, i.e. sizeof(int) in this case.
For more complex arrays exactly the same holds. These are all the same:
void g(Type p[][10][20]);
void g(Type (*p)[10][20]);
void g(Type p[10][10][20]);
void g(Type p[99][10][20]);
But these are all different from:
void g(Type p[][5][20]);
because adjusting the dimension of anything other than the outer array dimension affects the size of (at least) the outer array's elements meaning that the pointer arithmetic for navigating the array would have to change.
For example int a[n][m] is an array whose type is an int array of length m. In other words, the length of array is part of its type. And as for all function parameters, compiler need to know its type.
There is no such thing as multidimensional array in c++. It is just a syntax which looks like it. In int a[4] and int b[5] a and b are different types.
If you refer to static allocation, this is simple.
Because the blocks of memory are contiguous which means that the memory cells are one after each other and the compiler knows where the next cell is in memory.
For unidimensional array in memory looks like this:
http://cplusplus.com/doc/tutorial/arrays/arrays3.gif
For bidimensional array in memory looks like this:
http://i.msdn.microsoft.com/dynimg/IC506192.png
In short: The compiler doesn't need the dimension, because a array decays to a pointer. But any additional dimension is needed by the compiler, to calculate the correct location in memory.
At first you need to know that an array in C/C++ is a linear continuous object in memory. Which is very efficient.
Because an array in C/C++ is a linear continuous object in memory, an array will decay to a pointer. Copying the complete array will be a waste of time and memory and is not requiered. A pointer is anything needed to go through the array. To go through the array you can take the increment-operator or any calculation which evaluates to a valid address in the array. You can set a delimiter in the array itself i.e. '\0' in a String, or pass the length to the function seperatley to tell your code where the end of the array is.
With multi-dimensional arrays the thing is a little bit more complicated. A multi-dimesional array is still only a linear continuous object in the memory! But the compiler needs the information about the additional dimensions to calculate to correct position in memory, imagine the following:
char array[10][10]; // 0 - 99
correct:
// formal argument tells your compiler, that each column is 10 elements long
funca(int array[10][10]) {
// access to element 25 (2 * 10 + 4, the 10 is known through your formal argument, remember that an array is null based)
array[2][3] = 'x';
}
wrong:
// formal argument tells your compiler, that ech colum is 5 elements long
funcb(int array[10][5]) {
// access to element 15 (2 * 5 * + 4, the 5 is known through your formal argument, remember that an array is null based)
array[2][3] = 'x';
}
A note (or warning):
Arrays in Java, especiallay (irregular) multi-dimensional arrays are completely different.
This question already has answers here:
conversion of 2D array to pointer-to-pointer
(6 answers)
Closed 5 years ago.
how to assign two dimensional array to **pointer ?
this is the idea of what i want to do
int arrray [2][3];
int **pointer = array;
so pointer[0][1]= 1;
so any help ?
thanks in advance
Declare the pointer like this:
int (*pointer)[3] = array;
But this is infinitely nasty in C++. Perhaps you could find a better solution (one involving vectors and whatnot) if you explained what your general purpose is.
The simple answer is that you cannot. A bidimensional array is a contiguous block of memory that holds each line, while a pointer to pointer can refer to a memory location where a pointer to a different memory location containing the integers is.
You can on the other hand create a separate data structure that holds the pointers to the elements in the way you want (i.e. create an array of pointers, initialize those pointers to the beginning of each row, and use a pointer to that array of pointers as pointer), but it is not useful at all, but rather will complicate everything unneedingly.
The question probably comes from the common misconceptions that arrays and pointers are the same, which they are not. An array can decay to a pointer to the first element of the array (and will do so quite often), but the type of that pointer is the type of the first element. In a bidimensional array, the type of the first element is the inner array, not the basic element type.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is array name a pointer in C?
char arr[1024];
arr++ //move arr to arr+1, error!
I have heard the the name of a char array is a char pointer, is it?
The name of an array decays to an pointer to its first element sometimes.
An expression with array type will convert to a pointer anytime an array type is not legal, but a pointer type is.
You cannot do:
arr++;
Because array is an non modifiable l-value.
An array is a block of memory to which you gave a name.
What does it mean to "increment" it by one? That doesn't make any sense.
A pointer is a memory address. "Incrementing" it by one means to make it point to the element after it.
Hope that makes sense.
Arrays and pointers are not always exchangeable. A more interesting example to illustrate the difference between arrays and pointers is a 2D array:
Consider int **a and int b[3][3].
In the first approach to a 2D array we have a 1D array of pointers to 1D arrays in memory (of course you have to allocate the memory dynamically to use this).
In the second approach of actually using a 2D C array, we have the elements laid out sequentially in memory, and there's no separate location where an array of pointers are stored.
If you try to dereference b, you get a pointer to its first element (i.e. b gets converted to an int (*)[3] type).
nothing, apart from looks..
Well and as you defined the array there you declared already 1024 bytes for the array. Also you obviously can't change the array "base".
An array name is for most (but not all) purposes identical to a constant pointer (not to be confused with a pointer to a constant). Because it's a constant, you cannot modify it with the increment operator ++. There's a good answer explaining this in more detail in an older similar question.
came across the code shown below in a small C++ example:
int (*arr1)[ARRAY_SIZE];
int (*arr2)[ARRAY_SIZE];
int (*arr3)[ARRAY_SIZE];
then in the constructor of the class:
ParallelMultiply::ParallelMultiply(int mat1[ARRAY_SIZE][ARRAY_SIZE],
int mat2[ARRAY_SIZE][ARRAY_SIZE],
int result_mat[ARRAY_SIZE][ARRAY_SIZE]):arr1(mat1),
arr2(mat2),
arr3(result_mat)
{
}
here, ParallelMultiply is the class, mat1, mat2, result_mat are 2-D arrays, and ARRAY_SIZE is the defined array length. But How can arr1, arr2 and arr3 can be initialized with two dimensional arrays?? Please explain.
Thank you!!
You may be familiar with the way an array can decay to a pointer and then that pointer can be used like an array (as long as its actual extent is known).
When this sort of thing is done to a multidimensional array, you get a pointer to array with one less array bound. Then that pointer can be used like the multidimensional array.
So arr1[i][j] and mat1[i][j] are the same int and have the same address.
Note that since the class is copying only pointers to the 2D arrays, the user needs to make sure the lifetime of those array arguments is long enough. And any modifications made through the class will happen to the original arrays.
arr1, arr2 and arr3 are pointers. Each pointer pointing to an array of size ARRAY_SIZE.