What is the following code doing?
int g[] = {9,8};
int (*j) = g;
From my understanding its creating a pointer to an array of 2 ints.
But then why does this work:
int x = j[0];
and this not work:
int x = (*j)[0];
The parenthesis are superfluous in your example. The pointer doesn't care whether there's an array involved - it only knows that its pointing to an int
int g[] = {9,8};
int (*j) = g;
could also be rewritten as
int g[] = {9,8};
int *j = g;
which could also be rewritten as
int g[] = {9,8};
int *j = &g[0];
a pointer-to-an-array would look like
int g[] = {9,8};
int (*j)[2] = &g;
//Dereference 'j' and access array element zero
int n = (*j)[0];
There's a good read on pointer declarations (and how to grok them) at this link here: http://www.codeproject.com/Articles/7042/How-to-interpret-complex-C-C-declarations
int g[] = {9,8};
This declares an object of type int[2], and initializes its elements to {9,8}
int (*j) = g;
This declares an object of type int *, and initializes it with a pointer to the first element of g.
The fact that the second declaration initializes j with something other than g is pretty strange. C and C++ just have these weird rules about arrays, and this is one of them. Here the expression g is implicitly converted from an lvalue referring to the object g into an rvalue of type int* that points at the first element of g.
This conversion happens in several places. In fact it occurs when you do g[0]. The array index operator doesn't actually work on arrays, only on pointers. So the statement int x = j[0]; works because g[0] happens to do that same implicit conversion that was done when j was initialized.
A pointer to an array is declared like this
int (*k)[2];
and you're exactly right about how this would be used
int x = (*k)[0];
(note how "declaration follows use", i.e. the syntax for declaring a variable of a type mimics the syntax for using a variable of that type.)
However one doesn't typically use a pointer to an array. The whole purpose of the special rules around arrays is so that you can use a pointer to an array element as though it were an array. So idiomatic C generally doesn't care that arrays and pointers aren't the same thing, and the rules prevent you from doing much of anything useful directly with arrays. (for example you can't copy an array like: int g[2] = {1,2}; int h[2]; h = g;)
Examples:
void foo(int c[10]); // looks like we're taking an array by value.
// Wrong, the parameter type is 'adjusted' to be int*
int bar[3] = {1,2};
foo(bar); // compile error due to wrong types (int[3] vs. int[10])?
// No, compiles fine but you'll probably get undefined behavior at runtime
// if you want type checking, you can pass arrays by reference (or just use std::array):
void foo2(int (&c)[10]); // paramater type isn't 'adjusted'
foo2(bar); // compiler error, cannot convert int[3] to int (&)[10]
int baz()[10]; // returning an array by value?
// No, return types are prohibited from being an array.
int g[2] = {1,2};
int h[2] = g; // initializing the array? No, initializing an array requires {} syntax
h = g; // copying an array? No, assigning to arrays is prohibited
Because arrays are so inconsistent with the other types in C and C++ you should just avoid them. C++ has std::array that is much more consistent and you should use it when you need statically sized arrays. If you need dynamically sized arrays your first option is std::vector.
j[0]; dereferences a pointer to int, so its type is int.
(*j)[0] has no type. *j dereferences a pointer to an int, so it returns an int, and (*j)[0] attempts to dereference an int. It's like attempting int x = 8; x[0];.
Related
This question already has answers here:
Array changed in a void function, is still changed outside! why? (scope)
(4 answers)
Passing an array as a parameter in C
(3 answers)
Passing Arrays to Function in C++
(5 answers)
Passing an array as an argument to a function in C
(11 answers)
Closed 11 months ago.
I don't get it why you can alter the values inside the array, without using a reference or a pointer (&, *), I'm a freshmen student, and I don't know the reason behind, I hope someone can provide a logical answer, please refer to the code below, Thank You in Advance.
#include <iostream>
using namespace std;
void a(int x[]){
for(int i = 0; i < 5; i++){
x[i] += 2;
}
}
int main(){
int x[5] = {1,2,3,4,5};
a(x);
for(auto b : x){
cout << b << " ";
}
return 0;
}
A function parameter is never an array in C++. When you declare a function parameter as an array, it is automatically adjusted to be a pointer to element of such array. These declarations are effectively identical:
void a(int x[]); // looks like an array of int of unknown bound
void a(int* x); // declaration above is adjusted to this
void a(int x[1234]); // the size is ignored completely
An array implicitly converts to a pointer to the first element of the array (such conversion is called decay). Hence, you can call the function that doesn't accept an array parameter by passing an array argument:
int* ptr1 = x; // implicit conversion
int* ptr2 = &x[0]; // same conversion explicitly
a(x); // same conversion happens here
These two rules (function parameter adjustment and array to pointer decay) make it so that what syntactically looks like passing arrays by value, is actually done using indirection. Within the function, you modify the elements by indirecting through the pointer parameter that points to the array that exists outside of the function.
Important note: The adjustment of array to pointer in function parameter does not apply in other contexts. Arrays and pointers are distinct types with different properties.
Another note: The adjustment does not apply to parts of compound types. For example, a function parameter of type "pointer to array" will not be adjusted to be "pointer to pointer" and "reference to array" will not be adjusted to be "reference to pointer".
The parameter having the array type in this function declaration
void a(int x[]){
is adjusted by the compiler to pointer type to array elements type. That is the above declaration is equivalent to
void a(int *x){
In this call of the function
a(x);
the array designator is implicitly converted to pointer to its first element. That is the call is equivalent to
a( &x[0]);
So within the function you have a pointer to the first element of the array declared in main.
Using the pointer arithmetic you can access elements of the array. That is the elements of the array are passed to the function by reference in the C meaning indirectly through a pointer to them.
Within the function the variable x has the type int *. And this expression statement
x[i] += 2;
is equivalent to
*( x + i ) += 2;
Beacuse
void a(int x[]){
is the same as
void a(int *x){
and so you are using a pointer
Why?
Because an array like
int x[10];
'decays' to a pointer when passed to a function (and in other places). This can be very confusing but at the same time is very flexible
It mens that I can have a function like strlen that can accpet a 'real' array, or a pointer. These 'strings'
char *s1 = malloc(10);
strcpy(s1, "hello");
char s2[] = "hello";
char *s3 = "hello";
store their data in different ways but all can be handled by
size_t strlen(const char *s);
note that this is exactly the same as
size_t strlen(const char s[]);
they are 2 different ways of writing the same thing. Personal preference is for the second type if its really is an 'array' vs a pointer to maybe an array.
One issue with this 'decay' is that inside strlen (or any pointer/array accepting function) it is impossible to 'know' the length just from the parameter. The compiler knows that the size of s2 is 6 but this information is not carried forward to the function.
Regularly SO sees this
void my_func(int *arr){
int len = sizeof(arr)/sizeof(arr[0]);
....
}
int a[10];
my_func(a);
This will give len = 1 or 2 (depending on 32 or 64 bit machine), never 10
The flexibility costs a litle power
I have encountered this while writing a program with matrices, I used int** m to declare my matrix - because I needed dynamic allocation and in the function i used int a[][]. I don't remember having any problem with that. But when I used a simple m[6][6] matrix and f(int**m, int** m2, rest params) I had trouble.
It compiled and when I was running the program (code blocks with GCC) it just crashed. I tried debugging by adding printf()s and it was crashing at an if() block where it made no sense to crash. Modified the first function parameter from int a[][] to int* a[6] and it moved on, modified the second param later and my program worked on first try. By a more careful debug what I was saving in int m[i][j] and checking in the if was junk value, not what I was putting in, I was just putting 1 or 0 to mark something.
After all this years, unless I get compiler error by GCC when I do stuff like this, I just write the first way that comes to mind.
What is the logic behind using int** and int [][] to declare variable/get function parameters, in all 4 combinations? Most predefined functions I worked with use int** in the function header.
I know int [][] is not equivalent to int**, it is int* [] correctly, but what are the things that i'm missing? int[][] is an multi dimensional array means array of arrays, all 3 ways of writing it seem the same. And for int[][] it almost always asks to only let the first parameter void, like for int array[][][][] I need to put int array a[][n1][n2][n3] in the function parameter, right? It needs to know the dimension for multi-dimensional arrays except for the first one, because int* and int[] can be used without problems when declaring function arguments?
What are the exact differences betwenn int **a and int a[][] as function parameters in C and C++?
int *a. This is a pointer to an int.
int **a. This is a pointer to pointer to an int.
int a[] This would be an array of unspecified number of ints in all other contexts, but as a function parameter declarator, it is adjusted to be a pointer to int i.e. in that case it is same as if you had written int *a.
int a[][] This would be an array of unspecified number of arrays of unspecified number of ints, but such type is ill-formed because the array element cannot be an array of unspecified size.
int *a[] This would be an array of unspecified number of pointers to int in all other contexts, but as a function parameter declarator, it is adjusted to be a pointer to pointer to int i.e. in that case it is same as if you had written int **a.
int (*a)[N] This is a pointer to an array of N ints.
int a[][N] This would be an array of unspecified number of arrays of N ints in all other contexts, but as a function parameter declarator, it is adjusted to be a pointer to an array of N int i.e. in that case it is same as if you had written int (*a)[N].
Some examples:
void fun_1D(int*); // argument is pointer to int
void fun_1D(int[]); // same as above
void fun_1D(int[10]); // same as above; note that 10 is ignored
int arr_1D[20]; // array of int
fun_1D(arr_1D); // implicit conversion
fun_1D(&arr_1D[0]); // same as above
void fun_2D(int (*)[20]); // note that 20 is not ignored
void fun_2D(int[][20]); // same as above
void fun_2D(int[10][20]); // same as above; note that 10 is ignored
int arr_2D[20][20]; // array of array of int
fun_2D(arr_2D); // implicit conversion
fun_2D(&arr_2D[0]); // same as above
fun_1D(arr_2D[i]); // implicit conversion
fun_1D(&arr_2D[i][0]); // same as above
void fun_ptrs(int**); // argument is pointer to pointer to int
void fun_ptrs(int*[]); // same as above
void fun_ptrs(int*[10]); // same as above; note that 10 is ignored
int *arr_ptr[20]; // array of pointers
fun_ptrs(arr_ptr); // implicit conversion
fun_ptrs(&arr_ptr[0]); // same as above
fun_1D(arr_ptr[i]); // no conversion needed
// broken examples
fun_2D(arr_ptr); // int*[20] is not int(*)[20]
fun_ptrs(arr_2D); // int[20][20] is not int**
Notice how a function parameter declared as an array is adjusted as the same pointer type to which an array will decay to upon lvalue to rvalue conversion.
Some simple rules of thumb to remember:
An array is not a pointer.
A pointer is not an array.
A function argument written as an array is actually not an array. It is actually adjusted to be a pointer to the element of such array. After this adjustement, a function argument is never an array. This does not apply to any other contexts, except for function arguments.
Not every type can be element of an array. Arrays of unspecified length are such types.
There are no objects of "array unspecified length" types. They can only be used in extern variable declarations which refer to an array defined elsewhere, or in a definition where the actual size is deduced from the initialiser of the array, or in a function parameter declaration where the array is adjusted to be a pointer to the element.
If I declare int a[6][6] in main and call a function that expects int** a, will it workd?
No, because int[6][6] is not an int** and neither does it decay to one. int[6][6] decays to int(*)[6] as I explained above. int(*)[6] and int** are not convertible to one another. One is pointer to an array, the other is pointer to a pointer.
And the other way around
No, because int[6][6] argument is adjusted to int(*)[6]. See previous paragraph for reason why these are incompatible.
seems int a[][] is not accepted
Correct. As I explained in the fourth paragraph from the top (not counting the quote).
If I have functions f1(int *a) and f2(int a[]) and f2(int a[6]) what would sizeof (a) return in those cases ?
As I explained above, all of those declare a parameter of type int*. sizeof a would be same as sizeof(int*) because that is the type.
int **a
This is pointer to pointer to int.
int a[][]
This is array of array of int but this is not valid because the dimension of the second array must be known at declaration time, i.e. the second array must be complete, as it cannot be completed afterwards, like that
int a[][DIM]
C++ inherited C's behavior of arrays decaying into a pointer.
This behavior is really helpful, until one hits a sharp edge and realizes something odd is going on, and then one tries to figure out what it does and test out the behavior and realize it is a bit crazy.
But keep calm, once you realize what it means for an array to decay into a pointer, everything makes sense again.
Here is an example to illustrate the differences.
static void func1(int** p) {
(void)p;
}
static void func2(int (&a)[2][2]) {
(void)a;
}
int main() {
// x is a 2-dimensional array of int objects.
int x[2][2] = {{10, 20}, {30, 40}};
// x[0][0] is 10, and is at 0x1000 (say, for example)
// x[0][1] is 20, and is at 0x1004
// x[1][0] is 30, and is at 0x1008
// x[1][1] is 40, and is at 0x100C
// y is a 1-dimensional array of pointers.
int* y[2] = { &x[0][0], &x[1][0] };
// y[0] is 0x1000, and is at 0x1010 (say, for example)
// y[1] is 0x1008, and is at 0x1018
// x cannot decay into an int**, because it is not an array of pointers.
// y can decay into an int**, because it is an array of pointers.
func1(y);
// x can be used for an int[2][2] reference parameter.
// y cannot be used for an int[2][2] reference parameter.
func2(x);
}
When you declare arrays in C++ you are allocating a contigious block of memory that holds the members of the array.
int data[6]; // Block of 6 integers.
This is true even for dimensional arrays.
int threeD[2][3][4]; // Allocates a Block of 24 integers.
// The compiler keeps track of the number of
// of dimensions and does the maths for you
// to calculate the correct offset.
Now when an array is passed to a function the array will decay into a pointer to the first element.
Now if you are dynamically allocating a multi-dimensional array. You tend to do this as arrays of arrays. These arrays are NOT in contiguous memory. But you need to do it this way to allow you to use the square bracket operator [] as you would do normally.
int*** dynamicThreeD = new int**[2];
for(int l1 = 0 ; l1 < 2 ; ++l1) {
dynamicThreeD[l1] = new int*[3];
for(int l2 = 0 ; l2 < 3 ; ++l2) {
dynamicThreeD[l1][l2] = new int[4];
}
}
int threedD[2][3][4];
Though these two types look the same in the way they are accessed:
dynamicThreeD[1][2][3] = 8;
threeD[1][2][3] = 8;
These are not the same. The dynamicThreeD at ache [] is accessing the array and retrieving the next pointer for referencing next. While the threeD object results in an index calculation (3) + (4 * 2) + (4*3 * 1) which is then used as an offset from the first element.
dynamicThreeD[1][2][3] = 8;
// Equivalent to
int** tmp1 = dynamicThreeD[1];
int* tmp2 = tmp1[2];
tmp2[3] = 8;
threeD[1][2][3] = 8;
// Equivalent to
int index = (3) + (4 * 2) + (4*3 * 1)
// OK The compiler does not take the address like this
// But I needed to do some type gymnastics to convert the type
// at the language level.
//
// But you get the same effect like this.
// As the value is just offset by an index from the beginning of
// the array.
(&threed[0][0][0])[index] = 8;
The side affect of this is that multi dimensional arrays can be much more efficient as 1) we only need to do one memory accesses (not 3) get/set the data. 2) Because of data locality and caching you get a much better hit ratio.
On the other hand multi-dimensional arrays in parallel systems can be a pain if you have multiple writers as cache consistency becomes an issue if all the members are all in the same cache line. Here the array of array has an advantage as each line can be in a distinct part of memory and worked on independently (Note: I am oversimplify a very complex issue).
Among the other well answers, I want to focus your last concern.
"And for int[][] it almost always asks to only let the first parameter void, like for int array[][][][] I need to put int array a[][n1][n2][n3] in the function parameter, right?"
Yes, only the first dimension can be left unspecified. But if you want to have the other dimensions to be variable/determined at runtime, at least in C you can use:
int foo (int n1, int n2, int a[][n1][n2]) { ...
With an additional level of indirection, you can pass a fixed size of dimensions, since sizeof(*x), sizeof(x[0][0]) etc. knows the dimensions of the indirect type.
But generally in C, the array [] is just a pointer * and the size, especially when dynamic, needs to be passed or known, as a second parameter, global, MACRO, or in a struct, until classes come along. Of course, there is the null term thing used so much with char* and char**argv. For pointers, you pay 8 bytes overhead.
Why does int* ptr_arr_int = {1,2}; gives a compiler error, but whereas char* ptr_arr_char = "amruth"; compiles fine?
int* ptr_arr_int = {1,2}; // ->ERROR
char* ptr_arr_char = "amruth"; // ->OK
"amruth" is a const char[7] type in C++, and a char[7] type in C (although the behaviour on attempting to modify the string is undefined).
This can decay to a const char* or char* type respectively in some circumstances, such as yours.
Although an int[2] will similarly decay to an int* in some circumstances, {1, 2} is neither an int[2] nor a const int[2] type; rather it is a brace-initialiser.
As said, the string is an const char[7] array and while that can decay to a char*, {1, 2} cannot decay to int* (it's an brace initializer list, similarly: std::initializer_list). But note there is also the array [] declaration which allows you to automatically declare arrays. Combine that with the list-initialization since C++11 and you are able to initialize both via []:
int ptr_arr_int[] = { 1,2 }; //OK
char ptr_arr_char[] = "amruth"; //OK
A string by itself already implies a storage class -- it's a static (+effectively const) char array declared using special syntax.
In contrast to that, it's not clear how {1, 2} in int *ptr_arr_int = {1, 2} should be stored. Should it be static or auto?
If you want it auto when in a local scope or static when in file scope, then in C>=99 you can explicitly do int *ptr_arr_int = &(int[]){1,2}[0]; (the &[0] is optional).
You could conceivably make this implicit, but how far would you take this?int ****x = {1,2}; initialized by creating an array, a pointer to it, a pointer to that etc., could result int quite a bit of code/data and hiding a lot of code/data under a simple construct isn't quite the C way. It would also not be clear when the brace syntax should be initializing the ultimate target basic type or some of the intermediate pointer(s).
It is simply because the language syntax says so. Regarding arrays:
We must initialize an array with a brace-enclosed list {...}, containing no more items that what will fit inside the array.
As a special rule, char arrays can be initialized with a string literal, "...".
However, you have no arrays in your code, you only have pointers.
A char* can always be set to point at a string literal (in C) so char* ptr_arr_char = "amruth"; is valid. However, it is fishy style, because the string literal cannot be modified. Correct style is to use const char*.
C++ is more strict and string literals in C++ have type const char[]. and a C++ compiler will likely give a warning along the lines of "deprecated conversion" if you don't use const char*.
As for int* ptr_arr_int = {1,2};, it has two problems.
{1,2} is an initializer list, but ptr_arr_int is a single item, so it doesn't make any sense. There is a special, odd rule that actually allows us to use {} when initializing a single variable, but then you must only have one single initializer inside.
You cannot initialize a pointer with an integer. See "Pointer from integer/integer from pointer without a cast" issues.
If you meant to have the pointer point at a temporary array, only existing in the local scope, then you could have used the C feature called compound literal:
int* ptr_arr_int = (int[]){1,2};
This is AFAIK not possible to do in C++ though, unless you rely on non-standard extensions. But in either language you could of course simply do this instead:
int arr[2] = {1,2};
int* ptr_arr_int = arr;
You are declaring an array of pointers to int (int*). But the values you initialize the array with (1 and 2) are not pointers to integers, they are plain integers.
You cannot, because int * is not a structure that could be initialized with two values like you did with = {1,2};.
You could have initialized it this way:
int * ptr_arr_int = nullptr;
The other way could have been using an object that expects two values for construction:
struct Point
{
int a;
int b;
};
then you could have written:
Point p = {1,2};
No... that's not correct... that initialiser is only valid for arrays. Had you written:
int array[] = {1, 2};
it would be valid.... but you are trying to initialise a pointer variable, so this would be valid (despite of the warning, because 0xf45 is not an address):
int *pointer = { 0xf45 };
(because you put only a single entry, and it is considered a single value) but:
int *pointer = { 0xf45, 0 };
(You will get another warning about excess elements in scalar initializer) This means that for a single variable you tried to use two initializers. The braces notation was born to be able to initialise arrays, but also is permitted to be used with scalar types. This means that the two notations:
{ 0 }; /* a single value between braces */
and
0;
are equivalent.
The solution to your problem is to do an extra step, declaring an array and then pointing to it from the pointer:
int array[] = {1, 2};
int *pointer = array;
but think that you can make pointer to point to a different place than the beginning of array, and you cannot array to be magically moved elsewhere. And &array means the address of array array while &pointer means the address of the pointer variable pointer. pointer points to the address of array, but array is a constant pointer pointing to the address of array[0].
Pointers and arrays are somewhat confusing, but never think they are the same thing. Just compare sizeof(char[120]) with sizeof(char *) and you'll see.
okay so i have come across this pointer type and i tried to use it in my code but i get a warning from the compiler saying its in incompatible pointer type
this is the type
data_type (*i)[j] with i being the variable name
and j being the size of the pointer
for example if you want the pointer to be as size of 4 ints you would declare
int (*i)[4] and then you would need to assign an array of 4 ints
i = &s[4]
however when i try to assign it, i get a warning from compiler saying incompatible type
so what seems to be the problem here? and how do i use it correctly?
cdecl.org tells us that it is:
int (*i)[4]
declare i as pointer to array 4 of int
So, we can use it like this:
int arr[4];
int (*i)[4] = &arr;
Or, with heap allocated memory:
int (*j)[4] = malloc(sizeof(int[4]));
int (*i)[4]; declares i to be a pointer to an array of 4 ints. You said s is an array of 4 int
int s[4];
assignment
i = &s[4];
is wrong because &s[4] is the address of memory block just past the array and is of type int *. Generally arrays decay into pointer to its first element but in case of as an operand of unary & operator it doesn't decay and therefore &s gives the address of array s which is of type int (*)[4].
i = &s;
If j is variable, then I'd recommend to use std::vector instead and take a reference to the container rather than a pointer:
std::vector<int> i(j);
auto& i_ref = i;
If j is a constant expression, I'd still avoid using C-style arrays and use std::array instead, and still take only a reference:
constexpr std::size_t j = 4;
std::array<int, j> i;
auto& i_ref = i;
This
int s[4];
declares s to be array of 4 ints.
Using the expression s[4] (after s had been defined) would evaluated to the 5th element of s (an int).
As s only has 4 elements, doing so is "illegal" and provokes undefined behaviour of the program.
So to assign to int(*i)[4] the address of s do:
i = &s;
If using C99 or later to initialise i without declaring s you might also do:
i = &(int[4]){0};
Lets assume there's variable of type int** which is the pointer to a 5x5 2D array:
int** ptr_array_5by5;
and a function with the following prototype:
void print2DArray_with5Columns(int (*ptr_row)[5]);
Is there a way to cast ptr_array_5by5 into some type which would match the type of the first argument of the function?
print2DArray_with5Columns( (<some casting type>) ptr_array_5by5)
The important thing to realize here is that int** is not
a pointer to a 2D array of anything. It is a pointer to a 1D
array of pointers. int (*)[5] is a pointer to a 2D array of
int (or more correctly, it is a pointer to the first element
of such an array). You can pretty much convert any pointer type
to any other pointer type using reinterpret_cast, but it is
also pretty much guaranteed not to work at runtime. (There are
special exceptions, but they are all very platform specific, and
very close to the hardware.)
If you really have an int** which points to 5 int*, each of
which points to 5 int, and you need an int (*)[5], the only
way you're going to be able to successfully convert is by doing
a conversion on the actual underlying data (which will involve
a copy), and not a conversion on the pointer. Something like:
int tmp[5][5];
for ( int i = 0; i != 5; ++ i ) {
int* row = ptr_array_5by5[i];
for ( int j = 0; j != 5; ++ j ) {
tmp[i][j] = row[j];
}
}
You can then pass tmp to your function without any casts: the
implicit conversion of array to pointer will convert
int [5][5] to int (*)[5].
Of course.
int** ptr_array_5by5;
void print2DArray_with5Columns(int (*ptr_row)[5]);
print2DArray_with5Columns( (int (*)[5]) ptr_array_5by5);
print2DArray_with5Columns( reinterpret_cast<int (*)[5]>(ptr_array_5by5));
The C language declaration syntax, for all its faults, lets you create casts by simply rewriting the declaration omitting any identifiers. It compiles, and it might even work.
There is a lot of confusion here because the descriptive wording does not match the C declarations. Here is some code that implements this (peculiar) cast and shows that it can work, just as I said.
void print2DArray_with5Columns(int (*ptr_row)[5]) {
for (int i = 0; i < 5; i++)
cout << (*ptr_row)[i] << " ";
cout << std::endl;
}
int main() {
int* a;
int** ptr_array_5by5;
a = new int[25];
for (int i = 0; i < 25; i++)
a[i] = i;
ptr_array_5by5 = (int**)a;
print2DArray_with5Columns((int (*)[5])(ptr_array_5by5));
return 0;
}
Please note that this declaration is not a 5x5 matrix. The cast is simply a pointer to an array of 5 ints, which decays to a simple array. This code generates a 5x5 flat matrix and prints the first row.
I suspect the real problem is that the cast is wrong and therefore the whole question is wrong.
The question has been asked whether this is the dreaded Undefined Behaviour. With suitable care it is not. The standard in effect allows any kind of a pointer-to-object to be cast to some other pointer-to-object or to a void pointer or to a large enough integer, and back again. [Pointer-to-function and pointer-to-member are treated a bit differently.] The round-tripped pointer is guaranteed to retain the same value. Therefore this cast is not UB provided the rules are followed, which is not that hard to do.
int** and int(*)[5] are different types (as n.m. pointed out)
You may treat an array as a pointer, e.g. int a[5]; *(a+1) = 6;
You may treat a pointer as an array, e.g. int *a = new int[5]; a[1] = 6;.
But treating object A as if it were an object B does not mean that it actually is object B.
What you can do though is declaring an int (*)[5], write the values of ptr_array_5by5 into it (after allocating memory, of course), and pass it to print2DArray_with5Columns.
On the other hand, yes there are casts that make your code compile. But I doubt that using one of them is getting you closer to your goal (see http://ideone.com/lVzNrN).
I think you are confused by assuming that pointers are arrays. Pointers are not arrays and vice-versa. If ptr_array_5by5 would be a 2D array then the parameter in prototype is fine for passing ptr_array_5by5 as argument. But you declared it as int **ptr_array_5by5, it is better to change the parameter to int ** type.
Why would you like to cast int **?
You use pointers to point to addresses.
So instead of type casting pointers, you have to point this pointer to some variable.
There is no meaning of type casting pointers because they themselves don't store values.