For the first example, as to why you do not have to do any dereferencing, is that I am guessing the compiler is doing the heavy lifting. What is probably occurring is that A[i][j]
will increment a copy of the value of A as a new address value by j * sizeof(unsigned int *), then it will be assigned the address that is stored at A[j], as demonstrated by the fact that if you dereference *A[i], you will get the first value in the ith array. It will then increment the value of our address pointer by j * sizeof(unsigned int) to get to the number you are looking for.
The second example does not compile for me. You can also just do unsigned int A[n][m];
unsigned int n = 10;
unsigned int m = 15;
double ** A = new double * [n];
for(int i = 0; i < n; ++i) {
A[i] = new double[m]{1, 2, 3, 4};
}
std::cout << A << "\t" << *A << std::endl;
for(int j = 0; j < n; ++j) {
std::cout << A[j] << "\t" << *A[j] << "\t" << A[j][0] << std::endl;
}
for(int j = 0; j < n; ++j) {
delete(A[j]);
}
delete(A);
I hope this helps!