1

我遇到了一件棘手的事情。这是原始程序:

#include <stdio.h>
int main(int argc, char *argv[])
{
    // go through each string in argv

    int i = 0;
    while(i < argc) {
        printf("arg %d: %s\n", i, argv[i]);
        i++;
    }

    // let's make our own array of strings
    char *states[] = {"cali","heo","arb","flu"};

    int num_states = 4;
    i = 0;  // watch for this
    while(i < num_states) {
        printf("state %d: %s\n", i, states[i]);
        i++;
    }

    return 0;
}

以下是链接中提出的问题:http: //c.learncodethehardway.org/book/ex11.html

通过使用 i-- 从 argc 开始倒数到 0,使这些循环倒数。您可能需要做一些数学运算才能使数组索引正常工作。

针对上面提到的这个问题,我对上面的程序进行了修改。在下面的代码中,我只能执行 1 个 while 循环。我无法执行这两个循环。请纠正我的代码。

我使用valgrind了调试工具。

#include <stdio.h>
int main(int argc, char *argv[])
{
    int i = 2;
    while(i < argc) {
        printf("arg %d: %s\n", i, argv[i]);
        i--;
    }

    char *states[] = {
        "cali","heo","arb","flu"
    };

    int num_states = 4;
    i = 3;  // watch for this
    while(i < num_states) {
        printf("state %d: %s\n", i, states[i]);
        i--;
    }

    return 0;
}

输出:

$ make while
$ ./while hey how
2 how 
1 hey 
0 ./while 
Segmentation fault (core dumped)
$

而对于另一种输出方式——

$ ./while
3 flu
2 arb 
1 heo 
0 cali 
Segmentation fault (core dumped)
$

因此,我声称我“无法以上述方式同时执行两个 while 循环”。我已经初始化i=2并且它被递减并且我已经将i值重新初始化为 3。

4

6 回答 6

2

在and部分的while循环条件下,您的逻辑很糟糕。将它们更改为或在两种情况下都更改为或简单地更改,因为它最终变为 0。while(i<argc)while(i<num_states)while(i>=0)while(i)i--

#include <stdio.h>
  int main(int argc, char *argv[])
{
int i = 2;   // If OP is certain argc is 2!Better use i=argc instead
while(i >= 0)   //Error was  here 
{
    printf("arg %d: %s\n",argc-i, argv[argc-i]); // alteration here
    i--;
}


char *states[] = {
    "cali","heo","arb","flu"
};

int num_states = 4;
i = 3;  // watch for this
while(i >=0) {  //alteration here
    printf("state %d: %s\n", num_states-i, states[num_states-i]); // Here too
    i--;
}

return 0;}

注意:while(i < num_states)你的第二个程序中肯定会造成很大的麻烦,因为每次都会满足条件,i每次迭代后减少 1 并num_states保持固定为 4。

于 2013-04-24T06:21:13.423 回答
1

循环的想法是从i设置为最大值开始,并i在每次迭代时递减:

i = argc;
while (--i >= 0)
    printf("arg %d: %s\n", i, argv[i]);

i = 4;
while (--i >= 0)
    printf("state %d: %s\n", i, states[i]);
于 2013-04-24T06:18:55.440 回答
0

以下代码:

while(i < num_states) { <---------------------- HERE
    printf("state %d: %s\n", i, states[i]);
    i--;
}

您实际上是在倒计时并检查不正确的值。

一定是:

 while(i >= 0)

这里:

while(i < argc) {
    printf("arg %d: %s\n", i, argv[i]);
    i--;
}

相同:

while(i >= 0)
于 2013-04-24T06:20:35.857 回答
0
int max = 4;
int i = max;
while(i > 0)
{
    // backward count
    cout << "state " << i << " " << states[i-1] << endl;
    printf("state %d %s\n", i, states[i-1]);

    // forward count
    cout << "state " << max-i << " " << states[max-i] << endl;
    printf("state %d %s\n", max-i, states[max-i]);
    i--;
}
于 2013-04-24T06:22:51.460 回答
0

由于条件是

while(i < num_states)

并且你要递减 i,这个条件总是(并不总是)为真。当 i==-1 时,你将要访问states[-1],你应该阻止它。

代码应如下所示:

 i = num_states - 1;
 while (i >= 0)

这样,您当然可以以相反的顺序输出数组。要产生相同的输出,您可以改为执行以下操作:

int num_states = 4;
i = num_states - 1; 
while( (num_states - i - 1) < num_states) {
    printf("state %d: %s\n", num_states - i - 1, states[num_states - i - 1]);
    i--;
}

即使它看起来像一个代数技巧。

于 2013-04-24T06:28:56.097 回答
0

分段错误是由于在 i 为负数时尝试调用 argv[i](或 states[i]),但这是因为循环结构的逻辑缺陷。

例如,在第一个循环中:

int i = 2;
while(i < argc) {
    printf("arg %d: %s\n", i, argv[i]);
    i--;
}

例如,假设 argc 为 4。您的代码所做的是告诉循环在每次 i 小于 4 时重复。而且,由于 i 从 2 开始并且每次都下降,因此该循环可以永远重复。循环条件将始终评估为真。但是,由于最终 i 变为负数并且您尝试将其用作数组索引,因此会产生分段错误。修复它的最简单方法是:

int i = argc-1;
while(i >= 0) {
    printf("arg %d: %s\n", i, argv[i]);
    i--;
}

这样,我从 argv 的最后一个索引开始(即 argc-1,因为 argc 是数组中的元素数,而 argv 是从元素 0 开始的数组。例如,如果 argc 为 5,则此代码将通过 argv[0] 打印 argv[4])

我发现考虑 while 循环的最佳方式是使用基本英语。“在 y 为真时继续重复 x”。在您的代码中, y 始终为真,因此 x 会一直重复(或者,在这种情况下,直到出现分段错误)。

看看您是否也可以将此逻辑应用于其他循环。玩得开心学习c!

于 2013-04-24T06:34:53.600 回答