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.
  • 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