Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the first assignment of str1[0]? Shouldn't it be of str1[1]?

In the for loop, we are using ++i which means that i is incremented to 1 before the loop starts to execute. What am I getting wrong here?

Here is the code:

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

int main() {
    char str1[100], str2[100];
    int i;
    scanf("%s", str1);
    for (i = 0; str1[i] != '\0'; ++i) {
        str2[i] = str1[i];
    }
    str2[i] = '\0';
    printf("%s\n", str2);
    return 0;
}
like image 491
A.Vik Avatar asked Feb 05 '17 13:02

A.Vik


3 Answers

The for loop syntax is composed of three statements. The third ("update step") is executed at the end of the loop body. So in the first iteration, i is zero.

The expression

for(init_stmt; cond_expr; update_stmt)
  body_stmt;

Will result in code roughly equivalent to the following:

{
  init_stmt;
  while(cond_expr) {
    body_stmt;
    update_stmt;
  }
}
like image 56
StoryTeller - Unslander Monica Avatar answered Nov 15 '22 11:11

StoryTeller - Unslander Monica


Your premise is wrong. i is not incremented to 1 before the loop starts.

for (initialization_statement; conditional_statement; update_statement) {
    body_of_for_loop
}

The way for loop works is it executes the initialization statement and then checks if the conditional statement is true. If the conditional statement is true, the body of the for loop is executed. Once the body of the for loop is executed, the update statement is executed and then again the conditional statement is evaluated and so on.

like image 38
Rishi Avatar answered Nov 15 '22 12:11

Rishi


I'm afraid you are mistaken: in the context of the increment expression of the for statement, ++i, i++, i += 1 and i = i + 1 all have the same effect. Furthermore, this increment expression is executed once after each iteration, before evaluating the condition, but not before the first iteration. Here are the steps for the for statement evaluation:

  1. evaluates the initialization expression i = 0 ;
  2. evaluate the condition expression: if it is false, exit from the loop.
  3. evaluate the body of the loop:
    • if a break statement is evaluated, exit the loop
    • if a continue statement is evaluated branch directly to step 4 ;
    • otherwise, branch to step 4.
  4. evaluate the increment expression ++i ;
  5. branch to step 2.

The last statement correctly uses str2[i] = '\0';. The value of i at the end of the for loop is the first that failed the condition, the one for which str1[i] == '\0', which is known as the length of the C string in str1. This is the index at which you want to store the null terminator in str2.

Note that the code can be simplified and made safer this way:

#include <stdio.h>

int main(void) {
    char str1[100], str2[100];

    if (scanf("%99s", str1) == 1) {
        for (int i = 0; (str2[i] = str1[i]) != '\0'; i++) {
            continue;
        }
        printf("%s\n", str2);
    }
    return 0;
}
like image 41
chqrlie Avatar answered Nov 15 '22 12:11

chqrlie