Advice for constant string arrays in C

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
Hello I request your help for the following:

I want to store constant data inside arrays for various purposes.

Sometimes this would be small strings, sometimes arrays with binary data.

I have tried around a lot using the C compiler for this purpose. All I was able to do so far is the following:

Rich (BB code):
#define chr_a 0x04,0b11110,0b00101,0b00101,0b11110
#define chr_b 0x04,0b11111,0b10101,0b10101,0b01110

const char s_chr_a[]={chr_a};
const char s_chr_b[]={chr_b};

const char* const alpha_chr[]={s_chr_a,s_chr_b};
At first I define the data as a sequence of 8-bit pieces.

Then I create a const string containing this sequence.

Then I put numerous similar const strings into an array.

It compiles correctly, and I used it a few times.

I can obtain single array elements easily.

But, is it possible to make the definition more easy?

Is it possible for instance to put all the sequences directly in the const char * const array?

Creating numerous const strings works but maybe it can be avoided.

Another question I have if it is possible to build an array containing 5 bit elements (for instance), and only taking up 5 bits storage space?

I have shown an excerpt of a program that I am currently working on.
Previously, I only used textual strings, but now it is data pieces only requiring 5 bits.

I do know that PICs for instance on 16F baseline store constant string data using sequences of RETLW instructions, and then 8-bit values are returned.

If there is any easy advice, please do it.

But I can also continue to use it as explained above.

Edit: The reason why define is used to put together 8bit data is that normally I use this to support various languages. Some character sets are multiple byte, so I build them using cascading define sequences.

Edit: Actually currently I convert an assembler data table to C language. So the original data looks like this:
Rich (BB code):
/*
lc_d:
 dw 4
 dw b'11111'
 dw b'10001'
 dw b'10001'
 dw b'01110'
lc_e:
 dw 4
 dw b'11111'
 dw b'10101'
 dw b'10101'
 dw b'10001'
lc_f:
 dw 4
 dw b'11111'
 dw b'00101'
 dw b'00101'
 dw b'00001'
 
Last edited:

ErnieM

Joined Apr 24, 2011
8,377
...I want to store constant data inside arrays for various purposes.

...But, is it possible to make the definition more easy?

Is it possible for instance to put all the sequences directly in the const char * const array?
There's no need to do it in two steps like that:
Rich (BB code):
const char s_chr_a[]={0x04,0b11110,0b00101,0b00101,0b11110};
const char s_chr_b[]={0x04,0b11111,0b10101,0b10101,0b01110};
Another question I have if it is possible to build an array containing 5 bit elements (for instance), and only taking up 5 bits storage space?
Again yes, first ways offhand I can think of is to create these by shoving the 5 bit words together:

Sample data:
Rich (BB code):
element  value
   0     10000
   1     10010
   2     10100
   3     10110
   4     11000
   5     11010
Now these get strung together:

Rich (BB code):
11010 11000 10110 10100 10010 10000
parsing to bytes:
Rich (BB code):
 0b110101 0b10001011 0b01010010 0b01010000
And drop into array:
Rich (BB code):
 const char Packed[] = {0b110101 0b10001011 0b01010010 0b01010000}
To access these, you need to compute the offset byte count and bit count, shift things over, all the time keeping in mind the 5 bit words can and do overlap byte boundaries so you want to use integer types (for the current byte and the next byte too) to handle the character data.

You'll probably want to make a helper program to make the arrays for you from the raw 5 bit data too.

You could probably get the compiler to do a lot of this work for you if you define a long (32 bit) structure of the 5 bit entities so you only loose 2 out of 32 bits (6%)as opposed to 3 out of 8 bits (37%).

I'm still playing with that method. I can get 5 bit elements but have yet to keep them confined to the 32 bits.
 

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
I was more asking if there is a way to put the individual strings in the strings array. The define's are required for multibyte characters, where I want to use symbolic names for individual characters.

But here I use it for font data.

Apparently on a 16f59. There is also another big problem, I was not able to find a way to deference the array pointer.

When I use:
Rich (BB code):
void process(const char* a)
{char x= *a;
the compiler tells me it can't generate code for that.

On midrange PICs and 18F, it actually works. But not on baseline.

All what's possible is to pass
Rich (BB code):
&alpha_chr[2]
instead of
Rich (BB code):
alpha_chr[2]
And that does not work for dereferencing, somehow.
I get the correct value for the individual strings, but then
the dereferencing does not work.

I have spent hours, including to examine the disassembly.

Using the MPLABX SIM is even worse, it is not able to step through the dereferencing, and jumps incorrectly.

However, on the hardware it executes without stack corruption.

I have then displayed the obtained values in binary on the LED matrix!

It seems to be a 16bit value is generated, for the memory page, and the offset.

I have even written a direct access function for the string table using big A...

at 0xF1, there is a small piece of code generated by the compiler to access string tables, I figured out parameters are passed via memory address 0x0a, and 0x0b. It is possible to access it manually, even if the generated assembly code to do so is more lengthy.

After some hours guesswork, I was able to obtain the character data!

Rich (BB code):
unsigned char get_b(const char* a,unsigned char idx)
{
    ab=a;
    ab0=ab;
    ab1=ab>>8;

    STATUS=0;
    ab2=idx;

#asm
GLOBAL _ab,_ab0,_ab1,_ab2,_x
    MOVF (_ab0),W
    movwf 0x0a
    movf (_ab1),W
    MOVWF 0x0b
    call 0xf1
    movwf (_x)

    movf (_x),W
    movwf 0x0a
    movf (_ab2),W
    addwf 0x0a,f
    movf (_ab1),w
    movwf 0x0b
    call 0xf1
    movwf _x
#endasm
    return(x);
}
The next thing is how can I do the actual scrolling?

On a larger PIC, I have copied the proportional font data into a large Array, which is then parsed line by line.

However I don't have so much buffer RAM available.

I think I need to compute the total length in bits, then increase this bits pointer, and compute the offset each time it is increased, means parse through all the character data.

It is not clear to me how I can do this efficiently, for instance if I want to keep the width adjustable (characters can have different width in terms of bytes).

Also I need to rotate the output.

Somehow I am thinking of a projection algorithm, that gets a single scan line, and then projects it to the display memory.

Eventually, it is way too much effort to implement it on a 16f59.

Even if it is possible from the viewpoint of memory footprint- there are about 30% program memory used up now, including the font data.

I should use a more powerful PIC, simply, and put the computed scroll bitmap in a larger RAM buffer. But, since the scrolling does only happen a few times/second, it should be possible to process all the font data, even if this takes 10k or 20k inctruction cycles.

I have read through the compiler manual there is not much information about strings at all. There is no information that apparently on the baseline PICs, dereferencing is not possible, only to use the & operator. But then the final dereferencing on the individual character level simply does not work!

Using big A is really a final resort.
 

Attachments

THE_RB

Joined Feb 11, 2008
5,438
ErnieM, I think he's talking about using a 2 dimensional array?

If these are for text strings I think that's an ugly way of doing it. I would just put all the text strings into one array, then use 2 indexing variables to select which text string and which character.

It's a good goal with embedded coding to keep it simple in design, then work from there. Some array and pointer techniques from Windows programming etc are not a good idea in an embedded design.
 

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
And how would you do that in C?

How would you know the index value?
It could be more than 256 bytes.

By the way I have done it like that in assembler, used a relocation table with 256 bytes for the whole ASCII, pointing into the string table.

I have now a SUPER 16F59- with 2K RAM buffer.

Otherwise these chips would never see opportunity to be used.

Yes there are serial SRAM chips now.

But the wires for 256 bytes are not so many...just a few.

If you know any good way to use constant tables in XC8, let me know.

Reloctation/indexing tables I had sufficienct in assembler,
was quite a hassle for nested LCD menu's.
 

Attachments

ErnieM

Joined Apr 24, 2011
8,377
I was more asking if there is a way to put the individual strings in the strings array. The define's are required for multibyte characters, where I want to use symbolic names for individual characters.

But here I use it for font data.
I'm not following what you want.

Apparently on a 16f59. There is also another big problem, I was not able to find a way to deference the array pointer.

When I use:
Rich (BB code):
void process(const char* a)
{char x= *a;
the compiler tells me it can't generate code for that.
You would need to show an example. This works for me:
Rich (BB code):
#include <htc.h>

const char Str[] = "ABCD";
void process(const char* a);

main(void)
{
  process(&Str);
  process(&Str[0]);
  process(&Str[1]);
  process(&Str[2]);
  process(&Str[3]);
}  

void process(const char* a)
{
  char x = *a;
}

It builds without warning and the simulator has no trouble telling me the value of x.


I could not follow the remainder of your post. Please being up a single problem at a time to discuss.
 

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
I don't think I would want to craft indexing for string tables manually.

The following works quite well, larger than 256 bytes no problem.

Rich (BB code):
const char* const months_jp[]=
{s_ichigatsu,s_nigatsu,s_sangatsu,\
 s_shigatsu,s_gogatsu,s_rokugatsu,s_shichigatsu,\
 s_hachigatsu,s_kugatsu,s_juugatsu,s_juuichigatsu,s_juunigatsu};
const char* const months_jp_lt[]=
{"ichigatsu","nigatsu","sangatsu","shigatsu","gogatsu","rokugatsu",\
 "shichigatsu","hachigatsu","kugatsu","juugatsu","juuichigatsu","juunigatsu"};
const char* const months_en[]=
{"January","February","March","April","May","June","July",\
 "August","September","October","November","December"};
const char* const months_en_sh[]=
{"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"};
just for the baseline PICs, the compiler is not able to create code for dereferencing.

Maybe there is a way to do it in C. It is not clear to me why the compiler can't do it.

And you see as well, the english strings I spell directly in the strings array.
 
Last edited:

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
I'm not following what you want.



You would need to show an example. This works for me:
Rich (BB code):
#include <htc.h>

const char Str[] = "ABCD";
void process(const char* a);

main(void)
{
  process(&Str);
  process(&Str[0]);
  process(&Str[1]);
  process(&Str[2]);
  process(&Str[3]);
}  

void process(const char* a)
{
  char x = *a;
}

It builds without warning and the simulator has no trouble telling me the value of x.


I could not follow the remainder of your post. Please being up a single problem at a time to discuss.
OK I will try your sample for 16F59.

However, I ask how to dereference arrays in the form const char* const xxxx[]={str1,str2,str3};

I have given example code above, that works well on midrange 16F, and 18F.

On the baseline I have done it manually using big A.

I am trying to get along with the project, so I have mentioned additional issues. But I have solved it by adding a 2K RAM.

This project is mainly for my own entertainment, and to improve my programming skills.

I know it could be done simply using a 18F (for instance).
 

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
OK I tried, using the 16f59, MPLABX 1.30 + XC8 1.01

I get a zero value.

Maybe I am doing something wrong, or it needs to be spelled slightly differently?

2 screenshots attached. I get a virtual address for the string table,
but the value I obtain from dereferencing is zero.
 

Attachments

ErnieM

Joined Apr 24, 2011
8,377
It's hard to tell from screen shots as what is being moused over isn't clear. Plus it only can show one variable. Did MPLABX do away with the watch window? That can show an explicit set of variables.

What did process return? Did it work correctly?

It does for me, under MPLAB 8.84/CX8v1.00

Rich (BB code):
#include <htc.h>

const char Str[] = "ABCD";
char process(const char* a);

main(void)
{
  char XX;
  XX = process(&Str[0]);
  XX = process(&Str[1]);
  XX = process(&Str[2]);
  XX = process(&Str[3]);
}  

char process(const char* a)
{
  char x = *a;
  return x;
}
 

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
Have you used 16f59?

I can only obtain zero.

There are also various issues using MPLABX. I always had issues with MPLAB, the PICKIT2, and sometimes also PICKIT3.

-Make sometimes will freeze and needs to be terminated with task manager
-Menus sometimes disappear when I hover the topics. This has improved with 1.30, but is still present

-Memory areas are apparently mixed up, assembler code that is generated simply stops inbetween at 3ff. I fixed that with putting the main function at 0x400.

-I had serious troubles with my assembler containing routine, until I have now also put it at 0x0050 absolutely.

-There have been various issues with putting data variables into memory, even if more than 50% are left. I also solved that by putting some variables into page zero absolutely.

Altogether it is a nightmare to use the 16f59.
I still can't use the debugger (MPLAB SIM) properly, it even has issues with the TRIS instruction.

But I have not tried maybe it is better now having some stuff at absolute addresses.

Using 16F midrange or 18F, none of the serious issues above is present. Except the MAKE sometimes will freeze.

I tried to run MPLAB SIM again, it seems to be mixing up things when the string routine is called. The PCL will contain 0x82, that is also the first entry from the string table. However I can't trace into it (single step).

But I made letters A-D working now, I can store them into the RAM, read back, and display them. I give up for now, it's 4.29AM here

I wonder if I can make this program working as intended...having all these issues.

And, if you can maybe test for a const char* const[] string table?

The entries from the string table were actually returned in the hardware program, but after that, I have not been successful to do the second deferencing, to get individual bytes from the string. I tried hours yesterday,
including to display things in binary on the small LED matrix display.

Rich (BB code):
unsigned char get_b(const char* a,unsigned char idx) @ 0x050
{
  // ab=a;
  // ab0=ab;
  // ab1=ab>>8;

    ab0=((unsigned int)(a));
    ab1=((unsigned int)(a))>>8;

    STATUS=0;
    ab2=idx;

      
#asm
 GLOBAL _ab,_ab0,_ab1,_ab2,_x

    MOVF (_ab0),W
    movwf 0x0a
    movf (_ab1),W
    MOVWF 0x0b
    call 0xf1
    movwf (_x)

    bcf (_STATUS),5
         bcf (_STATUS),6
    incf (_ab0),f
    MOVF (_ab0),W
    movwf 0x0a
    movf (_ab1),W
    MOVWF 0x0b
    call 0xf1
    movwf (_x2)

    bcf (_STATUS),5
         bcf (_STATUS),6
    movf (_x),W
    movwf 0x0a
    movf (_ab2),W
    addwf 0x0a,f
    movf (_x2),w
    movwf 0x0b
    call 0xf1
   movwf (_x)

             bcf (_STATUS),5
         bcf (_STATUS),6
#endasm

  //  display_data[0]=(x>>5)&0x1f;
  //  display_data[1]=x&0x1f;
  //  display_data[2]=(x2>>5)&0x1f;
  //  display_data[3]=x2&0x1f;
    return(x);
}
This is what I am using now, not that I would be very fond of it.
 

WBahn

Joined Mar 31, 2012
30,071
Another question I have if it is possible to build an array containing 5 bit elements (for instance), and only taking up 5 bits storage space?
Have you looked into bit fields? I don't know if that will do what you want, nor do I know if it is a practical approach on a MCU or with compiler's that target an MCU.
 

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
Have you looked into bit fields? I don't know if that will do what you want, nor do I know if it is a practical approach on a MCU or with compiler's that target an MCU.
yes I saw this in various C books, on websites, inside manuals etc.

But I did not yet feel sufficient enough to attempt to cram large amounts of elements into an array, using said bitfields.

The compiler somehow would generate code (means AND masks) to aquire the bits? And if I load them into an 8 bits char, also clear it before loading?

I will read through it again.

The assembler construct works well enough in terms of stability, seems to be I am doing everything required (manually) to read from the compiler generated string tables.

I still don't understand what is the reason why the compiler can not do this for me like on midrange and 18F.

So if I have some element in the form const char* const data1[]={"STR1","STR2"};

I can pass data1[0] (for instance) to a function having the parameter form void func_a(const char* a)

Then in turn I can dereference using *a, which gives me the first character from string 1 (element 0).

After that I can simply increment a as pointer.

On the baseline, all what is possible to compile is to pass &data1[0] to the said function.

I have examined the values obtained all the way through using binary display on the small LED matrix.

The string tables use a high word of 0x80 for page 0, 0x81 for page 1, etc.,
then followed by the index inside the same page for the element. *actually first the high word, then the index, see attach.

The (compiler generated) function (or code piece) excepts two parameters, the page number OR'ed with 0x80, as well the index.

The final string table only contains a data element!

I have also tried to do a second dereferencing (passing the address with the & operator), however it simply does not work!

I have spent hours on this. As I wrote above on midrange and 18F, I simply pass the element literally. Some kind of built-in dereferencing?

I have again created code to display the obtained pointer value (&alpha_chr[0]), and to display it on the LED matrix. It is a bit lengthy, however, it does not work inside the debugger.

I can successfully obtain the entries from the first level string table.

So if I spell &alpha_chr[0], actually I obtain a 16-bit virtual address.
This address in turn is passed to the compiler string fetcher.

I have taken a screen shot from the first level table.

And the main function is included, with some code deactivated.

I get (on the LED matrix) flipping through the virtual addresses for the first level string table.

So, this is 0x8081, 0x8083, 0x8085, etc.

However, I need to do a second deferencing.

Since the data is in the form const char* const data1[]

I have not yet been successful with this!

Rich (BB code):
void main(void) @ 0x400
{
    const char* curr_chr_size2_ptr;
    unsigned char curr_chr_size2,disp2,disp3;
    unsigned int disp;

    ConfigureOscillator();
    InitApp();

    tsize=0;
    for(i=0;i<26;i++){tsize+=get_b(&alpha_chr,0);}

    chr_curr=0;
    while(1)
    {
        if(TMR0>0x80)
        {TMR0=0;
         refresh();
         scrollstep_ctr++;
        }

        if(scrollstep_ctr>200)
        {
            scrollstep_ctr=0;
            do_scroll();

            curr_chr_size=get_b(&alpha_chr[chr_curr],0);

            curr_chr_size2_ptr=&alpha_chr[chr_curr];
            curr_chr_size2=*curr_chr_size2_ptr;

            disp=(unsigned int)(curr_chr_size2_ptr);
            disp2=((unsigned int)(disp))>>8;
            disp3=((unsigned int)(disp));

    display_data[0]=(disp2>>5)&0x1f;
    display_data[1]=disp2&0x1f;
    display_data[2]=(disp3>>5)&0x1f;
    display_data[3]=disp3&0x1f;

    display_data[4]=(curr_chr_size2>>5)&0x1f;
    display_data[5]=curr_chr_size2&0x1f;

   //         for(i=0;i<5;i++){store_ram(16+i,0);
   //         display_data[display_pos]=0;}

   //         for(i=0;i<curr_chr_size;i++)
   //         {store_ram(16+i,get_b(&alpha_chr[chr_curr],i+1));}

            chr_curr++;
            if(chr_curr>25)chr_curr=0;
  
//            for(i=0;i<curr_chr_size;i++)
  //          {display_data[display_pos]=load_ram((16+(curr_chr_size-1))-i);}
        }
    }
}


The refreshing code for the matrix is not included.

Relevant are these lines:
Rich (BB code):
    curr_chr_size2_ptr=&alpha_chr[chr_curr];
            curr_chr_size2=*curr_chr_size2_ptr;
I want to obtain byte 0 from element 0, which is the size of the element, which I have stored manually in every element.
After that, the data. So I also need to increment this pointer.

I guess if I would pass the element without the &qualifier,
one level of dereferencing already will be done.

How can I do the 2-level dereferencing?
What are the required typcasts?
Is it possible at all?

It does not matter if it is complicate to spell.
I would prefer to do it in C, instead of using assembler.

I am also sorry it is a bit complex. It is way over a forum thread maybe to include documentation of all steps that I have taken, screen shots from all the memory, the string fetcher etc.

If you don't follow/don't understand enough, I can supply more information.
 

Attachments

WBahn

Joined Mar 31, 2012
30,071
I still don't understand what is the reason why the compiler can not do this for me like on midrange and 18F.
My guess is that it is a simply matter of the compiler seeing a certain operation and saying, "for this pattern, I need to generate this sequence of assembly instructions" and, for base parts, the resources needed to support that sequence simply aren't there. That doesn't mean that the pattern can't be implemented, just that the compiler hasn't been taught how within the resource constraints.
 

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
So maybe something like
Rich (BB code):
const char* lvl2= (const char*)(*lvl1);
can do the job?

If lvl1 is
Rich (BB code):
const char* lvl1=&alpha_chr[0];
.

I made a video showing the output of above code on the LED matrix.
http://youtu.be/KQib1_PAJdY

Bit0 is at the top, towards Bit7 at the bottom.

The first two lines are displaying 16bits value of the pointer I obtained, see post #14.
The third line suggests to be indeed the index part again of a virtual pointer.

Hampering to my efforts really is the fact baseline code can not execute correctly in MPLABX SIM.
I use latest v. 1.30
Even the TRIS instruction causes the simulator to stop, I get around this by changing the PC manually.
The numerical value obtained for the string pointer is incorrect, then after this when the string fetcher is called, the Simulator will enter an endless loop.

Only when I have done the typecasts to display 16 bits value on real hardware (LED display), I have indeed gained more understanding how strings are used/generated etc. by PIC C.

I also made a video stepping through a small piece of code, where I obtain the 16bit virtual address.
All I get is zero...and this is apparently incorrect. It works in real hardware.
The Simulator seems to have a problem with the typecasts.
http://youtu.be/ZvwMguFpDPI
 
Last edited:

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
My guess is that it is a simply matter of the compiler seeing a certain operation and saying, "for this pattern, I need to generate this sequence of assembly instructions" and, for base parts, the resources needed to support that sequence simply aren't there. That doesn't mean that the pattern can't be implemented, just that the compiler hasn't been taught how within the resource constraints.
Yes seems to be some kind of top-level dereferencing is built-in as compiler ability, but not for baseline.

1. It can be done in assembler
2. Maybe there is a way to do it in C, I have obtained some new ideas. Also to display the 16-bit values, to obtain them at all, I had to do typecasting all the way through.

There is no sufficient documentation about this in the compiler manual.

Maybe there are some (PIC specific) books with such topics?

However I don't want to have a stack of beginner's books around, with mostly irrelevant information. Books I have for Windows programming...mostly 3D graphics stuff.

I would consider to buy one book if it teaches me some professional aspects of PIC micro C.
 

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
Ugly isn't it?

Rich (BB code):
curr_chr_size2_ptr=&alpha_chr[chr_curr];
curr_chr_size2=*curr_chr_size2_ptr;
lvl2=   ((const char*)\
         (\
         (*curr_chr_size2_ptr)\
         |\
         (\
         ((unsigned int)(*(curr_chr_size2_ptr+1)))<<8)\
         )\
         );

curr_chr_size2=*((const char*)(lvl2));
Apparently the compiler is not intelligible enough to load a 16bit value from the string table. Even if the (const char*) typecase is used, only 8bits are loaded. So it is required also to load the high byte, which is stored at the next address inside the string table.

Isn't there an easier way to do this? Or is it uncommon to use jagged arrays inside PIC C? Or is it that normally I would have to use determined indexing? Means fixed length strings?

A little better:
Rich (BB code):
        lvl22=*(curr_chr_size2_ptr+1)<<8;
        lvl22<<=8;
        lvl22|=*(curr_chr_size2_ptr);
        lvl2=(const char*)lvl22;
All the code needed to get the pointer to the first string character from a string table in the format
const char* const[]={"str1","str2"}

Rich (BB code):
     curr_chr_size2_ptr=&alpha_chr[chr_curr];
     lvl22=*(curr_chr_size2_ptr+1);
     lvl22<<=8;
     lvl22|=*(curr_chr_size2_ptr);
     lvl2=((const char*)(lvl22));
     curr_chr_size2=*lvl2;
 

Attachments

Last edited:

WBahn

Joined Mar 31, 2012
30,071
Isn't there an easier way to do this? Or is it uncommon to use jagged arrays inside PIC C?
What is a "jagged array"?

When you say:

const char* constr[]={"str1","str2"};

You are saying that you have an array consisting of two pointers. One pointer points to the first character of the first string and the second pointer points to the first character of the second string. Nothing 'jagged' about it.
 

ErnieM

Joined Apr 24, 2011
8,377
I still have no dea what you are trying to accomplish and what is the issue.

It appears you are having problems using string pointer arrays for the PIC16F59. These work for me just fine using the MPLAB (not X) simulator for the PIC16F59 device:


Rich (BB code):
#include <htc.h>  // for PIC16F59
const char* Strings[]={"a1","bb22","ccc333"}; // define "jagged" array
char Buffer[10];
void FillBuffer(char* Dest,const char* Source);

main(void)
{
  FillBuffer(Buffer, Strings[0]);
  FillBuffer(Buffer, Strings[1]);
  FillBuffer(Buffer, Strings[2]);
}  

void FillBuffer(char* Dest, const char* Source)
{
  while ( (*Dest++ = *Source++) != 0); 
}
After each call to FillBuffer the contents of Buffer are inspected in the watch window and contain the expected characters.
 

Thread Starter

takao21203

Joined Apr 28, 2012
3,702
Doh.

I clearly wrote that this form does not compile.
I have to use the & operator.

The reason why it compiles on your machine are unknown to me.

Also jagged = javascript array
http://www.java2s.com/Code/CSharp/Collections-Data-Structure/Demonstratejaggedarrays.htm

means multidimension array. Not to implement a definition in terms of of PIC programming topics. Only for some kind of reference. There are abilities to deal with arrays built into javascript.


I also wrote that it does compile for 16F midrange and 18f.

In addition the issue is solved, as I figured out how it can be done in C.

Remember that pointer could be obtained from anywhere, or where the information can be found that I always can use the automatic dereferencing?

I have now gained understanding how the compiler is dealing with constant data on the 16F.

Thank you for your help.
 
Top