[毕业生的商业软件开发之路]C#表达式以及判断语法结构

时间:2021-07-12 13:51:11

近期开始接触到在校学生、高校实习生和毕业生,在此说一下笔者对这些徘徊在职场门口的学生一些建议,希望能给这些初学者进入软件开发行业带来一些帮助,使得毕业生能更顺利的进入软件开发公司开始职场生涯,人生来一个完美的转弯。

---------------------------------------------------------

 

表达式 数学表达式 C#的数学表达式支持加、减、乘、除和求模运算,这个和其他编程语言差不多。其支持的运算符如下表所示

+ 加,例如“2 + 3,运算结果为5。
- 减,例如“2-3”,运算结果为-1。
* 乘,例如“2*3”,运算结果为6。
/ 除,例如“2/3”,运算结果为“0.66666”。
% 求模,例如“2%3”,运算结果为“2”。
++ 自增1,例如“int a = 2 ; a ++ ”,运算结果为“3”。
-- 自减1,例如“int a = 2 ; a--”,运算结果为“1”。

C#支持使用园括号来改变运算的优先级。   逻辑表达式 C#支持的逻辑表达式,和其他编程语言差不多,其支持的运算符如下表所示

意义 优先级 语法
逻辑反 !
等于 == (两个等于号,中间不能有空格)
大于
大于等于 >=
小于 <
小于等于 <=
不等于 !=
逻辑与 &&
逻辑或 ||

   

&& 逻辑与,比如“BooleanValue1 && BooleanValue2,只有两个条件都成立,这个表达式才成立。
|| 逻辑或,比如“BooleanValue1 || BooleanValue2,两个条件中任意一个成立,则这个表达式就会成立。
! 逻辑反,比如“! BooleanValue”,若条件成立,则表达式不成立,若条件不成立,则表达式成立。

       C#支持使用园括号来改变运算的优先级。 位运算表达式 C#支持类似C语言的位运算。

<<  左位移,相当于乘以2的若干次方。比如“int a = 3 ; a <<2其效果等于“a = a * 2 * 2,运算结果为12 ;但左位移操作比乘法操作要快得多,若固定为乘上2的若干次方值时,尽量用左位移操作。
>>  右位移,相当于除以2的若干次方,比如“int a = 100 ; a >>2,其效果等于“a = a / 4,运算结果为25;但右位移操作比除法操作要快得多,若固定为除以2的若干次方值时,尽量用右位移操作。
& 位与操作。
| 位或操作。

  执行结构 C#采用的是类似C、JAVA语言的执行结构,主要有。 顺序执行 条件判断 在C#中有多种条件判断执行语句,主要有 if 结构 C#支持if条件判断结构,使用很简单,其演示代码如下 理论上这段代码中的花括弧去掉,可以写成如下,
   
  
  
  1. DateTime dtm = DateTime.Now;  
  2. string b = null;  
  3. if (dtm.Hour >= 12)  
  4. {  
  5.     b = "下午";  
  6. }  
  7. else 
  8. {  
  9.     b = "上午";  
注意,在实践中是不推荐这种写法的,这种写法虽然比较简练些,但很可能制造出难于察觉的程序错误,还是必须老老实实的把花括号写出来。   在书写if语句时,若逻辑表达式是复合的,包含了多个条件,则需要进换行。例如对于以下的代码,if语句中包含了一个具有4个成员的复合逻辑表达式

 

 
  
 
 
  1.  int NumberValue = 10;  
  2. string StringValue = "123";  
  3. char CharValue = 'z';  
  4. double DoubleValue = 30;  
  5.    
  6. if ( NumberValue == 10 || StringValue == "123" || CharValue == 'z' || DoubleValue >= 20 )  
  7. {  
  8.     Console.WriteLine("条件成立");  
  9. }  
这不写法不美观,一条语句过长,推荐写成如下样式
  
 
 
  1. int NumberValue = 10;  
  2. string StringValue = "123";  
  3. char CharValue = 'z';  
  4. double DoubleValue = 30;  
  5.    
  6. if ( NumberValue == 10  
  7.     || StringValue == "123" 
  8.     || CharValue == 'z' 
  9.     || DoubleValue >= 20 )  
  10. {  
  11.     Console.WriteLine("条件成立");  
  12. }  
另外如果判断条件就是一个布尔值,理论上可以写成如下代码
  
 
 
  1. bool BooleanValue = true;  
  2. if ( BooleanValue )  
  3. {  
  4.     Console.WriteLine("条件成立");  
  5. }  
但在实践中,还是推荐写成如下代码
  
 
 
  1. bool BooleanValue = true;  
  2. if ( BooleanValue == true )  
  3. {  
  4.     Console.WriteLine("条件成立");  
  5. }  
虽然上一种写法比较简短,但第二种写法的可读性更好。 类似的,当判断这个布尔值是否为false时,可以使用逻辑反运算符,其代码如下
  
 
 
  1. bool BooleanValue = true;  
  2. if ( ! BooleanValue )  
  3. {  
  4.     Console.WriteLine("条件成立");  
  5. }  
这种写法的可读性也不好,因为人们在快速的阅读代码中有可能将这个“!”字符漏掉,因此在实践中,还是推荐写成如下代码
  
 
 
  1. bool BooleanValue = true;  
  2. if ( BooleanValue == false )  
  3. {  
  4.     Console.WriteLine("条件成立");  
  5. }  
 在实际编写代码中,代码的可读性比简短要重要,优先考虑。笔者反对编写简短隐晦的代码来炫耀技术,那跟[袁永福版权所有]孔乙己说“茴”字有4种写法一样不切实际。 三元运算符 C#中的三元运算符代码结构为“ 判断条件 ? 当判断成立时的值 : 当判断不成立时的值 ”,例如以下代码演示了三元运算符
  
 
 
  1. DateTime dtm = DateTime.Now;  
  2. string b = dtm.Hour >= 12 ? "下午" : "上午";  
在这段代码中,若当前时间的小时数大于等于12,则获得数值“下午”,否则获得数值“上午”。 这种三元运算符功能和if-else语句一样,不过能更为简短的方式实现功能。在很多情况下能减少代码量,提高代码的可读性。不过三元运算符没有什么扩展性,一次只能设置一个变量值。 switch 结构   在C#中使用“if ( 判断条件 ) 执行代码 ; else 执行代码”,比如以下代码说明了作息状态

 

  
 
 
  1. DateTime dtm = DateTime.Now;  
  2. string state = null;  
  3. switch (dtm.Hour)  
  4. {  
  5.     case 6:  
  6.         {  
  7.             state = "起床";  
  8.         }  
  9.         break;  
  10.     case 8:  
  11.         {  
  12.             state = "吃早饭";  
  13.         }  
  14.         break;  
  15.     case 9:  
  16.         {  
  17.             state = "上班";  
  18.         }  
  19.         break;  
  20.     case 12:  
  21.         {  
  22.             state = "吃午饭";  
  23.         }  
  24.         break;  
  25.     case 13:  
  26.         {  
  27.             state = "上班";  
  28.         }  
  29.         break;  
  30.     case 18:  
  31.         {  
  32.             state = "下班";  
  33.         }  
  34.         break;  
  35.     case 22:  
  36.         {  
  37.             state = "睡觉";  
  38.         }  
  39.         break;  
  40. }  
  41. Console.WriteLine(state);  
其中的 switch语句块还可以写成如下的紧凑样式
  
 
 
  1. switch (dtm.Hour)  
  2. {  
  3.     case 6: state = "起床"; break;  
  4.     case 8: state = "吃早饭"; break;  
  5.     case 9: state = "上班"; break;  
  6.     case 12: state = "吃午饭"; break;  
  7.     case 13: state = "上班"; break;  
  8.     case 18: state = "下班"; break;  
  9.     case 22: state = "睡觉"; break;  
  10. }  
若使用if-else结构写出这种语句,则可以写成如下
  
 
 
  1. DateTime dtm = DateTime.Now;  
  2. string state = null;  
  3. if (dtm.Hour == 6)  
  4. {  
  5.     state = "起床";  
  6. }  
  7. else if (dtm.Hour == 8)  
  8. {  
  9.     state = "吃早饭";  
  10. }  
  11. else if (dtm.Hour == 9)  
  12. {  
  13.     state = "上班";  
  14. }  
  15. else if (dtm.Hour == 12)  
  16. {  
  17.     state = "吃午饭";  
  18. }  
  19. else if (dtm.Hour == 13)  
  20. {  
  21.     state = "上班";  
  22. }  
  23. else if (dtm.Hour == 18)  
  24. {  
  25.     state = "下班";  
  26. }  
  27. else if (dtm.Hour == 22)  
  28. {  
  29.     state = "睡觉";  
  30. }  
  31. Console.WriteLine(state);  
可以看出对于多个常数的比较判断,使用switch结构还是比较方便的,但在case语句中只能是常数,不能是逻辑表达式,这使得switch结构应用受到不小的限制。 在switch语句块中可以不使用花括号,因为没有添加花括号不会导致难于察觉的错误,但还是推荐若case-break结构中的功能代码比较多时还是加花括号。 在C语言中,case结构如果不加上break关键字就可以贯穿执行到下一个case结构,但在C#中,case结构不能贯穿,必须添加break或者return关键字来结束case执行块。     循环结构 在C#中有多种循环结构,以下分别说明 for 循环结构 在C#中,for循环结构写法为“for( 初始化 ; 逻辑表达式 ; 累加处理 ) { 循环体 }”。例如以下代码包含了一个for循环结构
  
 
 
  1. int count = 0;  
  2. for (int index = 0; index < 100; index++)  
  3. {  
  4.     count = count + index;  
  5. }  
  6. Console.WriteLine(count.ToString());  
理论上这段代码可以写成如下
  
 
 
  1. int count = 0;  
  2. for (int index = 0; index < 100; index++)  
  3.     count = count + index;  
  4. Console.WriteLine(count.ToString());    
但笔者推荐还是加上花括号,因为不加花括号很容易导致难于察觉的程序错误。 在代码“for( int index = 0 ; index < 100 ; index ++ )”中,关键字“for”说明开始进行了一个循环;“int index = 0是初始化这个循环,定义了一个累加变量;“index < 100是这个循环是否执行的逻辑表达式,若判断成立则执行循环,否则立即退出循环;“index ++ ”是每次执行完一次循环体后执行的代码,这里是将累加变量自增1。 上面的for循环执行的步骤如下[袁永福版权所有]
  
 
 
  1. int count = 0;  
  2. int index = 0;  
  3. // 执行第1次循环  
  4. if (index < 100)  
  5. {  
  6.     count = count + index;  
  7.     index++;  
  8. }  
  9. else 
  10. {  
  11.     goto EndFor;  
  12. }  
  13. // 执行第2次循环  
  14. if (index < 100)  
  15. {  
  16.     count = count + index;  
  17.     index++;  
  18. }  
  19. else 
  20. {  
  21.     goto EndFor;  
  22. }  
  23. // 执行第3次循环  
  24. if (index < 100)  
  25. {  
  26.     count = count + index;  
  27.     index++;  
  28. }  
  29. else 
  30. {  
  31.     goto EndFor;  
  32. }  
  33.           
  34. // 无穷尽的执行循环体  
  35.  
  36. or:  
  37. Console.WriteLine(count.ToString( ));  
注意,理论上说循环会无穷尽的执行下去,因此需要设置好退出循环的判断条件,否则就容易出现死循环,导致死机。 for循环是使用最为灵活的循环结构,在实践中可以使用它写成很多精致的代码。 在各种循环结构中,包括for循环,都可以使用关键字continue来跳过一些代码直接进入下一次循环,使用关键字break来立即退出循环。若从套嵌了多层的循环跳出来则可以使用goto语句。 foreach 循环结构 foreach循环结构是一种针对列表类型的循环语法结构,其语法为“foreach( 类型名称 变量名 in 列表变量名) { 循环体 }”,以下代码演示了foreach的使用。
  
 
 
  1. string[ ] names = new string[100];  
  2. foreach (string name in names)  
  3. {  
  4.     Console.WriteLine(name);  
  5. }  
在foreach循环中,循环变量是只读的,不能为它设置值,比如上面的foreach循环体重不能写上“name = “张三”; ”这样的代码,但是for语句是可以的。[袁永福版权所有] foreach循环本质上是C#的一个语法封装,上述这段代码等效于如下代码
  
 
 
  1. string[ ] names = new string[100];  
  2. System.Collections.IEnumerator enumerator  
  3.     = ((System.Collections.IEnumerable)names).GetEnumerator();  
  4. enumerator.Reset();  
  5. while (enumerator.MoveNext())  
  6. {  
  7.     string name = (string)enumerator.Current;  
  8.     Console.WriteLine(name);  
  9. }  
因此任何类型只要实现了“System.Collections.IEnumerable”接口的类型就可以用于foreach循环结构。而且这段代码中“enumerator.Current”是只读的属性,这就决定了foreach循环体内不能设置循环变量的值。   while 循环结构 C#执行while循环结构,其代码结构为“while( 逻辑表达式 ) { 循环体 }”,例如上节的演示程序
  
 
 
  1. string[ ] names = new string[100];  
  2. System.Collections.IEnumerator enumerator  
  3.     = ((System.Collections.IEnumerable)names).GetEnumerator();  
  4. enumerator.Reset();  
  5. while (enumerator.MoveNext())  
  6. {  
  7.     string name = (string)enumerator.Current;  
  8.     Console.WriteLine(name);  
  9. }  

就是一个while循环结构。这个循环等价于执行以下代码

  
 
 
  1. // 执行第一次循环  
  2. if (enumerator.MoveNext())  
  3. {  
  4.     string name = (string)enumerator.Current;  
  5.     Console.WriteLine(name);  
  6. }  
  7. else 
  8. {  
  9.     goto EndWhile;  
  10. }  
  11. // 执行第二次循环  
  12. if (enumerator.MoveNext())  
  13. {  
  14.     string name = (string)enumerator.Current;  
  15.     Console.WriteLine(name);  
  16. }  
  17. else 
  18. {  
  19.     goto EndWhile;  
  20. }  
  21. // 执行第三次循环  
  22. if (enumerator.MoveNext())  
  23. {  
  24.     string name = (string)enumerator.Current;  
  25.     Console.WriteLine(name);  
  26. }  
  27. else 
  28. {  
  29.     goto EndWhile;  
  30. }  
  31. // 无穷尽的执行循环  
  32. hile:  

  do-while 循环结构

C#支持do-while循环结构,其用法为“do{ 循环体 }while ( 逻辑表达式 ) ;”例如以下代码演示了do-while循环结构。[袁永福版权所有]
  
 
 
  1. string[ ] names = new string[100];  
  2. int index = 0;  
  3. do 
  4. {  
  5. Console.WriteLine(names[index]);  
  6. index ++ ;  
  7. }  
  8. while (index < names.Length - 1);  

这段代码相当于执行以下代码

  
 
 
  1.     // 执行第一次循环  
  2.     Console.WriteLine(names[index]);  
  3. index++;  
  4.     if (! (index < names.Length - 1))  
  5.     {  
  6.         goto EndDoWhile;  
  7.     }  
  8.     // 执行第二次循环  
  9.     if (index < names.Length - 1)  
  10.     {  
  11.         Console.WriteLine(names[index]);  
  12.         index++;  
  13.     }  
  14.     else 
  15.     {  
  16.         goto EndDoWhile;  
  17.     }  
  18.     // 执行第三次循环  
  19.     if (index < names.Length - 1)  
  20.     {  
  21.         Console.WriteLine(names[index]);  
  22.         index++;  
  23.     }  
  24.     else 
  25.     {  
  26.         goto EndDoWhile;  
  27.     }  
  28. // 无穷尽的执行循环  
  29. EndDoWhile:  

从这段代码可以看出,do-while循环和for、while循环有个不同就是它在执行第一次循环体的前不计算逻辑表达式,让代码无保障的运行在高风险区,这就成为一个程序错误的高发区。因此笔者很少使用do-while语句,只在某些特殊的情况下才使用。

笔者建议,要写出稳定健壮的程序,开发人员必须有着很强的风险意识,对意外不得有侥幸心理,认认真真的尽量处理所有可能出现的风险。一个程序应该编写大量的代码来维护一个安全的环境,让功能性的代码运行得到保障。[袁永福版权所有]

 

 

本文出自 “南京袁永福” 博客,请务必保留此出处http://xdesigner.blog.51cto.com/3148541/633086