I can't seem to find what I'm looking for. I'm learning how to use 2D Arrays in C while also learning pointers. Whats the best way to declare a pointer for a 2D array?
I'm doing it this way
int nums[2][3] = {
{5, 4, 3},
{3, 0, 9}
};
int *numsptr = nums;
printf("%p\n", numsptr);
Also how can I access specific indexes through pointers? The article I read said this.
In general, nums[i][j] is equivalent to *(*(nums+i)+j)
I tried doing this.
printf("%d\\n", (*numsptr + 1) + 2);
Which outputs 8
(Which isn't in the 2D array)
This is how I generally would
numsptr[r*cols + c]
Which would be equivalent to
nums[r][c]
If you want to dynamically find cols
rather than hardcode, the following expression can be used
sizeof(nums[0])/sizeof(nums[0][0])
The reason this
printf("%d\n", (*numsptr + 1) + 2);
prints 8
is because *numsptr
returns the value at nums[0]
, which is 5
, adds 1
, and then adds 2
(which is 8
);
how can I access specific indexes through pointers?
Depends on the pointer. You can declare a pointer to an array of 3 ints
, that way you can just access the pointer almost as-if the array (but watch out for sizeof
):
int (*ptr)[3] = nums;
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 3; ++j) {
printf("[%d][%d] = %d\n", i, j, ptr[i][j]);
// since you mentioned `a[b] == *(a + b)` some alternatives:
// or printf("[%d][%d] = %d\n", i, j, *(*(ptr + i) + j));
// or printf("[%d][%d] = %d\n", i, j, *(ptr[i] + j));
// or printf("[%d][%d] = %d\n", i, j, (*(ptr + i))[j]);
// or pls dont printf("[%d][%d] = %d\n", i, j, i[ptr][j]);
}
}
You use a pointer to the array of 2 arrays of 3 int
s. Semantically, it's a different thing and you have to first dereference the pointer:
int (*var)[2][3] = &nums;
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 3; ++j) {
printf("[%d][%d] = %d\n", i, j, (*var)[i][j]);
}
}
Because elements in an array are laid in memory continuously, you can alias the array with a pointer to int
and do the row/column arithmetic yourself:
int *p = (int*)nums;
for (int i = 0; i < 2 * 3; ++i) {
printf("[%d] = %d\n", i, p[i]);
}
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 3; ++j) {
printf("[%d][%d] = %d\n", i, j, p[i * 3 + j]);
}
}
There are several flavors of pointers to multidimensional arrays.
There's the pointer that comes from applying the &
operator to the array expression. Given the declaration
int nums[2][3];
then the expression &nums
yields a pointer of type int (*)[2][3]
- “pointer to 2-element array of 3-element array of int
”. You'd declare it as
int (*ptr)[2][3] = &nums;
You'd index into it as (*ptr)[i][j]
. Since the []
operator has higher precedence than the unary *
operator, you need to explicitly group the *
with ptr
for it to work properly.
There's the pointer that comes from the “decay” rule for arrays - 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
” will be converted (“decay”) to an expression of type “pointer to T
” and the value of the expression will be the address of the first element of the array. So the expression nums
“decays” from type “2-element array of 3-element array of int
” ( int [2][3]
) to type “pointer to 3-element array of int
” ( int (*)[3]
):
int (*ptr)[3] = nums; // no & operator
You'd index into this as ptr[i][j]
. Remember that the subscript operation a[i]
is defined as *(a + i)
, so *ptr
is the same as ptr[0]
, so (*ptr)[j]
is the same as (ptr[0])[j]
. This is probably the more commonly used form for pointers to 2D arrays.
Then there's the double pointer int **
, which is not actually a pointer to a 2D array, but a pointer to an array of pointers, each element of which points to the first element of another array, usually allocated like so:
int **ptr = malloc( 2 * sizeof *ptr );
if ( ptr )
{
for ( size_t i = 0; i < 2; i++ )
{
ptr[i] = malloc( 3 * sizeof *ptr[i] );
}
}
This is an example of a “jagged” array, where the rows are not contiguous and don't have to be the same size. These are usually allocated dynamically. You'd index into it as ptr[i][j]
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.