开发者

c# syntax question - for loop and end of line

I am currently learning c# and reading a few books. I can do quite a few things, however only from modifying examples - it really frustrates that I do not actually understand how/why some of the more basic items work.

I have just done a console application that takes arguments and displays them all one by one.

The code is:

using System;

class test
{ static int Main(string[] argsin)
{ 

for (
        int i = 0; 
        i < argsin.Length; 
        i++
    )
Console.WriteLine("Argument: {0}", argsin[i]);
Console.ReadLine();
return -1;
}
}

Now, this works perfectly, but coming from a basic (no pun!) understand of Visual Basic, how/why does it know to print the correct argument and then go on to the next without quitting the application after the first Console.WriteLine... I feel I have missed the fundamentals of how this works!

Next, why is it tha开发者_JS百科t inside the for loop, each line ends with a semicolon apart from i++?

I keep forgetting to add it from time to time, and then when trying to work out why it wasn't compiling, I added one where I wasn't meant to!


Your code is formatted a bit strangely, if you reformat it as this I think it's easier to understand:

using System;

class test
{ 
    static int Main(string[] argsin)
    { 
        for (int i = 0; i < argsin.Length; i++)
        {
            Console.WriteLine("Argument: {0}", argsin[i]);  
        }
        Console.ReadLine();
        return -1;
    }
}

So as you can see int i = 0; i < argsin.Length; i++ are not 3 different lines, they are all just arguments to the for loop.

And adding the { and } makes it easier to see what lines of code are inside the for loop.


I will try to explain the loop by comparing to VB syntax.

In C#: for (int i = 0; i < 5; i++)

In VB: For i = 0 To 4

The i = 0 part is the same in both, so I guess it's clear - this is used to initialize the loop iterator.

The i < 5 part in C# becomes 0 to 4 in VB.... you can think of this as though VB is doing a "shortcut", but the meaning in both is the same: that is the loop condition, i.e. what is the condition that the loop will keep running, in this case the loop will keep running as long as i is less then 5.

And finally, the i++ part which is required in C# to tell "what will happen to the iterator after each iteration?" is not needed in good old friendly VB that will simply increment it by 1 for you, always - by default.

Why having semicolon after each part of the loop? Because each part has its own meaning and usage so the compiler must know how to separate the parts when building the final code. Why not having semicolon after the i++ part? Same reason that you don't have comma after last argument passed to function e.g. Console.WriteLine("Argument: {0}", argsin[i], );

About the loop having no "block" only one line, it was explained in the other answers, rule of thumb is that C# allow single line blocks to appear without the brackets.


By convention c# and all c like languages when presented with a for loop (or and if statement etc) will run the line immediately after. Personally I don't like writing code like this, i feel it lacks readability.

To clarify we can add curly braces to denote scope

for (
        int i = 0; 
        i < argsin.Length; 
        i++
    )
{
     Console.WriteLine("Argument: {0}", argsin[i]);
}
Console.ReadLine();
return -1;

now what the for loop executes is clearly defined (and if we wanted to do more in our loop we would add the extra instructions in between the curly braces).

edit: The reason for the semi colons as you define your for loop is that each part of that definition is a separate statement.

int i = 0; //creates an integer i and sets its value to 0
i < argsin.Length; sets our comparison operation to define when the loop ends
i++ //what to do at the end in this case increment i by 1

Each needs to be treated independent of the others and as the semi colon denotes the end of a statement in c# (which is why each line ends in it) we use it to break up the statements so the compiler can read it.

While the 2 semicolons are mandatory the arguments are not we could if we wanted change it to be this.

int i = 0;
for (;;)
{
     if(i>=argsin.Length){
         break;
     }
     Console.WriteLine("Argument: {0}", argsin[i]);
     i++;
}

This is functionally identical to the way you wrote it but I've moved all the logic out of the for statement to its equivalent position inside (or outside in the case of defining i) the loop


The reason why you application prints the right number of arguments is that the WriteLine statement is part of the loop. In C# if you've only got one line of code after a for statement then you don't need curly brackets. (This is the same for if too)

So

for (int i = 0; i < argsin.Length; i++)
    Console.WriteLine("Argument: {0}", argsin[i]);

is the same as

for (int i = 0; i < argsin.Length; i++)
{
    Console.WriteLine("Argument: {0}", argsin[i]);
}

As the for the semi-colon after the i++ thats just how it is. Normally the for statement is written on one line as I've done in my samples above.

Hope this helps.


I've brushed your formatting a little up, which gives you an easier understanding on how it works.

using System;

class test
{
    static int Main(string[] argsin)
    { 

        for (int i = 0; i < argsin.Length; i++ )
            Console.WriteLine("Argument: {0}", argsin[i]);

        Console.ReadLine();
        return -1;
    }
}

There's a special rule for C-like languages: You define it's scope using if(true) { ... } similar to If True Then ... End If, but if you only have one line, you can decide not to use brackets. Therefor the next line after the if or for[each] will be used for the scope.

The i++ does not end with a ; because it is within the declaration of the for.

Also, don't forget to have a look at the foreach loop.


If I rewrite your method with different formatting (but identical syntax), it may make things clearer:

static int Main(string[] argsin)
{ 
    for (int i = 0; i < argsin.Length; i++)
    {
        Console.WriteLine("Argument: {0}", argsin[i]);
    }

    Console.ReadLine();
    return -1;
}

Remember that c# doesn't use a line break for statement termination (unlike VB). The "third line" in your 'for' loop isn't actually a "line," it's just the third expression, and is terminated by the closing bracket.

The reason the loop continues rather than quitting is because (without squiggly brackets to indicate a statement block) the 'for' loop will only loop the single statement immediately following the loop - that is, the 'Console.WriteLine'. I'm guessing that you thought that the 'ReadLine' and 'return' statements would be part of the loop but, in C# syntax, that's not the case. (I added the bracess to my version to make the scope of the loop clearer).


I'll answer the part of your question...

for is a construct that has initializer, loop statement, and terminating condition.

So

for (X, Y, Z) { }

would be equivalent to

X;
while (Y)
{
//   code
    Z;
}

As for your question about not quiting the application - for () will bind to first NEXT statement, or statement BLOCK. In your case, you have only one line as a statement. If there would be more lines, you should write them encased in { and }.


Typical syntax for a for loop is:

for( int i = 0; i < argsin.Length; i++ )
{
    //<CODE>
}

So you'd read it (in your mind) as: "With the temporary value 'i' starting at the value 0, while 'i' is less than 'argsin.Length', do '//' with i as the value, always ending with 'i++'"

A for loop just gets translated to:

{
    int i = 0;
    while( i < argsin.Lenth )
    {
        //<CODE>
        i++;
    }
}

(The extra surrounding braces are to say that 'i' goes out of scope and can no longer be used when the brace closes). Like any 'if' or 'while' statement the closing parenthesis provides the 'end-of-statement' "Character" (if you will) and so the semicolon is unnecessary. Earlier they are a must because you have to know where to end each statement.

[EDIT]

By the way: there's a little more to it than a straight translation. There are cases where you can include multiple initializations, and multiple 'at the end of each loop' instructions. Don't worry about those until you understand what's going on.


That is the basic of the for loop, in that loop, you declare that the starting value of integer i is zero and it should continue to loop until i is equal to the length of string[] argsin and increase the value of i on each iteration. Which means if the length of your argsin array is 5, the loop will

// first run
for(int i = 0;i<5;i++)
Console.WriteLine("Argument: {0}",argsin[0]);

// second run
for(int i = 1;i<5;i++)
Console.WriteLine("Argument: {0}",argsin[1]);

// third run
for(int i = 2;i<5;i++)
Console.WriteLine("Argument: {0}",argsin[2]);

// forth run
for(int i = 3;i<5;i++)
Console.WriteLine("Argument: {0}",argsin[3]);

// fifth run
for(int i = 4;i<5;i++)
Console.WriteLine("Argument: {0}",argsin[4]);

After 5 runs, i will be 5 and will not meet 5 < 5 and quit this loop and go on with the next statement.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜