C 中组合解引用和减量

发布于 2024-10-15 07:02:10 字数 455 浏览 7 评论 0原文

我需要一种尽可能有效的方法来移动数组的内容。我需要将每个数组位置的内容向右移动一位并忽略第一个,以便我可以在那里写入一个新值。

这就是我所拥有的:

#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--;
}

我想做的是将 for 循环的两行合并为一个操作。类似于:

*pa = *(pa--);

然而,其结果是未定义的。我是否坚持使用我已经使用的东西?

编辑:我应该澄清这不是我正在使用的实际代码,只是一个简单的示例来演示我所追求的构造。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

陈独秀 2024-10-22 07:02:10

如果您确实需要这样做,memmove 可能是您的最佳选择。

但是,如果可能的话,您最好完全避免它。无需移动当前内容来为新项目腾出空间,只需保留指向数组中“最旧”位置的指针即可。当您需要添加新项目时,请执行诸如 *new_pos++ = new_item; 之类的操作。

当您需要读取数据时,您将从 new_pos+1 开始,并通读接下来的 5 项,但每次递增时,您都会执行 % LENGTH ,因此当到达数组末尾时,它会“环绕”到开头。

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.

︶葆Ⅱㄣ 2024-10-22 07:02:10

效率不是以行数来衡量的,因此尝试以这种方式“压缩”代码不会获得任何好处。

如果您删除最后一个元素,那么我的建议是使用循环缓冲区而不是数组,这样您就根本不需要这种转变。元素访问的价格会略有增加,但当 LENGTH 等于 2 的幂时,价格会非常小。

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.

桜花祭 2024-10-22 07:02:10
*pa = *(pa--);

但是,其结果是未定义的。我是否坚持使用我已经使用的东西?

是的。也不要让这件事困扰你。你的编译器很聪明。无论您是在一行还是两行上执行此操作,它都会找出一种有效的方法来执行此操作。

如果您想做其他可能更优化的事情,请使用 memmove 而不是循环

memmove(&myArray[1],&myArray[0],(sizeof myArray - 1)*sizeof *myArray);
*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);
厌味 2024-10-22 07:02:10

也许移位整数数组中的元素是一个好的优化器可以处理的事情。但您确定真的需要担心汇编指令吗?有没有分析并发现问题在那里?

如果这是瓶颈,则可能是您可以在算法中更改某些内容......例如,为什么您需要进行这种转换?如果缓冲区是固定大小的,那么为什么不将其用作循环缓冲区呢?

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文