在Python中,我可以这样做:
str = "abcd"
while(str):
print str
虽然它不是很有用(迭代字符串中的元素通常是需要的),但它可能让我想知道为什么C中的等价物不是,所以:
char str[] = "abcd"
while(str[])
{
do stuff
}
当我尝试编译时:
isblank.c:11:13: error: expected expression
while (str[])
^
1 error generated.
我被迫在表达式中添加字符串的索引,因此强制它迭代字符串的元素。
为什么会这样?
答案 0 :(得分:4)
此:
char str[] = "abcd"
while(str)
{
do stuff
}
一旦在str
的声明中添加分号并用实际代码替换do stuff
,就完全合法了。它也没用。 str
是一个数组表达式,因此在大多数上下文中它都会衰减到指向数组的第一个元素,包括这个元素。当用作条件时,if (pointer)
相当于if (pointer != NULL)
。因此,只要数组对象str
的地址不为空(即永远),循环就会继续执行。如果您想要无限循环,只需写下while (1)
或for (;;)
。
但是您的代码没有使用while (str)
;它使用了while (str[])
,产生了这个错误:
isblank.c:11:13: error: expected expression
while (str[])
^
1 error generated.
编译器抱怨只是因为str[]
不是语法上有效的表达式。
您的Python代码:
str = "abcd"
while(str):
print str
是一个无限循环,重复打印abcd
。 C等价物非常相似:
char str[] = "abcd";
while (str) {
puts(str);
}
条件的评估定义不同(C的if
测试指针是否为非NULL,而Python的if
测试字符串是否为非空),但在这两种情况下它始终是是的,导致无限循环。
答案 1 :(得分:2)
你正在展示的两个片段都在做同样的工作(产生一个无限循环),除了在python str
中是对象abcd
的引用。此引用可以更改为另一个对象。在C中,str
是一个数组,它是不可修改的左值。
答案 2 :(得分:1)
因为python具有更智能的类型识别,因为它是更高级别的语言,并且支持很多类型信息。
虽然C中的数组只是内存中的一组值,但在python中,每个对象实际上都包含有关自身的更多信息。
例如,如果你接受字符串,它将定义它的迭代器以及它的范围操作的开始和结束。这就是python何时知道对象何时开始结束等。
在C中,当你要求一个char数组类型的数据数组时,你就得到了这个。 C甚至不会为您存储数组的大小,因此可以访问5个元素数组的第6个元素。它将编译,因为它是正确的C,但可能在运行时爆炸。话虽如此,如果你想迭代字符数组,C不会假设默认行为。可能是因为它的设计时间和方式,因此你必须指定如何访问元素。编译器无法判断您是否要按顺序,按相反顺序,每秒等访问它们。但由于这些假设的长矛,字符数组的内存使用率总是比python中更高效。
答案 3 :(得分:0)
在C中执行此操作的一种方法是:
char *str = "abcd";
for (; *str; str++)
{
printf("Character is %c\n", *str);
}
完整示例: http://ideone.com/AaEGgH