我曾认为可以在一个 for
循环中声明多个变量:
for (int i = 0, char* ptr = bam; i < 10; i++) { ... }
但我刚刚发现这是不可能的。GCC 给出以下错误:
error: expected unqualified-id before 'char'
你真的不能在 for
循环中声明不同类型的变量吗?
我曾认为可以在一个 for
循环中声明多个变量:
for (int i = 0, char* ptr = bam; i < 10; i++) { ... }
但我刚刚发现这是不可能的。GCC 给出以下错误:
error: expected unqualified-id before 'char'
你真的不能在 for
循环中声明不同类型的变量吗?
你可以(但通常不应该)使用局部结构体类型。
for ( struct { int i; char* ptr; } loopy = { 0, bam };
loopy.i < 10 && * loopy.ptr != 0;
++ loopy.i, ++ loopy.ptr )
{ ... }
自 C++11 起,只要这些部分不依赖于局部变量,就可以更加优雅地初始化它们的各个部分。for ( struct { int i = 0; std::string status; } loop;
loop.status != "done"; ++ loop.i )
{ ... }
这几乎可以读懂,但还不够实用。
C++17通过 结构化绑定解决了这个问题:
using namespace std::literals::string_literals;
for ( auto [ i, status ] = std::tuple{ 0, ""s }; status != "done"; ++ i )
确实无法同时声明和初始化不同类型的声明符。但这并不是特定于for循环的。如果您这样做,将会收到一个错误消息:
int i = 0, char *ptr = bam;
第一个for循环的子句可以是(C99 §6.8.5.3)"声明"或"void表达式"。请注意,您可以这样做:
int i = 0, *j = NULL;
for(int i = 0, *j = NULL;;){}
因为i
和*j
都是int
类型。声明的确切语法在§6.7中给出。
如果您真的需要变量保留在循环的作用域内,您可以编写以下代码:
{ char* ptr = bam; for (int i = 0; i < 10; i++) { ... } }
虽然有些丑陋,但是可以使用。
for (...)
的宏时它无法工作(因此宏的使用者需要为其添加自己的花括号来表示循环体)。 - Alex D试试这个:
int i;
char* ptr;
for (i = 0, ptr = bam; i < 10; i++) { ... }
你还可以这样做:
for (int i = 0; i < 10; i++) {
static char* ptr = bam;
}
bam
不是编译时常量,或者在循环内部修改了ptr
并且循环被执行了第二次,那么这种方法就行不通。此外,静态内存速度较慢,并且在循环结束时不会被释放,增加了应用程序的内存占用。因为这些原因,我对这个答案进行了负评。 - undefined我认为现在教给孩子们的编程语言是为了限制你的思维,让你只能按照既定方式拼凑乐高积木,从而构建平庸的东西。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]);
}
}
这里没有任何遗漏。这种使用for循环连接一个一次性的for循环的技术已经被用来嵌入调用获取此哈希对象的枚举器,并开始枚举,以获取提取的键和值,同时通过方便地将它们创建为用户的void指针,他只需要给它们命名。然后它们就会被填充,枚举将继续,直到所有键和值都完成。如果用户在迭代中中断,整个级联的一次性for循环将会崩溃,因为它们可能根本不存在,因为它们是由编译器可以看到将展开循环的简单const操作构造的。所以基本上它让你扩展语法来做这样的事情,而不会有任何惩罚。
但是你需要了解一些C语言,并至少让自己的头脱离出这些玩具语言的机器人盒子,这是学校现在正在灌输给他们的。
for(int i = 0, char* ptr = bam)
жҜ”int i; char* ptr; for(i = 0, ptr = bam)
жӣҙйҡҫйҳ…иҜ»гҖӮж¶ҰиүІеҗҺзҡ„еҶ…е®№еә”дҝқжҢҒеҺҹж„ҸпјҢ并且жҳ“дәҺзҗҶи§ЈгҖӮиҜ·жіЁж„ҸпјҢжӯӨеӨ„дёҚжҸҗдҫӣйҷӨзҝ»иҜ‘з»“жһңд№ӢеӨ–зҡ„д»»дҪ•дҝЎжҒҜгҖӮ - Michael Mrozekptr
和bam
这样的名称,很难使其更易读。 - msw