Thread: 2-dimensional array & pointers

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    27

    2-dimensional array & pointers

    Hi guys, I'm pretty much a C newbie, but I've dabbled in other languages over the years. For my current project I'm using mikroElektronica Pro C on a PIC microcontroller.

    I've got a 2-dimensional array defined like this:

    Code:
    const char FONTTABLE[96][5]= 
    { 
    {0x00,0x00,0x00,0x00,0x00}, 
    {0x00,0x00,0x5f,0x00,0x00}, 
    {0x00,0x07,0x00,0x07,0x00}, 
    /** [90 rows snipped] **/ 
    {0x00,0x41,0x36,0x08,0x00}, 
    {0x10,0x08,0x08,0x10,0x08}, 
    {0x78,0x46,0x41,0x46,0x78} 
    };

    I want to select a given row from this using the index (0-95), then pass that element (a 5 element array) to a routine that will process each byte for the size of the row (5 in this case). I'm pretty sure I need to use a pointer, but no matter what I do I get compile errors.

    Any tips?

  2. #2
    Registered User
    Join Date
    Dec 2009
    Location
    Rome
    Posts
    7
    Let's say you wanna select the 4th row
    char *p = FONTTABLE[3][0];

    p identifies the pointer to the first element of the 4th row
    p+1 = p + sizeof(char) identifies the pointer to the second element of the 4th row
    ...
    p+4 identifies the pointer to the fifth element of the 4th row

    *p identifies the first element of the 4th row
    *(p+1) identifies the second element of the 4th row
    and so on

    i hope it helped you

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Quote Originally Posted by nigelmercier View Post
    Hi guys, I'm pretty much a C newbie, but I've dabbled in other languages over the years. For my current project I'm using mikroElektronica Pro C on a PIC microcontroller.

    I've got a 2-dimensional array defined like this:

    Code:
    const char FONTTABLE[96][5]= 
    { 
    {0x00,0x00,0x00,0x00,0x00}, 
    {0x00,0x00,0x5f,0x00,0x00}, 
    {0x00,0x07,0x00,0x07,0x00}, 
    /** [90 rows snipped] **/ 
    {0x00,0x41,0x36,0x08,0x00}, 
    {0x10,0x08,0x08,0x10,0x08}, 
    {0x78,0x46,0x41,0x46,0x78} 
    };

    I want to select a given row from this using the index (0-95), then pass that element (a 5 element array) to a routine that will process each byte for the size of the row (5 in this case). I'm pretty sure I need to use a pointer, but no matter what I do I get compile errors.

    Any tips?
    You have an array, char FONTTABLE[96][5]. If you said FONTTABLE[i], that would give you the i'th "row" (from 0-95); FONTTABLE[i] is of type char[5]. Anyway, this just means that you can use
    Code:
    char FONTTABLE[96][5]=/*...*/
    
    int i = 44;  /* in the range [0, 96) */
    process(FONTTABLE[i]);
    
    void process(char row[5]) {
        int j;
        for(j = 0; j < 5; j ++) {
            char c = row[j];
            /* ... */
        }
    }
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    Registered User
    Join Date
    Dec 2009
    Posts
    27
    Interesting: one answer with pointers, one without

    Perhaps I should have said, I'm happy about extracting the row, just not sure about getting a handle on it. I think I'm beginning to understand, but I'm not sure about:

    Code:
    p+1 = p + sizeof(char)
    I think I will need to use sizeOf, because the same routine is going to process char arrays of different sizes - the above is a sample of one of them.

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Perhaps I should have said, I'm happy about extracting the row, just not sure about getting a handle on it. I think I'm beginning to understand, but I'm not sure about:

    Code:
    p+1 = p + sizeof(char)
    I think I will need to use sizeOf, because the same routine is going to process char arrays of different sizes - the above is a sample of one of them.
    I'm really not sure what your question is. If you can figure out how to extract a row, then extracting characters from the row is basically the same thing.
    Code:
    #include <stdio.h>
    
    /* If you leave out the last dimension, the compiler will calculate it for you.
    */
    static const char FONTTABLE[][5]= 
    {
        {0x00,0x00,0x00,0x00,0x00},
        {0x00,0x00,0x5f,0x00,0x00},
        {0x00,0x07,0x00,0x07,0x00},
        /** [90 rows snipped] **/
        {0x00,0x41,0x36,0x08,0x00},
        {0x10,0x08,0x08,0x10,0x08},
        {0x78,0x46,0x41,0x46,0x78}
    };
    
    void print(const char data[5]) {
        int x;
        for(x = 0; x < 5; x ++) {
            printf("0x%02x ", data[x]);
        }
        printf("\n");
    }
    
    int main(int argc, char *argv[]) {
        print(FONTTABLE[2]);
        
        return 0;
    }
    And by the way: my example might not have used pointers directly, but arrays behave in much the same way most of the time, especially when you pass them as arguments to functions.

    I just noticed the last line of your post. If you're dealing with arrays of different sizes, then you can't pass an "array" parameter like char data[5]; you have to pass a pointer to the first element, as well as the number of elements in the array. For example:
    Code:
    #include <stdio.h>
    
    /* If you leave out the last dimension, the compiler will calculate it for you.
    */
    static const char FONTTABLE[][5]= 
    {
        {0x00,0x00,0x00,0x00,0x00},
        {0x00,0x00,0x5f,0x00,0x00},
        {0x00,0x07,0x00,0x07,0x00},
        /** [90 rows snipped] **/
        {0x00,0x41,0x36,0x08,0x00},
        {0x10,0x08,0x08,0x10,0x08},
        {0x78,0x46,0x41,0x46,0x78}
    };
    
    void print(const char *data, size_t size) {
        size_t x;
        for(x = 0; x < size; x ++) {
            printf("0x%02x ", data[x]);
        }
        printf("\n");
    }
    
    int main(int argc, char *argv[]) {
        print(FONTTABLE[2], sizeof(FONTTABLE[0])/sizeof(FONTTABLE[0][0]));
        
        return 0;
    }
    The sizeof() part just gives you 5, in this example.

    Maybe you can be a little more specific as to exactly what you're trying to do?
    Last edited by dwks; 12-26-2009 at 05:29 PM.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    Registered User
    Join Date
    Dec 2009
    Location
    Rome
    Posts
    7
    Quote Originally Posted by nigelmercier View Post
    Interesting: one answer with pointers, one without

    Perhaps I should have said, I'm happy about extracting the row, just not sure about getting a handle on it. I think I'm beginning to understand, but I'm not sure about:

    Code:
    p+1 = p + sizeof(char)
    I think I will need to use sizeOf, because the same routine is going to process char arrays of different sizes - the above is a sample of one of them.
    i was saying that the 1 of p+1 come from sizeof(char)
    if we were talking about int, sizeof(int) on a 32 bit machine would give 4
    and passing between two cells of memory array (using pointers) would be p+4

    i hope i was more clear now

  7. #7
    Registered User
    Join Date
    Dec 2009
    Posts
    27
    Quote Originally Posted by dwks View Post
    Maybe you can be a little more specific as to exactly what you're trying to do?
    OK, lets say I've calculated elsewhere that I need the data in row i. Now I want to pass this row (a one-dimensional array) to another function. In this function I need to (say) iterate through the array (using the sizeof the passed array as the iteration delimiter) and calculate the total of the elements of the row.

    Code:
     
    void getResults(char candidateNumber)
    { // enter this function with a number 0-255 and extract results
    getTotal(/*what goes in here to pass a reference the sub-array?*/)
    // more code
    }
     
     
    void getTotal(/*what goes in here to pass the sub-array?*/)
    { 
    integer total = 0;
    for(x = 0; x < the sizeof the passed array?; x ++) 
      {total = total + each element of the passed array?};
    }

    Pointers are still above my learning curve, so I'm just stuck on how to declare the pointer to get a handle on the passed array, and how to reference it within the functions, see the 4 questions marked ? in the dummy code above.

    Nigel

    PS It isn't quite like that, but I want to avoid complications of using print statements, I know nothing about them - PICs don't have print output!
    Last edited by nigelmercier; 12-27-2009 at 09:40 AM.

  8. #8
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    The last post by dwks makes that ample clear, so read it well especially the code section.
    Code:
    void getResults(char candidateNumber)
    {
        ...
        getTotal(FONTTABLE[i], sizeof FONTTABLE[i]);
        ...
    }
    
    void getTotal(char *handle, int size)
    {
        int i, total = 0;
        for (i = 0; i < size; i++) 
            total += *(handle + i);
    }

  9. #9
    Registered User
    Join Date
    Dec 2009
    Posts
    27
    Quote Originally Posted by itCbitC View Post
    The last post by dwks makes that ample clear, so read it well especially the code section.
    Thanks, but I didn't understand this bit:

    Code:
     
    void print(const char *data, size_t size) {
        size_t x;
    It seems to have a type size_t - is that right?

    Code:
    void getResults(char candidateNumber)
    {
        ...
        getTotal(FONTTABLE[i], sizeof FONTTABLE[i]);
        ...
    }
     
    void getTotal(char *handle, int size)
    {
        int i, total = 0;
        for (i = 0; i < size; i++) 
            total += *(handle + i);
    }
    Now that I can follow, thank you. So I have to pass the size to the function, not find it within? This is probably where I have been going wrong.

  10. #10
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    The only way you can find the end of an array is to either pass the size, and use it to control your loop, or, to set aside a specific value as a terminator. That's what all the string functions do. They say this is valid until you run into 0. So, you can do something like that, or you have to supply the size.


    Quzah.
    Hope is the first step on the road to disappointment.

  11. #11
    Registered User
    Join Date
    Dec 2009
    Location
    Rome
    Posts
    7
    Quote Originally Posted by nigelmercier View Post
    Thanks, but I didn't understand this bit:

    Code:
     
    void print(const char *data, size_t size) {
        size_t x;
    It seems to have a type size_t - is that right?
    stdlib.h - Wikipedia, the free encyclopedia

    quzah answered already for the rest of the question

  12. #12
    Registered User
    Join Date
    Dec 2009
    Posts
    27
    Quote Originally Posted by quzah View Post
    The only way you can find the end of an array is to either pass the size, and use it to control your loop, or, to set aside a specific value as a terminator. Quzah.
    What I meant was, do I have to pass the size, or can I find in in the called function?

  13. #13
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    What part of my answer was confusing?

    The only way you can find the end of an array is to either pass the size, and use it to control your loop, or, to set aside a specific value as a terminator.

    So, if we break that down:
    1. Pass the size.
    2. Don't pass the size, but stop when you hit a specific predetermined value.

    Pick an option in the very short list above.


    Quzah.
    Hope is the first step on the road to disappointment.

  14. #14
    Registered User
    Join Date
    Oct 2009
    Location
    While(1)
    Posts
    377
    What Mr. Quzah want to tell u is that......
    How would you know that, in calling function the array size..... for traversal

    example

    Code:
    void print_elements(const int* array, const int array_size) {
    
     // How would u know the array size.......
      for (int i = 0; i < array_length/*array_size */; ++i)
    
    }
    
    // than u can iterate easily with array_length

  15. #15
    Registered User
    Join Date
    Dec 2009
    Posts
    27
    Quote Originally Posted by itCbitC View Post
    The last post by dwks makes that ample clear, so read it well especially the code section.
    Code:
    void getResults(char candidateNumber)
    {
        ...
        getTotal(FONTTABLE, sizeof FONTTABLE);
      ...
    }
     
    void getTotal(char *handle, int size)
    {
      int i, total = 0;
      for (i = 0; i < size; i++) 
          total += *(handle + i);
    }

    Oh dear, I thought I was winning for a moment. Here is my equivalent code:


    Code:
    void charLcd(unsigned char character) // Send any # of bytes to LCD
    {
    int tablept; // pointer in table -  i in above example
    if ((character<0x20)||(character>0x7f))
    {return;} // Exit function if character out of ASCII range
    tablept = (character - 32); // Index to row of the character in table.
     
    sendGlyphs(font5[tablept], 5); //LINE 128 (note ignore sizeof for tests and use 5)
    }
     
    void sendGlyphs(char *handle, int size)
    { char count;
    for (count=0; count<size; count++) // Send all columns to print the character.
    {
    sendData((*handle + count));
    }
    sendData(0x00); // 1 pixel space after character.
    }
    I get an error Illegal pointer conversion in Line 128:

    sendGlyphs(font5[tablept], 5); // which is the equivalent of
    getTotal(FONTTABLE[i], sizeof FONTTABLE[i]);

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 10-21-2007, 07:44 AM
  2. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  3. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  4. Hi, could someone help me with arrays?
    By goodn in forum C Programming
    Replies: 20
    Last Post: 10-18-2001, 09:48 AM