Create a pointer to two-dimensional array

后端 未结 10 1307
温柔的废话
温柔的废话 2020-11-22 07:16

I need a pointer to a static 2-dimensional array. How is this done?

static uint8_t l_matrix[10][20];

void test(){
   uint8_t **matrix_ptr = l_matrix; //wron         


        
相关标签:
10条回答
  • 2020-11-22 07:47

    You can do it like this:

    uint8_t (*matrix_ptr)[10][20] = &l_matrix;
    
    0 讨论(0)
  • 2020-11-22 07:49

    Here you wanna make a pointer to the first element of the array

    uint8_t (*matrix_ptr)[20] = l_matrix;
    

    With typedef, this looks cleaner

    typedef uint8_t array_of_20_uint8_t[20];
    array_of_20_uint8_t *matrix_ptr = l_matrix;
    

    Then you can enjoy life again :)

    matrix_ptr[0][1] = ...;
    

    Beware of the pointer/array world in C, much confusion is around this.


    Edit

    Reviewing some of the other answers here, because the comment fields are too short to do there. Multiple alternatives were proposed, but it wasn't shown how they behave. Here is how they do

    uint8_t (*matrix_ptr)[][20] = l_matrix;
    

    If you fix the error and add the address-of operator & like in the following snippet

    uint8_t (*matrix_ptr)[][20] = &l_matrix;
    

    Then that one creates a pointer to an incomplete array type of elements of type array of 20 uint8_t. Because the pointer is to an array of arrays, you have to access it with

    (*matrix_ptr)[0][1] = ...;
    

    And because it's a pointer to an incomplete array, you cannot do as a shortcut

    matrix_ptr[0][0][1] = ...;
    

    Because indexing requires the element type's size to be known (indexing implies an addition of an integer to the pointer, so it won't work with incomplete types). Note that this only works in C, because T[] and T[N] are compatible types. C++ does not have a concept of compatible types, and so it will reject that code, because T[] and T[10] are different types.


    The following alternative doesn't work at all, because the element type of the array, when you view it as a one-dimensional array, is not uint8_t, but uint8_t[20]

    uint8_t *matrix_ptr = l_matrix; // fail
    

    The following is a good alternative

    uint8_t (*matrix_ptr)[10][20] = &l_matrix;
    

    You access it with

    (*matrix_ptr)[0][1] = ...;
    matrix_ptr[0][0][1] = ...; // also possible now
    

    It has the benefit that it preserves the outer dimension's size. So you can apply sizeof on it

    sizeof (*matrix_ptr) == sizeof(uint8_t) * 10 * 20
    

    There is one other answer that makes use of the fact that items in an array are contiguously stored

    uint8_t *matrix_ptr = l_matrix[0];
    

    Now, that formally only allows you to access the elements of the first element of the two dimensional array. That is, the following condition hold

    matrix_ptr[0] = ...; // valid
    matrix_ptr[19] = ...; // valid
    
    matrix_ptr[20] = ...; // undefined behavior
    matrix_ptr[10*20-1] = ...; // undefined behavior
    

    You will notice it probably works up to 10*20-1, but if you throw on alias analysis and other aggressive optimizations, some compiler could make an assumption that may break that code. Having said that, i've never encountered a compiler that fails on it (but then again, i've not used that technique in real code), and even the C FAQ has that technique contained (with a warning about its UB'ness), and if you cannot change the array type, this is a last option to save you :)

    0 讨论(0)
  • 2020-11-22 07:49

    The basic syntax of initializing pointer that points to multidimentional array is

    type (*pointer)[1st dimension size][2nd dimension size][..] = &array_name

    The the basic syntax for calling it is

    (*pointer_name)[1st index][2nd index][...]
    

    Here is a example:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main() {
       // The multidimentional array...
       char balance[5][100] = {
           "Subham",
           "Messi"
       };
    
       char (*p)[5][100] = &balance; // Pointer initialization...
    
       printf("%s\n",(*p)[0]); // Calling...
       printf("%s\n",(*p)[1]); // Calling...
    
      return 0;
    }
    

    Output is:

    Subham
    Messi
    

    It worked...

    0 讨论(0)
  • 2020-11-22 07:52

    You could also add an offset if you want to use negative indexes:

    uint8_t l_matrix[10][20];
    uint8_t (*matrix_ptr)[20] = l_matrix+5;
    matrix_ptr[-4][1]=7;
    

    If your compiler gives an error or warning you could use:

    uint8_t (*matrix_ptr)[20] = (uint8_t (*)[20]) l_matrix;
    
    0 讨论(0)
提交回复
热议问题