迭代从 N 到 0(含)的所有值以获得无符号值

发布于 2024-12-20 11:21:20 字数 310 浏览 4 评论 0原文

我有这段代码适用于常规有符号整数,我正在尝试编写一个与 size_t 一起使用的等效版本(就像现在开始和计数是整数,我需要它们是 size_t):

int count,start;
for (start = (count-2)/2; start >=0; start--)
{
     someFunction( x, start, count); // x is to illustrate function has other parameters
}

我觉得这样代码对于一个非常简单的解决方案来说足够简单,但我画了一个空白。

I have this code that works fine for regular signed integers that I am trying to write an equivalent version that will work with size_t (as in that as of now start and count are ints and i need them to be size_t) :

int count,start;
for (start = (count-2)/2; start >=0; start--)
{
     someFunction( x, start, count); // x is to illustrate function has other parameters
}

I feel like this code is straight forward enough for a really simple solution but I am drawing a blank.

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

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

发布评论

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

评论(4

青衫负雪 2024-12-27 11:21:20

你可以这样重写它:

start = count/2;
while (start > 0){
    start--;
    someFunction( x, start, count);
}

否则,我能想到的唯一其他选择是在有符号和无符号之间进行一些非标准兼容的转换...或者用 ~(size_t)0 做一些事情...

以下是一些不符合标准的替代方案:

for (start = (count-2)/2; (ssize_t)start >= 0; start--)
{
     someFunction( x, start, count);
}

for (start = (count-2)/2; start != ~(size_t)0; start--)
{
     someFunction( x, start, count);
}

You could rewrite it like this:

start = count/2;
while (start > 0){
    start--;
    someFunction( x, start, count);
}

Otherwise, the only other option I can think of is to do some non-standard compliant casting between signed and unsigned... or to do something with ~(size_t)0...

Here are some non-standard compliant alternatives:

for (start = (count-2)/2; (ssize_t)start >= 0; start--)
{
     someFunction( x, start, count);
}

for (start = (count-2)/2; start != ~(size_t)0; start--)
{
     someFunction( x, start, count);
}
渔村楼浪 2024-12-27 11:21:20
size_t cnt, start;
for (start = cnt/2; start-- > 0; ) { ... }
  • if cnt=0 : start 将从零开始,循环代码将永远不会执行;循环结束后,start 将为 (size_t)-1
  • if cnt=1 :相同
  • if cnt >=2 :循环代码将至少执行一次;在第一次迭代中,start 将为 (cnt/2)-1;最后一次迭代的开始值为 0;循环开始后将是 (size_t)-1

编辑如果OP确实想为 cnt=1 循环一次,则需要一个三元组:

for (start = (cnt==1) ? 1 : cnt/2; start-- > 0; ) { ... }
size_t cnt, start;
for (start = cnt/2; start-- > 0; ) { ... }
  • if cnt=0 : start will start at zero, the loop code will never execute; after the loop, start will be (size_t)-1
  • if cnt=1 : the same
  • if cnt >=2 : the loop code will execute at least once; on the first iteration, start will be (cnt/2)-1; on the last iteration start will be 0; after the loop start will be (size_t)-1

EDIT if the OP really wants to loop once for cnt=1, a ternary is necessary:

for (start = (cnt==1) ? 1 : cnt/2; start-- > 0; ) { ... }
森罗 2024-12-27 11:21:20

只使用减一的值怎么样?

size_t start_plus_one;
for (start_plus_one = (count-2)/2+1; start_plus_one >=1; start_plus_one--)
{
     someFunction( x, start_plus_one-1, count); // x is to illustrate function has other parameters
}

What about just using a value off by one?

size_t start_plus_one;
for (start_plus_one = (count-2)/2+1; start_plus_one >=1; start_plus_one--)
{
     someFunction( x, start_plus_one-1, count); // x is to illustrate function has other parameters
}
韶华倾负 2024-12-27 11:21:20

您可以修复原始代码中的结束条件。 -1/2 在 C99 中保证为 0,这使得循环体执行一次,因此如果仍然需要,您可能需要特别对待 count == 1类型未签名后的行为。

size_t count = something;
if (count > 1) {
    for (size_t start = (count-2)/2; start != SIZE_MAX; --start) {
        someFunction(x, start, count);
    }
}

这是可行的,因为我们知道 start 的初始值不可能是 SIZE_MAX,因为除以 2 后不存在 size_t 的值SIZE_MAX

对于更一般的循环,可能需要从 SIZE_MAX 开始,一直到 0(含),显然我们不能在循环体之前执行退出检查,因为我们希望循环体执行一次对于 size_t 的每个值,因此没有可以退出的值。为了允许这种情况:

size_t count = SIZE_MAX, start = SIZE_MAX;
do {
    someFunction(x, start, count);
} while (start-- != 0);

在所有情况下,SIZE_MAX 都可以替换为 -1,它更通用,因为它会转换为每个无符号类型的最大值,但是导致令人困惑的问题

You can fix the end condition from your original code. -1/2 is guaranteed to be 0 in C99, which makes the loop body execute once, so you might have to treat count == 1 specially if that's still the required behavior once the types are unsigned.

size_t count = something;
if (count > 1) {
    for (size_t start = (count-2)/2; start != SIZE_MAX; --start) {
        someFunction(x, start, count);
    }
}

This works because we know that the initial value of start cannot possibly be SIZE_MAX, because there is no value of size_t that when divided by 2 yields SIZE_MAX.

For more general loops, that might need to start at SIZE_MAX and go all the way down to 0 inclusive, clearly we cannot perform the exit check before the loop body, because we want the loop body to execute once for every value of size_t, so there is no value on which we can exit. To allow for that case:

size_t count = SIZE_MAX, start = SIZE_MAX;
do {
    someFunction(x, start, count);
} while (start-- != 0);

In all cases, SIZE_MAX can be replaced with -1, which is more generic in that it converts to the max value of every unsigned type, but leads to confused questions.

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