C语言 如何在 C 中的 for (;;) 循环中初始化多个变量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3348766/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:01:04  来源:igfitidea点击:

How do I initialize several variables in a for (;;) loop in C?

cloopsinitializationfor-loop

提问by bodacydo

I thought one could initialize several variables in a forloop:

我认为可以在for循环中初始化几个变量:

for (int i = 0, char* ptr = bam; i < 10; i++) { ... }

But I just found out that this is not possible. GCC gives the following error:

但我刚刚发现这是不可能的。GCC 给出以下错误:

error: expected unqualified-id before 'char'

错误:'char' 之前的预期不合格 ID

Is it really true that you can't initialize variables of different types in a forloop?

真的不能在for循环中初始化不同类型的变量吗?

回答by Potatoswatter

You can (but generally shouldn't) use a local struct type.

您可以(但通常不应该)使用本地结构类型。

for ( struct { int i; char* ptr; } loopy = { 0, bam };
      loopy.i < 10 && * loopy.ptr != 0;
      ++ loopy.i, ++ loopy.ptr )
    { ... }


Since C++11, you can initialize the individual parts more elegantly, as long as they don't depend on a local variable:

从 C++11 开始,您可以更优雅地初始化各个部分,只要它们不依赖于局部变量:

for ( struct { int i = 0; std::string status; } loop;
      loop.status != "done"; ++ loop.i )
    { ... }

This is just almost readable enough to really use.

这几乎是可读的,足以真正使用。



C++17 is scheduled to address the problem with structured bindings:

C++17 计划解决结构化绑定的问题:

for ( auto [ i, status ] = { 0, ""s }; status != "done"; ++ i )

However, the detailed feature set and syntax are still in flux.

但是,详细的功能集和语法仍在不断变化。

回答by Matthew Flaschen

It's true that you can't simultaneously declare and initialize declarators of different types. But this isn't specific to for loops. You'll get an error if you do:

确实,您不能同时声明和初始化不同类型的声明符。但这不是特定于 for 循环的。如果你这样做,你会得到一个错误:

int i = 0, char *ptr = bam;

too. The first clause of a for loop can be (C99 §6.8.5.3) "a declaration" or a "void expression". Note that you can do:

也。for 循环的第一个子句可以是(C99 §6.8.5.3)“声明”或“无效表达式”。请注意,您可以执行以下操作:

int i = 0, *j = NULL;
for(int i = 0, *j = NULL;;){}

because iand *jare both of type int. The exact syntax for a declaration is given in §6.7

因为i*j都是 类型int。声明的确切语法在 §6.7 中给出

回答by Axel Gneiting

If you really need the variables to stay in the scope of the loop you could write

如果你真的需要变量留在循环的范围内,你可以写

{ char* ptr = bam; for (int i = 0; i < 10; i++) { ... } }

It's a bit ugly, but works.

这有点难看,但有效。

回答by Gary

Try this:

尝试这个:

int i;
char* ptr;
for (i = 0, ptr = bam; i < 10; i++) { ... }

回答by Ladon

You can also do:

你也可以这样做:

for (int i = 0; i < 10; i++) {
    static char* ptr = bam;
}

回答by Karel Petranek

According to http://linuxsoftware.co.nz/cppgrammar.html#for-init-statementyou can get only simple declaration or an expression (which is not permitted to contain declaration) in the for-init statement. That means the answer is no (if I analyzed the BNF correctly :) )

根据http://linuxsoftware.co.nz/cppgrammar.html#for-init-statement,您只能在 for-init 语句中获得简单的声明或表达式(不允许包含声明)。这意味着答案是否定的(如果我正确分析了 BNF :))

回答by nobody

I think the languages they teach you kids these days are meant to handcuff you and rot your brain so you just be quiet and put the lego blocks together in the very limited form in which they are meant to snap together so you build mediocre stuff. The beauty of C is that you can follow the rules, and in a clever way, to get what you want. Here is how you write this loop with extra initialzers. Here is a working example that shows you how to bridge an extended loop onto a first. You use the first to pirate its variables and they remain in scope. You use a dummy variable to make the outer loop run once. A smart compiler will note the fact and nuke the loop with the loop unroller. So for you it is just benefit. The second array then uses some variables from the first declaration and the second declaration and runs to completion. It is a trivial example just meant you to be able to understand how to do it without the heavy handed move of throwing in some scoping. Because this technique can be used with macros when written like this in order to create beautiful next-generation like structure enumeration, like "for value in array do", of which I have many.

我认为这些天他们教给你孩子的语言是为了给你戴上手铐并腐蚀你的大脑,所以你只是安静地把乐高积木以非常有限的形式放在一起,在这种形式下,它们可以拼凑在一起,这样你就可以建造平庸的东西。C 的美妙之处在于你可以遵循规则,并以一种聪明的方式,得到你想要的。以下是如何使用额外的初始值设定项编写此循环。这是一个工作示例,向您展示如何将扩展循环桥接到第一个循环上。你使用第一个来盗版它的变量,它们仍然在范围内。您使用虚拟变量使外循环运行一次。一个聪明的编译器会注意到这个事实,并用循环展开器破坏循环。所以对你来说这只是好处。然后第二个数组使用第一个声明和第二个声明中的一些变量并运行到完成。这是一个微不足道的例子,只是意味着您能够理解如何做到这一点,而无需投入一些范围。因为这种技术可以在这样编写时与宏一起使用,以创建漂亮的下一代结构枚举,例如“for value in array do”,我有很多。

#include "stdio.h"
int
main(int argc, char **argv)
{
    const int max=7;
    const char *array[7] = {
    "hello","you","kids","who","don't","know","malloc\n"
    };

    for(int i=0,count=max,$=1;$;$=0)
    for(const char **p=array;count<max;i++)
    {
        printf("%s ",p[i]);
    }
}

There is nothing missing here. This technique of for loop joining with a one shot for loop has been used to embed in a call to get an enumerator for this hash object, and start the enumeration, to get the values extracted for the key and value, and also by convenience create them as void pointers for the user, he just has to name them. Then they are filled, and the enumeration will continue until all keys and values are done. If the user breaks in the iteration the whole cascade of oneshot forloops will fall apart as we'd want because they're probably not even there since they were constructed with simple const ops that the compiler can see will unroll the loop. So basically it lets you extend the syntax to do things like this with no penalty.

这里没有任何遗漏。这种将 for 循环与一次性 for 循环结合的技术已被用于嵌入调用以获取此哈希对象的枚举数,并开始枚举,以获取为键和值提取的值,并且还方便地创建它们作为用户的空指针,他只需要命名它们。然后它们被填充,枚举将继续直到所有的键和值都完成。如果用户在迭代中中断,整个 oneshot forloops 级联将像我们希望的那样分崩离析,因为它们可能甚至不存在,因为它们是用编译器可以看到的简单 const 操作构建的,它将展开循环。所以基本上它可以让你扩展语法来做这样的事情而不会受到惩罚。

But you need to know a bit of C and at least have your head out of the robot box that the schools are putting them in these days with these toy languages.

但是你需要知道一点 C 并且至少让你的头脑走出学校现在用这些玩具语言把它们放在机器人盒子里的东西。