for循环的退出条件是什么?

时间:2018-08-01 19:35:16

标签: c loops data-structures

我的下面程序运行正常,但我不理解在标记的位置使用exp[i]作为循环终止条件。为什么以及在什么情况下会使循环退出?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// Stack type
struct Stack
{
   int top;
   unsigned capacity;
   int* array;
};

// Stack Operations
struct Stack* createStack( unsigned capacity )
{
   struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack));

   if (!stack) 
      return NULL;

   stack->top = -1;
   stack->capacity = capacity;

   stack->array = (int*) malloc(stack->capacity * sizeof(int));

   if (!stack->array)
      return NULL;
   return stack;
}

int isEmpty(struct Stack* stack)
{
   return stack->top == -1 ;
}

char peek(struct Stack* stack)
{
   return stack->array[stack->top];
}

char pop(struct Stack* stack)
{
   if (!isEmpty(stack))
      return stack->array[stack->top--] ;
   return '$';
}

void push(struct Stack* stack, char op)
{
   stack->array[++stack->top] = op;
}


// A utility function to check if the given character is operand
int isOperand(char ch)
{
   return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
}

// A utility function to return precedence of a given operator
// Higher returned value means higher precedence
int Prec(char ch)
{
   switch (ch)
   {
      case '+':
      case '-':
         return 1;

      case '*':
      case '/':
         return 2;

      case '^':
         return 3;
   }
return -1;
}


// The main function that converts given infix expression
// to postfix expression. 
int infixToPostfix(char* exp)
{
   int i, k;

   // Create a stack of capacity equal to expression size 
   struct Stack* stack = createStack(strlen(exp));
   if(!stack) // See if stack was created successfully 
      return -1 ;

下面for循环的退出条件是什么?

for (i = 0, k = -1; exp[i]; ++i) 
{
    // If the scanned character is an operand, add it to output.
    if (isOperand(exp[i]))
        exp[++k] = exp[i];

    // If the scanned character is an ‘(‘, push it to the stack.
    else if (exp[i] == '(')
        push(stack, exp[i]);

    // If the scanned character is an ‘)’, pop and output from the stack 
    // until an ‘(‘ is encountered.
    else if (exp[i] == ')')
    {
        while (!isEmpty(stack) && peek(stack) != '(')
            exp[++k] = pop(stack);
        if (!isEmpty(stack) && peek(stack) != '(')
            return -1; // invalid expression             
        else
            pop(stack);
    }
    else // an operator is encountered
    {
        while (!isEmpty(stack) && Prec(exp[i]) <= Prec(peek(stack)))
            exp[++k] = pop(stack);
        push(stack, exp[i]);
    }

}

// pop all the operators from the stack
while (!isEmpty(stack))
    exp[++k] = pop(stack );

exp[++k] = '\0';
printf( "%sn", exp );
}

// Driver program to test above functions
int main()
{
   char exp[] = "a+b*(c^d-e)^(f+g*h)-i";
   infixToPostfix(exp);
   return 0;
}

4 个答案:

答案 0 :(得分:3)

只要exp[i]的值为true,循环就会继续。

exp[i]在没有任何其他上下文的情况下求值为char。可以在期望布尔值的地方使用char。如果false的值为char,则布尔值为0,否则为true

在您的用法中,循环将对exp的每个字符(终止的空字符)继续进行。当遇到终止空字符时,循环将停止。

更容易理解的形式是使用exp[i] != '\0'

for (i = 0, k = -1; exp[i] != '\0'; ++i) { ... }

答案 1 :(得分:0)

exp[i]

如果您有字符串终止符(\0),则其求值为false。如果它是另一个char,则求值为true,因此进入循环。 如果为\0,则循环停止。

答案 2 :(得分:0)

如上所述,exp [i]返回true,直到命中“ \ 0”(空字符)为止。如果没有空字符,它将继续并可能溢出。

答案 3 :(得分:0)

为使代码更加清晰,我们可以对上述for循环进行以下更改:

int exp_length = strlen(exp);
for(i = 0, k = -1; i<exp_length; ++i) {

}

两者都做同样的事情。
基本上,for循环中的中间表达式用于评估终止条件。只要中间表达式的值为true,for循环就会继续,并且当中间表达式的值为false时,for循环会中断。

  • 如果i = exp_length,则条件i<exp_length的计算结果为false,并进行循环中断。
  • 类似地,exp字符串中的最后一个字符(at i = exp_length)包含null,因此条件exp[i]的计算结果为false,并进行循环中断。