【发布时间】:2015-08-18 16:16:14
【问题描述】:
for (i = 0; *(str+i); i++)
{
//some code;
}
此语法中的第二个条件是什么意思?可以这样写吗?
【问题讨论】:
-
首先你要记住,在 C 中,字符串以零结尾。然后你必须记住,在 C 中,所有布尔表达式中的零都被认为是 false,任何非零都是 true。现在条件表达式应该更有意义了。
for (i = 0; *(str+i); i++)
{
//some code;
}
此语法中的第二个条件是什么意思?可以这样写吗?
【问题讨论】:
此类循环通常用于具有可以转换为布尔值的标记值的数组。例如字符串。 (字符串以零字符终止)
例如,这个循环计算字符串文字“Hello”的长度
const char *str = "Hello";
size_t i = 0;
for ( ; *( str + i ); i++ )
{
/* empty body of the loop */
}
std::cout << "The length of string literal " << str
<< " is equal to " << i << std::endl;
或者在 C 中你可以使用printf
printf( "The length of string literal %s is equal to %zu\n", str, i );
表达式*( str + i ) 等价于str[i]
在for循环中,这个表达式使用的条件等价于
*( str + i ) != 0
也就是只是转换为bool类型
( bool ) *( str + i )
因此,如果表达式等于 0,则生成 false,否则生成 true。
另一个例子。如果要输出程序参数那么可以这样写
#include <iostream>
int main( int argc, char *argv[] )
{
while ( *argv ) std::cout << *argv++ << std::endl;
}
C 中的奥特
while ( *argv ) puts( *argv++ );
因为带有程序参数 argv[] 的数组的最后一个元素总是等于 NULL。
程序中的while循环等价于下面的for循环
for ( int i = 0; *( argv + i ); i++ )
或者
for ( int i = 0; argv[i]; i++ )
来自 C++ 标准(5.2.1 下标)
1 后缀表达式后跟方括号中的表达式是 后缀表达式。其中一个表达式应具有类型 “T 数组”或“指向 T 的指针”,另一个应为无范围的 枚举或整数类型。结果是“T”类型。 “T”型 应该是一个完全定义的对象类型。65 表达式 E1[E2] 与 *((E1)+(E2)) 相同(根据定义)
在 C 中同样有效。
【讨论】:
C。也许标签被改变了?建议更改std::cout << ... #include <iostream>, "C++ Standard ..."
是的。 str 是一个指针,因此当到达字符串空终止符('\0')时,条件为假,使循环停止执行其主体。
想象一下字符串会是这样的:
str: 'a'|'b'|'\0'
i: 0 | 1 | 2
所以当i 得到值2,那么这个*(str+i) 将给出0,因此你的循环在那个时候会是这样的:
for (i = 0; 0; i++)
因为指针运算将导致*(str+i) 指向字符串的最后一个条目。
【讨论】:
str 大概是一个指针,而不是一个字符串。字符串由空字符 '\0' 终止,而不是由空指针 NULL 终止。
*(str+i) 等效于 str[i],前提是 str 是指向某些数据类型的指针。这是一个有效的语法。str 似乎是一个以空字符结尾的字符串。当*(str+i) 等于'\0' 时,此条件将false。
【讨论】:
str 是空终止字符串吗?
在其最通用的形式中,for 循环包含以下元素:
for ( init-statement; condition-statement; iter-statement ) statement
这些元素中的每一个都是非常开放的。在您的情况下,条件语句只是*(str+i)。如果计算结果为非零值,则将执行循环的 statement 部分。如果计算结果为零,则循环将终止。
当你想执行语句给定次数时,你可以使用:
for ( i = 0; i < count; ++i ) { ... }
假设您的代码中的str 指向以空字符结尾的字符串,您正在为str 中的所有字符执行语句。您的 for 循环相当于:
for (i = 0; str[i] != '\0'; i++)
【讨论】:
陈述是正确的。 是的,我们可以将它用作 *(str+i) 它将一直运行到字符串的末尾。 其中 * 在特定地址提供价值。
例子:
char str[5]={"test"};
cout<<*str; // it will always give default first index value
cout<<*(str+1) // it will display first character of string
所以当它到达字符串的末尾时,它将变为空。 字符串的结尾始终为空字符。 那么Loop就会终止。
【讨论】:
C 问题。考虑putchar(*str); 而不是cout<<*str;
循环中的第二条语句检查条件是否为真。如果条件为真,则循环继续;如果为假,则终止循环。此外,C 将0 视为false,并且将任何非零值视为true。因此,*(str+i) 如果非零则计算为 true,如果为零则计算为 false。由于 C 中的每个字符串都是一个以\0 结尾的字符数组(或计算为false 的零),因此查看字符串终止字符的结果为false,因此该语句是合法且有效的。
关于在 C 语言中为什么会发生这种情况的更多信息,这是在算术逻辑单元 (ALU) 的累加器中加载某些内容的副作用,这会导致设置一些标志(例如 ACC 是否为零)。
【讨论】:
为了清楚起见,for 循环构造
for (i = 0; *(str+i); i++)
可以改写为
for (i = 0; str[i]; i++) //pointer arithmetic
可以改写为
for (i = 0; (str[i] != 0); i++) //condition checking
所以,本质上,*(str+i) 是条件检查语句(类似于涉及< / > 运算符的最广泛使用的条件检查语句),这是完全合法合法。
它的作用是循环直到ith 元素不为空。
null 的十进制值为 0,FWIW。
【讨论】: