0

I have written this code but on compilation i'm getting message "invalid expression" for the following statement

unsigned short address[] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/*array is being   initialized here.no problem uptil here.*/
unsigned short rowHead=3;
unsigned short colHead=0;
unsigned short rowTail =0;
unsigned short colTail =0;
unsigned short foodx;
unsigned short foody;
unsigned short turn=0;
void gameOver()
{
unsigned short i=0;
address[] ={0b10000001,0b01000010,0b00100100,0b00011000,
            0b00011000,0b00100100,0b01000010,0b10000001};
/*this is the line where compiler complaints as invalid expression.*/
while(1)
    {
    PORTD &=~(1<<i);
    PORTB =address[i];
    delay_ms(5);
    PORTD |=1<<i;
    i%8;
    }
}
shafeeq
  • 141
  • 1
  • 3
  • 14
  • C doesn't support `0b` as a prefix for binary numbers. Or any other base, really. – unwind Jun 22 '13 at 13:21
  • What base are you speaking? I know that C support this bases: `0x` = 16-base and `0` = 8-base by std. – The Mask Jun 22 '13 at 13:27
  • yeah 0b as well as 0x both are working – shafeeq Jun 22 '13 at 13:29
  • 1
    0b for binary constants is an extension which seems to be supported in a number of compilers, including gcc and clang. See qrdl's answer to [this question](http://stackoverflow.com/questions/2611764/can-i-use-a-binary-literal-in-c-or-c). – Nigel Harper Jun 22 '13 at 13:34
  • "address[] =" is valid only for definition, remove the "[]" when assigning. – kfsone Jun 22 '13 at 18:38

3 Answers3

8

You can only do that when declaring and assigning a variable at the same time. You cannot do so afterwards. You could create another variable and assign that, though:

unsigned short address2[] = { 0b10000001,0b01000010,0b00100100,0b00011000,
                              0b00011000,0b00100100,0b01000010,0b10000001 };
address = address2;

This might make problems with sizeof(address) afterwards; if you need that it's probably better to just use another variable.

Joey
  • 344,408
  • 85
  • 689
  • 683
  • Err... please, how is `address` declared in this case? As for the declaration in the OP this won't work. – alk Jun 22 '13 at 13:49
  • `address` should be an `unsigned short *` from what I can see and know. I didn't try to compile the code, though. – Joey Jun 22 '13 at 13:54
  • Ahok, fine ... thanks - it might be a good idea to add this to the answer though, as it's not obvious from the OP. – alk Jun 22 '13 at 13:56
  • Changing the OP's variable from an array to a pointer is pretty extreme. Without seeing the rest of the code this is potentially very bad advice. – sh1 Jun 22 '13 at 18:33
0

If you want to assign a whole array in one go (and not just get a reference to it) you could wrap it into a struct like this:

#include <stdlib.h>
#include <stdio.h>

#define ADDRESS_DEF {1, 2, 3}

typedef struct 
{
  unsigned short _[sizeof((int[]) ADDRESS_DEF) / sizeof(*((int[]) ADDRESS_DEF))];
} address_t;

address_t address_def = {ADDRESS_DEF};

int main()
{
  address_t address = address_def;

  size_t size = sizeof(address._) / sizeof(*address._);

  for (size_t s = 0; s < size; ++s)
    printf("address #%zd = %uh\n", s, address._[s]);


  address = (address_t) {{4, 5, 6}};

  for (size_t s = 0; s < size; ++s)
    printf("address #%zd = %uh\n", s, address._[s]);

  return 0;
}
alk
  • 69,737
  • 10
  • 105
  • 255
0

Within the gameOver() function, you're trying to assign all of the values of an array with a single assignment. This isn't legal. You would normally use memcpy() or a loop to set the values one by one. This is often done by declaring and initialising a temporary array and copying the contents into the array you want to re-initialise.

If you do copy from a temporary array, it's best practice to make it static and const, to inform the compiler that you don't mean to write to it and you don't need to see it re-initialised every time you execute the code. Like so:

static const unsigned short tmp[] = { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 };
memcpy(address, tmp, sizeof(address));

The name of your destination variable is a bit dubious, though. Typically if something was called address I would expect it to be a pointer. If you meant it to be a pointer, and if you don't mean to change the values that address points to, then your assignment would be nearly legal.

unsigned short const *address;
/* ... */
static const unsigned short tmp[] = { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 };
address = tmp;

Making tmp[] const (and making address a pointer to const) allows the compiler to put the data in a read-only segment, which might mean ROM on an embedded system.

If there's some hidden complexity to your code, not shown in the question, and this stops you from making address a pointer to const, then things would be complicated. If you changed address to a pointer and went ahead with modifying what it points at, this might have unintended consequences.

However, the code that is shown does not look like it needs copying, and elements need be no larger than a char to hold all their values. The temporary array could just as easily be the working array:

void gameOver()
{
    unsigned short i=0;
    static const unsigned char tmp[] = { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 };

    while(1)
    {
        PORTD &=~(1<<i);
        PORTB = tmp[i];
        delay_ms(5);
        PORTD |=1<<i;
        i%8;  /* <-- this has no effect, I think you meant i=(i+1)%8; */
    }
}
sh1
  • 4,324
  • 17
  • 30