Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
02/23/08 22:30
Modified:
  02/23/08 23:11

Read: times


 
Msg Score: +1
 +1 Good Question
#151357 - Putting it all together
Responding to: ???'s previous message
There are some subtle aspects of how C handles strings that everyone is dancing around here but nobody is explaining very clearly because it's a lot of work. Let me try to fill in the gaps.

Hint #1. When you code a literal string in C, it automatically adds a byte containing zero at the end to mark the end of the string. So, when you code:
char string[] = "abcde";
that makes an array of six bytes (not five). The first five, string[0] through string[4], contain the characters 'a' through 'e', as you'd expect. The sixth byte, string[5], contains the character '\0', or simply zero.

Hint #2. When you concatenate literal strings in your program, the compiler lumps them all together into one string with a single '\0' at the end. So, when you code:
unsigned char code phrases[] = {
  "ABC"
  "DEF......."
  "XYZ......."
  };
this is exactly as if you'd written
unsigned char code phrases[] = "ABCDEF.......XYZ.......";
That gives you a single array of 24 bytes with a single '\0' at the end. As you have discovered, in order to recover what you originally thought of as three separate strings, you have to pad the strings so they are all the same length, and then you have to do some goofy address calcualtions yourself, like this:
x + line_no * MAXCHARS_ON_LINE
This is not what you want, because your strings are not all the same length, and you shouldn't have to explicitly code the low-level address calcualtions. Tsuneo hinted at a better solution, which I will expand here as ...

Hint #3. You should code your string table like this:
unsigned char code *phrases[] = {
  "Short",
  "Medium",
  "Very long"
  };
This may be confusing because it looks so much like the previous example, but it's really quite different. By coding "*phrases[]" instead of just "phrases[]" (without the *), you're telling the compiler you want an <array of pointers to char> instead of an <array of char>. Then, by separating the three strings with commas, you instruct the compiler to make three separate strings, each with its own terminating zero, instead of just one.

So two things happen here. First the compiler makes three character arrays, one for each of the three strings that you specified. The first is six bytes long and contains the characters S-h-o-r-t plus the terminating zero. The second is seven bytes long and contains the characters M-e-d-i-u-m plus a terminating zero. The third is ten bytes long and contains V-e-r-y- -l-o-n-g plus the terminating zero. The compiler puts these characters into memory wherever it feels like. Most of the time, you don't know or care exactly where.

Then the compiler also makes the phrases[] array and initializes it with pointers to the three strings. That means the phrases[] array contains three elements. The first, phrases[0], contains a pointer to the beginning of the first string. The second, phrases[1], contains a pointer to the beginning of the second string. The third, phrases[2], contains a pointer to the beginning of the third string.

As Michael pointed out, you can #define a symbol that represents the number of strings by coding something like
#define NUMBER_OF_STRINGS (sizeof(phrases) / sizeof(char *))
Now, with all that set up, you can see that the easy way to iterate through the strings is to create a for loop that iterates from 0 up to (but not including) NUMBER_OF_STRINGS. And the easy way to iterate through the characters within any one of the strings is to start at the beginning of the string and check for the terminating zero at each step. So a bit of top-down pseudocode for your program would look like this:
START main()
  REPEAT
    FOR each string from 0 to NUMBER_OF_STRINGS-1
      CALL Clear Display
      CALL Put Phrase(current string)
      CALL Word Delay      
      ENDFOR    
    FOREVER

START Put Phrase
  Start at first character in phrase
  WHILE Not yet at terminating zero
    CALL Put Character(current character)
    Advance to next character
    ENDWHILE
  END

START Put Character
  Copy character to P0
  CALL Write Enable  
  END
Hint #4.When you're experimenting with things like we're discussing here, you may be better off working on your PC than on your embedded system. The debugging tools will probably be better on the PC, the edit-compile-debug cycle will be shorter, printf() will work, etc., etc.

Hope this helps.

-- Russ


List of 54 messages in thread
TopicAuthorDate
Best way to consolidate....out of memory            01/01/70 00:00      
   isn't this the classical gotcha?            01/01/70 00:00      
   There was a hint here....            01/01/70 00:00      
      Not const            01/01/70 00:00      
         Not necessarily            01/01/70 00:00      
            Hmmm...            01/01/70 00:00      
               Hmmm, indeed            01/01/70 00:00      
               Why?            01/01/70 00:00      
                  One reason ... and the prolly the original intent            01/01/70 00:00      
                     Obviously            01/01/70 00:00      
                        Speed            01/01/70 00:00      
                           Rogue programs?            01/01/70 00:00      
                              Yes. And stupid programmers            01/01/70 00:00      
                                 True            01/01/70 00:00      
                           cases            01/01/70 00:00      
                        The Obvious...            01/01/70 00:00      
                           Fair enough            01/01/70 00:00      
                              make sure the developer doesn't do something stupi            01/01/70 00:00      
                              Const to Code EPROM or FLASH,,,            01/01/70 00:00      
                           const and volatile - for optimization            01/01/70 00:00      
                  consts in other than CODE space            01/01/70 00:00      
                     Use the extended keywords            01/01/70 00:00      
                        'const' and 'volatile'            01/01/70 00:00      
   Unreadable code!            01/01/70 00:00      
      It really was all Keils fault....;)            01/01/70 00:00      
   You don't want to start from here!            01/01/70 00:00      
      Previously, on 8052.com...            01/01/70 00:00      
      Array of string            01/01/70 00:00      
         Yes, my mistake            01/01/70 00:00      
   string concatenate            01/01/70 00:00      
      Comments            01/01/70 00:00      
         Wow......LOL            01/01/70 00:00      
            Not a C vs ASM thing            01/01/70 00:00      
               From your perspective, it may make sense            01/01/70 00:00      
      I went this direction....code padding removal?            01/01/70 00:00      
         For but one byte added to the array...            01/01/70 00:00      
         With proper ordering in source file...            01/01/70 00:00      
         Putting it all together            01/01/70 00:00      
            Spectacular Russ.....            01/01/70 00:00      
   THINK            01/01/70 00:00      
      that is surely needed            01/01/70 00:00      
      A bit easier to read?            01/01/70 00:00      
         easy to read???            01/01/70 00:00      
      typedef vs #define            01/01/70 00:00      
      I think not            01/01/70 00:00      
         Tks Russ.            01/01/70 00:00      
            THINK(ing)            01/01/70 00:00      
               ???            01/01/70 00:00      
                  Objectives.            01/01/70 00:00      
                     I beg your pardon?!            01/01/70 00:00      
                     I see            01/01/70 00:00      
   Best way to consolidate....out of memory            01/01/70 00:00      
   Why specify CODE for functions?            01/01/70 00:00      
      there is so much stuff            01/01/70 00:00      

Back to Subject List