user1167219
user1167219

Reputation:

Using a global array like a pointer, C

Objective

I have a global TX array, and a CRC function that has to progress through this array. The CRC function should not process the first byte. To avoid this I am trying to increment the array by doing TX++. This is causing problems.

Problem

Please take a quick look at the code below:

void Send_To_Manager(void)
{   
    TX[0] = 0x55;
    TX[1] = 0x00;
    TX[2] = 0x01;
    TX[3] = 0x00;
    TX[4] = COMMON_COMMAND;     
    TX++;
    TX[5] = CRC8(TX,4);
    TX[6] = CO_RD_VERSION;
    TX += 5;
    TX[7] = CRC8(TX,1);
    TX -= 6;
    UART_TX(8);     
}

I would like to blind the CRC8 function of the first byte in the TX array. By executing TX++, I am expecting the TX[0] to be 0x00. However I am getting the error:

error: wrong type argument to increment

I am also getting the errors for TX += 5; and TX -= 6 as:

error: incompatible types in assignment

I played around with this, so instead if the function has an array such as:

void Send_To_Manager(unsigned char data[100])
{
    data++; 
}

The above works as intended.

Questions

Thank you all for your time.

Upvotes: 0

Views: 305

Answers (2)

zakinster
zakinster

Reputation: 10688

Why can I do this for Function based arrays and not Global arrays?

Arrays as function parameters are decayed to pointers, data in your example is just a local variable with type unsigned char*, you can modify it as you want. TX however is (I suppose) a static array and not a modifiable pointer.

If I do wish to do this for global arrays how can I do it?

First, make sure that's really what you want to do. Modifying the value of TX will not only affect the call to CRC8 but also all the following instructions that are dereferencing the value of TX.

As instance, TX++; TX[5] = CRC8(TX,4); is equivalent to TX[6] = CRC8(TX+1,4); TX++;.

If you don't want that side effect, don't change the value of TX, just use CRC8(TX+1,4) and CRC8(TX+5,4).

However, if that's really what you want, then you'll have to use a temporary pointer :

void Send_To_Manager(void)
{   
    char* myTX = TX;
    myTX[0] = 0x55;
    myTX[1] = 0x00;
    myTX[2] = 0x01;
    myTX[3] = 0x00;
    myTX[4] = COMMON_COMMAND;     
    myTX++;
    myTX[5] = CRC8(myTX,4);
    myTX[6] = CO_RD_VERSION;
    myTX += 5;
    myTX[7] = CRC8(myTX,1);
    myTX -= 6;
    UART_TX(8);     
}

If the increments of myTX have to be kept for the next call to Send_To_Manager, you could make it static to the function. If the modifications of TX have to be reflected in the whole program, then you have a strong architecture issue.

How would you prefer to achieve the above objective?

If the modification of TX must only impact the Send_To_Manager function, the above solutions will do fine. In other cases, you'll have to rethink your program architecture. A possible solution could be to pass the current progressing state as parameters instead of using a global state variable.

char* Send_To_Manager(char* currentTX)
{   
    currentTX[0] = 0x55;
    ...
    currentTX[4] = COMMON_COMMAND;     
    currentTX++;
    ...
    return currentTX;
}

Upvotes: 4

Thom Smith
Thom Smith

Reputation: 14086

Instead of trying to alter the array reference itself, why not:

TX[5] = CRC8(TX+1,4);
TX[7] = CRC8(TX+6,1);

Upvotes: 1

Related Questions