Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Complex multidimensional array in C++

Complex multidimensional array in C++

Scheduled Pinned Locked Moved C / C++ / MFC
helpquestionc++data-structurestutorial
15 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    Vaclav_
    wrote on last edited by
    #1

    I can do multidimensional array , no problem. What I need is sort of " multidimensional array of single variable and variable length array ". The main array is defined / assigned (?) and of "fixed length" - three in example - for now. Of course I need to access all using pointer. How do I accomplish this ? PS I did try std:array , but it conflicts with "boost" - can't do for now.

          int Array \[3\]\[2\] = {{2, 5} , {3,1} , {4,9}}; multidimensional array OK 
    
      int Array\_Array \[ ??? \] = {
    		  {{1} ,{2, 5 ....}},      {single element} , {array...} 
    		  {{2} ,{2, 5 ...}},
    		  {{3} ,{2, 5....}}
      };
    

    Help will be appreciated. Cheers Vaclav

    L K S 3 Replies Last reply
    0
    • V Vaclav_

      I can do multidimensional array , no problem. What I need is sort of " multidimensional array of single variable and variable length array ". The main array is defined / assigned (?) and of "fixed length" - three in example - for now. Of course I need to access all using pointer. How do I accomplish this ? PS I did try std:array , but it conflicts with "boost" - can't do for now.

            int Array \[3\]\[2\] = {{2, 5} , {3,1} , {4,9}}; multidimensional array OK 
      
        int Array\_Array \[ ??? \] = {
      		  {{1} ,{2, 5 ....}},      {single element} , {array...} 
      		  {{2} ,{2, 5 ...}},
      		  {{3} ,{2, 5....}}
        };
      

      Help will be appreciated. Cheers Vaclav

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      Use a class or structure which has pointer for the second variable:

      struct foo
      {
      int first;
      int* second;
      } fooArray[];

      D V 3 Replies Last reply
      0
      • L Lost User

        Use a class or structure which has pointer for the second variable:

        struct foo
        {
        int first;
        int* second;
        } fooArray[];

        D Offline
        D Offline
        Daniel Pfeffer
        wrote on last edited by
        #3

        If you have an two-dimensional array where each row has a differing number of elements, why not use a std::vector?

        std::vector foo2DArray[];

        Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

        L 1 Reply Last reply
        0
        • D Daniel Pfeffer

          If you have an two-dimensional array where each row has a differing number of elements, why not use a std::vector?

          std::vector foo2DArray[];

          Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          I think you meant this answer for Vaclav.

          D 1 Reply Last reply
          0
          • L Lost User

            I think you meant this answer for Vaclav.

            D Offline
            D Offline
            Daniel Pfeffer
            wrote on last edited by
            #5

            :-O

            Freedom is the freedom to say that two plus two make four. If that is granted, all else follows. -- 6079 Smith W.

            1 Reply Last reply
            0
            • L Lost User

              Use a class or structure which has pointer for the second variable:

              struct foo
              {
              int first;
              int* second;
              } fooArray[];

              V Offline
              V Offline
              Vaclav_
              wrote on last edited by
              #6

              Thanks, just what the doctor ordered. Then I can add another member to the struct if I want. Nice and clean solution.

              L V 2 Replies Last reply
              0
              • V Vaclav_

                I can do multidimensional array , no problem. What I need is sort of " multidimensional array of single variable and variable length array ". The main array is defined / assigned (?) and of "fixed length" - three in example - for now. Of course I need to access all using pointer. How do I accomplish this ? PS I did try std:array , but it conflicts with "boost" - can't do for now.

                      int Array \[3\]\[2\] = {{2, 5} , {3,1} , {4,9}}; multidimensional array OK 
                
                  int Array\_Array \[ ??? \] = {
                		  {{1} ,{2, 5 ....}},      {single element} , {array...} 
                		  {{2} ,{2, 5 ...}},
                		  {{3} ,{2, 5....}}
                  };
                

                Help will be appreciated. Cheers Vaclav

                K Offline
                K Offline
                k5054
                wrote on last edited by
                #7

                If your single element is unique, then maybe a map of vectors might be a better choice e.g.

                map>

                There is a requirement that obj_a implement operator<(). Basically if its not a basic type (e.g. int, double, string, etc), you need to add a

                bool operator<(const foo& other) const {}

                method to the object, which is usually straight forward.

                V 1 Reply Last reply
                0
                • V Vaclav_

                  Thanks, just what the doctor ordered. Then I can add another member to the struct if I want. Nice and clean solution.

                  L Offline
                  L Offline
                  Lost User
                  wrote on last edited by
                  #8

                  Yes, if you are using a struct you can have many different items inside it. Also, as Daniel mentions below (to me) you may want to use a std::vector rather than a simple array.

                  1 Reply Last reply
                  0
                  • V Vaclav_

                    Thanks, just what the doctor ordered. Then I can add another member to the struct if I want. Nice and clean solution.

                    V Offline
                    V Offline
                    Vaclav_
                    wrote on last edited by
                    #9

                    Here is my test code. It is not very "dynamic" but will do for now. I may add the "Command" as a first element in Data array to make sure they match. Actually it would simplify things (a little ) - using just multidimensional array with first element being "Command". But I like the struct for future.... Now I need to modify usage of Command /Data....

                    #define COMMAND_ARRAY 16
                    struct ILI9341 {
                    int Command; // ILI9341 commands
                    int* Data; // ILI9341 data
                    } ILI9341Array[COMMAND_ARRAY];

                    // define/ assign Command
                    int index = 0;
                    int dataIndex = 0;
                    int DefineCommand\[COMMAND\_ARRAY\] = { 0x0, 0x1, 0x4 };
                    int DefineData\[\]\[10\] = { { 1, 2, 3, 4 }, { 5, 6, 7 }, { 9, 10, 11, 12, 13,
                    		14 } };
                    for (index = 0; index != 3; index++) {
                    	ILI9341Array\[index\].Command = DefineCommand\[index\];
                    

                    #ifdef DEBUG
                    cout << "ILI9341Array[" << dec << +index << "] Command 0x" << hex
                    << ILI9341Array[index].Command << endl;
                    #endif
                    ILI9341Array[index].Data = DefineData[index];
                    #ifdef DEBUG
                    do {
                    cout << "ILI9341Array[" << dec << +index << "] Data[" << dec
                    << +dataIndex << "] 0x" << hex
                    << ILI9341Array[index].Data[dataIndex] << endl;

                    	} while (ILI9341Array\[index\].Data\[++dataIndex\]);
                    	dataIndex = 0;
                    

                    #endif

                    }
                    
                    K 1 Reply Last reply
                    0
                    • V Vaclav_

                      Here is my test code. It is not very "dynamic" but will do for now. I may add the "Command" as a first element in Data array to make sure they match. Actually it would simplify things (a little ) - using just multidimensional array with first element being "Command". But I like the struct for future.... Now I need to modify usage of Command /Data....

                      #define COMMAND_ARRAY 16
                      struct ILI9341 {
                      int Command; // ILI9341 commands
                      int* Data; // ILI9341 data
                      } ILI9341Array[COMMAND_ARRAY];

                      // define/ assign Command
                      int index = 0;
                      int dataIndex = 0;
                      int DefineCommand\[COMMAND\_ARRAY\] = { 0x0, 0x1, 0x4 };
                      int DefineData\[\]\[10\] = { { 1, 2, 3, 4 }, { 5, 6, 7 }, { 9, 10, 11, 12, 13,
                      		14 } };
                      for (index = 0; index != 3; index++) {
                      	ILI9341Array\[index\].Command = DefineCommand\[index\];
                      

                      #ifdef DEBUG
                      cout << "ILI9341Array[" << dec << +index << "] Command 0x" << hex
                      << ILI9341Array[index].Command << endl;
                      #endif
                      ILI9341Array[index].Data = DefineData[index];
                      #ifdef DEBUG
                      do {
                      cout << "ILI9341Array[" << dec << +index << "] Data[" << dec
                      << +dataIndex << "] 0x" << hex
                      << ILI9341Array[index].Data[dataIndex] << endl;

                      	} while (ILI9341Array\[index\].Data\[++dataIndex\]);
                      	dataIndex = 0;
                      

                      #endif

                      }
                      
                      K Offline
                      K Offline
                      k5054
                      wrote on last edited by
                      #10

                      That's way too much typing. Consider:

                      #include <iostream>
                      #include <iomanip>
                      #include <map>
                      #include <vector>

                      using namespace std;

                      #define DEBUG

                      int main()
                      {
                      map<int,vector<int>> IL9341Command = {{ {0x0, {{ 1, 2, 3, 4 }} },
                      {0x1, {{ 4, 6, 7, }} },
                      {0x4, {{ 9, 10, 11, 12, 13, 14 }} },
                      {0xff, {{ 44, 55, 66, 77 }} } }};

                      #ifdef DEBUG
                      for(auto iter : IL9341Command) {
                      cout << "IL9341Comand [ 0x" << hex << iter.first << " ] =";
                      for(auto cmd : iter.second)
                      cout << " 0x" << hex << cmd;
                      cout << endl;
                      }

                      int \*data = IL9341Command\[0xff\].data(); // get access to raw vector data
                      
                      cout << "\\nCommand\[0xff\] data :";
                      for(size\_t i = 0; i < IL9341Command\[0xff\].size(); i++)
                          cout <<  " 0x" << data\[i\];
                      cout << endl;
                      

                      #endif // DEBUG

                      return 0;
                      

                      }

                      You can access the command data directly if you know the key via IL941Command[key], without having to iterate through the array, and as shown above, access to the "raw data" can be gained by calling data() on the vector. If you have C++17 then you can simplify the for(auto iter ...) loop as follows

                      for(auto [key, data] : IL9341Command) {
                      cout << "IL9341Comand [ 0x" << hex << key << " ] =";
                      for(auto cmd : data)
                      cout << " 0x" << hex << cmd;
                      cout << endl;
                      }

                      K 1 Reply Last reply
                      0
                      • K k5054

                        That's way too much typing. Consider:

                        #include <iostream>
                        #include <iomanip>
                        #include <map>
                        #include <vector>

                        using namespace std;

                        #define DEBUG

                        int main()
                        {
                        map<int,vector<int>> IL9341Command = {{ {0x0, {{ 1, 2, 3, 4 }} },
                        {0x1, {{ 4, 6, 7, }} },
                        {0x4, {{ 9, 10, 11, 12, 13, 14 }} },
                        {0xff, {{ 44, 55, 66, 77 }} } }};

                        #ifdef DEBUG
                        for(auto iter : IL9341Command) {
                        cout << "IL9341Comand [ 0x" << hex << iter.first << " ] =";
                        for(auto cmd : iter.second)
                        cout << " 0x" << hex << cmd;
                        cout << endl;
                        }

                        int \*data = IL9341Command\[0xff\].data(); // get access to raw vector data
                        
                        cout << "\\nCommand\[0xff\] data :";
                        for(size\_t i = 0; i < IL9341Command\[0xff\].size(); i++)
                            cout <<  " 0x" << data\[i\];
                        cout << endl;
                        

                        #endif // DEBUG

                        return 0;
                        

                        }

                        You can access the command data directly if you know the key via IL941Command[key], without having to iterate through the array, and as shown above, access to the "raw data" can be gained by calling data() on the vector. If you have C++17 then you can simplify the for(auto iter ...) loop as follows

                        for(auto [key, data] : IL9341Command) {
                        cout << "IL9341Comand [ 0x" << hex << key << " ] =";
                        for(auto cmd : data)
                        cout << " 0x" << hex << cmd;
                        cout << endl;
                        }

                        K Offline
                        K Offline
                        k5054
                        wrote on last edited by
                        #11

                        Hmm. Not sure why the code didn't format properly within the <pre code="C++"> tags. I looked closely and there wasn't any tags in the code as posted. Also, how does one post code with preprocessor directives in column one without them turning into (h1) header lines? Edit: the format issue with the code was because I needed to convert "<" into <.

                        1 Reply Last reply
                        0
                        • K k5054

                          If your single element is unique, then maybe a map of vectors might be a better choice e.g.

                          map>

                          There is a requirement that obj_a implement operator<(). Basically if its not a basic type (e.g. int, double, string, etc), you need to add a

                          bool operator<(const foo& other) const {}

                          method to the object, which is usually straight forward.

                          V Offline
                          V Offline
                          Vaclav_
                          wrote on last edited by
                          #12

                          Well , I realize my way is too crude for today's standards. Yes, the "command(s)' are unique and direct access to data would be much cleaner than scanning. But I forgot that the command is actually "top level" - the same data can be actual "command" or "data" ( to be read). The clocking of the command (command or data) is different so I need some identifier for that. I need to rethink the method how to accomplish that - so far plain two dimensional array with "command" , " command or data flag " , "data" scheme looks simpler. Minor issue is - the "data" can be 0x0 - such as "0x4, 0x0, 0x7" etc.so plain scanning won't do. I need a break. Later.

                          1 Reply Last reply
                          0
                          • V Vaclav_

                            I can do multidimensional array , no problem. What I need is sort of " multidimensional array of single variable and variable length array ". The main array is defined / assigned (?) and of "fixed length" - three in example - for now. Of course I need to access all using pointer. How do I accomplish this ? PS I did try std:array , but it conflicts with "boost" - can't do for now.

                                  int Array \[3\]\[2\] = {{2, 5} , {3,1} , {4,9}}; multidimensional array OK 
                            
                              int Array\_Array \[ ??? \] = {
                            		  {{1} ,{2, 5 ....}},      {single element} , {array...} 
                            		  {{2} ,{2, 5 ...}},
                            		  {{3} ,{2, 5....}}
                              };
                            

                            Help will be appreciated. Cheers Vaclav

                            S Offline
                            S Offline
                            Stefan_Lang
                            wrote on last edited by
                            #13

                            Vaclav_ wrote:

                            PS I did try std:array , but it conflicts with "boost" - can't do for now.

                            I'm using both boost functinality and std::array without any problems, ever. What is the problem you are experiencing? Maybe you were too gracious with using statements and contaminating your global namespace?

                            GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

                            1 Reply Last reply
                            0
                            • L Lost User

                              Use a class or structure which has pointer for the second variable:

                              struct foo
                              {
                              int first;
                              int* second;
                              } fooArray[];

                              V Offline
                              V Offline
                              Vaclav_
                              wrote on last edited by
                              #14

                              Richard, I finally decided to use your suggestion and having a hard time initializing the pointer in the struct. Here is how it looks as of today

                              struct ILI9341 {
                              	uint8\_t index;  // tracking index
                              	uint8\_t Command; //
                              	uint8\_t c\_d;    // flag 0 command 1 data
                              	uint8\_t \*Data;  // data array
                              // data array format
                              // valid data count
                              // data...
                              // end marker
                              	char \*Name;     // command name
                              	char \*Function; // brief function description
                              	uint32\_t delay = 0; // delay in uS after command
                              	char \*RefPage;  // ILI9341 manual reference page
                              	char \*Notes;    // misc notes
                              	uint8\_t temp\[COMMAND\_ARRAY\] = {}; // kluge 
                              } ILI9341\_CommandList\[COMMAND\_ARRAY\];
                              

                              I did try this (C sample I found) , but that obviously does not work initializing multiple struct and I feel it defeats the pointer by making the temp array fixed length.

                              uint8_t temp[3] = { 0x1, 0x0, 0xFF };
                              //int g_thing1array[3] = { 3, 4, 5 }; C example
                              //thing g_thing1 = { 1, 2, g_thing1array };
                              ILI9341_CommandList[4].Data = temp;

                              L 1 Reply Last reply
                              0
                              • V Vaclav_

                                Richard, I finally decided to use your suggestion and having a hard time initializing the pointer in the struct. Here is how it looks as of today

                                struct ILI9341 {
                                	uint8\_t index;  // tracking index
                                	uint8\_t Command; //
                                	uint8\_t c\_d;    // flag 0 command 1 data
                                	uint8\_t \*Data;  // data array
                                // data array format
                                // valid data count
                                // data...
                                // end marker
                                	char \*Name;     // command name
                                	char \*Function; // brief function description
                                	uint32\_t delay = 0; // delay in uS after command
                                	char \*RefPage;  // ILI9341 manual reference page
                                	char \*Notes;    // misc notes
                                	uint8\_t temp\[COMMAND\_ARRAY\] = {}; // kluge 
                                } ILI9341\_CommandList\[COMMAND\_ARRAY\];
                                

                                I did try this (C sample I found) , but that obviously does not work initializing multiple struct and I feel it defeats the pointer by making the temp array fixed length.

                                uint8_t temp[3] = { 0x1, 0x0, 0xFF };
                                //int g_thing1array[3] = { 3, 4, 5 }; C example
                                //thing g_thing1 = { 1, 2, g_thing1array };
                                ILI9341_CommandList[4].Data = temp;

                                L Offline
                                L Offline
                                Lost User
                                wrote on last edited by
                                #15

                                You cannot add initialisers to the struct definition, but only to actual instances of it. So it should rather be something like:

                                struct ILI9341 { // definition of the struct starts here
                                uint8_t index; // tracking index
                                uint8_t Command; //
                                uint8_t c_d; // flag 0 command 1 data
                                uint8_t *Data; // data array
                                // data array format
                                // valid data count
                                // data...
                                // end marker
                                char *Name; // command name
                                char *Function; // brief function description
                                uint32_t delay; // delay in uS after command
                                char *RefPage; // ILI9341 manual reference page
                                char *Notes; // misc notes
                                uint8_t* temp; // this should be a pointer to allow for variable length entries
                                } ILI9341_CommandList[COMMAND_ARRAY] =
                                { // actual instances in the array are initialised here
                                { // first entry in the structure array
                                0, // tracking index
                                0, // Command
                                0, // flag 0 command 1 data
                                buffer, // data array buffer declared elsewhere as BYTE buffer[some number]
                                "command name" // command name
                                "Function", // brief function description
                                100, // delay in uS after command
                                RefPage, // ILI9341 manual reference page
                                Notes, // misc notes
                                { 0x1, 0x0, 0xFF } // command array - you may need a counter somewhere to indicate
                                // how many entries are in this array
                                }, // end of the first entry
                                {
                                // other entries up to a maximum of COMMAND_ARRAY
                                }
                                };

                                And you can also fill in any of the fields later in the executable code by addressing struct entries as ILI9341_CommandList[n] where n is in the range [0..COMMAND_ARRAY-1].

                                1 Reply Last reply
                                0
                                Reply
                                • Reply as topic
                                Log in to reply
                                • Oldest to Newest
                                • Newest to Oldest
                                • Most Votes


                                • Login

                                • Don't have an account? Register

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • World
                                • Users
                                • Groups