现在学习C,我做了这个简单的 $.post( "charge.php", { stripeToken: token.id, amount:$("#custom-donation-amount").val(),stripeEmail:token.email})
。该程序只是检查给定的参数是否包含'a'字母。
for-loop
这样做的结果是一个永远循环的程序,但是如果我改变了行:
int main(int argc, char *argv[])
{
if(argc != 2) {
printf("ERROR: Need one argument\n");
return 1;
}
int i = 0;
char letter;
for(i = 0, letter = argv[1][i]; letter != '\0'; i++) {
switch(letter) {
case 'a':
printf("%d: 'a'\n", i);
break;
default:
printf("%d: '%c' is not an 'a'\n", i, letter);
}
}
return 0;
}
到
for(i = 0, letter = argv[1][i]; letter != '\0'; i++)
,
代码运行得很好。为什么是这样?
答案 0 :(得分:2)
letter
永远不会在您的循环中更新。它始终具有argv[1]
中字符串的第一个字符。发表此声明
letter = argv[1][i];
在循环体中的switch
语句之后。
答案 1 :(得分:2)
letter
仅被赋值一次;在循环的开始。该赋值应该在for循环中:
// Assign initial value to letter
char letter = argv[1][0];
for(i = 0; letter != '\0'; i++){
switch(letter) {
// ...
}
// Update new value to letter
letter = argv[1][i];
}
答案 2 :(得分:2)
for
循环的第一部分仅在开头初始化。您可以通过交换,
和;
来“修复”您的代码:
for (i = 0; letter = argv[1][i], letter != '\0'; i++) {
现在条件使用逗号运算符首先分配字母(并丢弃此值),然后检查字符是否为'\ 0'。实际上第二部分是多余的,因为letter = argv[1][i]
的值是字符,只有当它不是'\ 0'时它才是真的,所以我们可以把循环写为
for (i = 0; letter = argv[1][i]; i++) {
如果您不需要循环索引,经验丰富的C程序员不会使用上面的任何构造 - 包括索引,而只使用指向char的指针:
char *pos;
for (pos = argv[1]; *pos; pos++) {
switch(*pos) {
case 'a':
printf("'a'\n");
break;
default:
printf("'%c' is not an 'a'\n", *pos);
}
}
或甚至索引
char letter, *pos = argv[1];
int i;
for (i = 0; letter = pos[i]; i++) {
switch(letter) {
case 'a':
printf("%d: 'a'\n", i);
break;
default:
printf("%d: '%c' is not an 'a'\n", i, letter);
}
}
答案 3 :(得分:2)
如果您在调试for循环时遇到问题,通常会认为for (INITIALISE; TEST; INCREMENT)
等同于:
INITIALISE;
while (TEST)
{
// code
INCREMENT;
}
此外,您永远不应该使用逗号运算符。如果你真的知道你在做什么就可以使用它,但如果你真的知道你在做什么,那么你就不会在这里发布这个问题。
所以在你的for循环for(i = 0, letter = argv[1][i]; letter != '\0'; i++)
中用逗号替换逗号我们可以把它看作:
i = 0;
letter = argv[1][i];
while (letter != '\0')
{
// other code (which doesn't modify letter)
i++;
}
并且应该清楚为什么循环不会终止。
答案 4 :(得分:1)
每当你得到一个偶然的for-for循环时,首先要检查的是你是否实际增加了循环迭代器。你没有,所以你去。
修复是微不足道的,只需使用指针,这可能是你想要的吗?
const char* cptr = argv[1];
for(i = 0; cptr[i] != '\0'; i++)
{
switch(cptr[i])
{
...
}
}
你现在拥有一个纯粹,简单的循环。尽可能避免使用多个迭代器。作为奖励,它比原始版本运行得更快,因为在循环的每一圈都没有无意义的复制。