Combined dereference and decrement in C
I need as efficient a means as possible to shift the contents of an array. I need to shift the contents of each array location one to the right and ignore the first one, so that I can write a new value there.
Here's what I have:
#define LENGTH 5
int myArray[LENGTH] = {1, 2, 3, 4, 5};
int *pa = myArray + (LENGTH - 1);
for (ushort i = 5; i > 0; i--) {开发者_运维问答
*pa = *(pa - 1);
pa--;
}
What I'd like to do is combine the two lines of the for
loop into a single operation. Something like:
*pa = *(pa--);
The result of this is undefined, however. Am I stuck with what I'm already using?
EDIT: I should have clarified that this is not the actual code I'm using, just a quick example to demonstrate the construct that I was after.
If you really need to do this, memmove
is probably going to be your best choice.
If at all possible, however, you're better off avoiding it completely. Instead of shifting the current contents to make room for the new item, just keep a pointer to the "oldest" spot in the array. When you need to add a new item, do something like *new_pos++ = new_item;
.
When you need to read your data, you'll start from new_pos+1
and read through for the next 5 items, but each time you increment you'll do % LENGTH
, so when you reach the end of the array, it "wraps around" to the beginning.
Efficiency is not measured in number of lines, so you won't gain anything by trying to "compress" the code in this manner.
If you drop the last element, then my suggestion would be to use circular buffer instead of an array, so that you won't need this shift at all. The price of element access will increase slightly, but with LENGTH equal to a power of 2 it will be very small.
memmove(3)
*pa = *(pa--);
The result of this is undefined, however. Am I stuck with what I'm already using?
Yes. Also don't let this bother you. Your compiler is smart. It'll figure out an efficient way of doing this no matter if you had this on one line or two.
If you want to do something else that is probably more optmized, use memmove instead of your loop
memmove(&myArray[1],&myArray[0],(sizeof myArray - 1)*sizeof *myArray);
Probably shifting elements in an array of integers is something that a good optimizer can take care of. But are you sure you really need to worry about the assembler instructions? Did profile and found the problem is there?
If that's the bottleneck may be there is something you can change in the algorithm... for example why do you need to do that shifting? if the buffer is a fixed size one then why not using it as a circular buffer?
精彩评论