表达式&语句详解
一、表达式的定义
- 什么是表达式?
- Expressions,together with commands and declarations ,are one of the basic components of every programming language.We can say that expressions are the essential component of every language.
- An expression is a syntactic entity whose evaluation either produces a value or fails to terminate,in which case the expression is undefined.
- 各种编程语言对表达式的实现不尽相同,但大体上都符合这个定义
- C#语言对表达式的定义
- An expression is a sequence of one more operands and zero or more operation that can be evaluated to a signle value,object,method or namespace.Expressions can consist of a literal value,a method invocation,an operator and its operands,or a simple name.Simple names can be the name of a variable,type member,method parameter,namespace or type.
- 算法逻辑的最基本(最小)单元,表达一定的算法意图
- 因为操作符有优先级,所以表达式也就有了优先级
二、各类表达式概览
- C#语言中表达式的分类
- A value.Every value has an associated type.任何能得到值得运算(回顾操作符和结果类型)
- A variable.Every variable has an associated type.
- A namespace.
- A type.
- A method group.例如:Console.WriteLine,这是一组方法,重载决策决定具体调用哪一个
- A null literal.
- An anonymous function.
- A property access.
- An event access.
- An indexer access.
- Nothing.对返回值为void得方法得调用
- 复合表达式
- 注意操作符得优先级和同优先级操作符得运算方向
- 参考C#语言定义文档
- 仅作为参考,不必深究--毕竟我们是在学习语言、不是去实现这门语言
三、语句的定义
- Wikipedia对语句的定义
- In computer programming a statement is the smallest standalone element of an imperative programming language which express some antion to be carried out.A program written in such a language is formed by a sequence of one or more statements.A statement will have internal components(e.g.,expressions).
- 语句是高级的语法--汇编语言和机器语言只有指令(高级语言中的表达式对应低级语言中的指令),语句等价于一个或一组有明显逻辑的指令。
static void Main(string[] args)
{
double result= GetCylinderVolume(10, 100);
Console.WriteLine(result);
Console.Read();
}
static double GetCylinderVolume(double r, double h)
{
double area = 3.1416 * r * r;
double volume = area * h;
return volume;
}
#include <stdio.h>
double getCylinderVolume(double r, double h)
{
double area = 3.1416*r*r;
double volume = area * h;
return volume;
}
int main()
{
double result=getCylinderVolume(10, 100);
printf("volume=%f", result);
return 0;
}
- C#语言对语句的定义
- The
- C#语言的语句除了能够让程序员“顺序地”(sequentially)表达算法思想,还能通过条件判断、跳转和循环等方法控制程序逻辑的走向
- 简言之就是:陈述算法思想,控制逻辑走向,完成有意义的动作(action)
- C#语言的语句由分号(;)结尾,但由分号结尾的不一定都是语句
- 语句一定是出现在方法体里
四、语句详解
英文名 | 中文名 |
---|---|
statement: | |
$color{blue}labeled-statement$ | 标记语句 |
$color{blue}declaration-statement$ | 声明语句 |
$color{blue}embedded-statement$ | 嵌入语句 |
embedded-statement: | 嵌入语句: |
block | 块语句(简称“块”) |
empty-statement | 空语句 |
expression-statement | 表达式语句 |
selection-statement | 选择语句 |
iteration-statement | 迭代语句 |
jump-statement | 跳转语句 |
try-statement | try语句 |
checked-statement | checked语句 |
unchcdked-statement | uncheck语句 |
lock-statement | lock语句 |
using-statement | using语句 |
yield-statement | yield语句 |
//try语句
namespace StatementsExample2
{
class Program
{
static void Main(string[] args)
{
Calculator c = new Calculator();
int r = 0;
try
{
r = c.Add("", "100");
}
catch (Exception)
{
Console.WriteLine("%%##@FSAGF@!#R");
}
Console.Read();
}
}
class Calculator
{
public int Add(string arg1,string arg2)
{
bool hasError = false;
int a = 0;
int b = 0;
try
{
a = int.Parse(arg1);
b = int.Parse(arg2);
}
catch (ArgumentNullException ane)
{
Console.WriteLine(ane.Message);//("Your argument(s) are null");
hasError = true;
}
catch(FormatException fe)
{
Console.WriteLine(fe.Message);// ("Your argument(s) are not number");
hasError = true;
}
catch(OverflowException oe)
{
// Console.WriteLine(oe.Message );// ("Out of range!");
throw oe; //向上级抛出异常
}
finally
{
//第一类内容,释放系统资源的语句比如:关闭数据库
//
//第二类内容,写程序的日志
if (hasError )
{
Console.WriteLine("Execution has error!");
}
else
{
Console.WriteLine("Done!");
}
}
int result =a+b;
return result;
}
}
}
迭代语句
- while语句
- do语句
- for语句
- foreach语句
//九九乘法表
for (int a = 1; a <=9; a++)
{
for (int b = 0; b <=a; b++)
{
Console.Write
("*"); //打印三角星星
//("{0}×{1}={2} ",a,b,a*b); //打印乘法表
}
Console.WriteLine();
}
//foreach
int[] myArray = new int[] { 1, 2, 3, 4, 5 };
//Console.WriteLine(myArray .GetType ().FullName);
//Console.WriteLine(myArray is Array);
IEnumerator enumerator = myArray.GetEnumerator();
while (enumerator.MoveNext() )
{
Console.WriteLine(enumerator.Current);
}
跳转语句
- break
- continue
- goto
- return
- throw
字段属性索引器常量
类的成员:
成员 | 说明 |
---|---|
常量 | 与类关联的常量值 |
字段 | 类的变量 |
方法 | 类可执行的计算和操作 |
属性 | 与读写类的命名属性相关联的操作 |
索引器 | 与以数组方式索引类的实例相关联的操作 |
事件 | 可由类生成的通知 |
运算符 | 类所支持的转换和表达式运算符 |
构造函数 | 初始化类的实例或类本身所需的操作 |
析构函数 | 在永久丢弃类的实例之前执行的操作 |
类型 | 类所声明的嵌套类型 |
一、字段
- 什么是字段
- 字段(field)是一种表示与对象或类型(类与结构体)关联的变量
- 字段是类型的成员,旧称“成员变量”
- 与对象关联的字段亦称“实例字段”
- 与类型关联的字段称为“静态字段”,由static修饰
//字段的由来:在c语言中的体现
#include<stdio.h>
struct Student
{
int ID;
char* Name;
};
void main()
{
struct Student stu;
stu.ID = 1;
stu.Name = "Mr.Okey";
printf("Student #%d is %s", stu.ID, stu.Name);
}
//C#例子
//Student stu1 = new Student();
//stu1.Age = 40;
//stu1.Score = 90;
//Student stu2 = new Student();
//stu2.Age = 24;
//stu2.Score = 60;
//Console.WriteLine(Student.Amount);
List<Student> stuList = new List<Student>();
for (int i = 0; i < 100; i++)
{
Student stu = new Student();
stu.Age = 24;
stu.Score = i;
stuList.Add(stu);
}
int totalAge = 0;
int totalScore = 0;
foreach (var stu in stuList)
{
totalAge += stu.Age;
totalScore += stu.Score;
}
Student.AverageAge = totalAge / Student.Amount;
Student.AverageScore = totalScore / Student.Amount;
Student.ReportAmount();
Student.ReportAverageAge();
Student.ReportAverageScore();
class Student
{
public int Age;
public int Score;
public static int AverageAge;
public static int AverageScore;
public static int Amount;
public Student ()
{
Student.Amount++;
}
public static void ReportAmount()
{
Console.WriteLine(Student.Amount);
}
public static void ReportAverageAge()
{
Console.WriteLine(Student.AverageAge);
}
public static void ReportAverageScore()
{
Console.WriteLine(Student.AverageScore);
}
}
- 字段的声明
- 参见C#语言定义文档
- 尽管字段声明带有分号,但它不是语句
- 字段的名字一定是名词
- 字段的初始值
- 无显示初始化时,字段获得其类型得默认值,所以字段“永远都不会未被初始化”
- 实例字段初始化得时机--对象创建时
- 静态字段初始化得时机--类型被加载(load)时
- 只读字段
- 实例只读字段
- 静态只读字段
二、属性
- 什么是属性
- 属性(Property)是一种用于访问对象或类型得特征的成员,特征反映了状态
- 属性是字段的自然扩展
- 从命名是上看,field更偏向于实例对象在内存中的布局,property更偏向于反映现实世界对象的特征
- 对外:暴露数据,数据可以存储在字段里,也可以是动态的
- 对内:保护字段不被非法值污染
- 属性由Get/Set方法对进化而来
- 又一个“语法糖”---属性背后的秘密
class Student
{
//public int Age;
private int age;
public int GetAge()
{
return this.age;
}
public void SetAge(int value)
{
if (value <0&&value>=100)
{
this.age = value;
}
else
{
throw new Exception("Age value has error.");
}
}
public int Age
{
get
{
return this.age;
}
set
{
if (value<0&&value>=120)
{
throw new Exception("Age value has error.");
}
}
}
}
- 属性的声明
- 完整声明--后台(back)成员变量与访问器
- 简略声明--只有访问器(查看IL代码)
- 动态计算属性的值
- 属性的名字一定是名词
- 只读属性--只有getter没有setter
- 尽管语法正确,几乎没有人使用
class Person
{
private int age;
public int Age
{
get { return age; }
set
{
age = value;
CalculateCanGoToSchool();
}
}
//当不经常使用的时候:
public bool CanWork
{
get
{
if (this.age>=16)
{
return true;
}
else
{
return false;
}
}
}
private bool canGotoSchool;
//当经常使用的时候可以使用
public bool CanGotoSchool
{
get { return canGotoSchool; }
//set { };
}
private void CalculateCanGoToSchool()
{
if (this.age >5)
{
this.canGotoSchool = true;
}
else
{
this.canGotoSchool = false;
}
}
}
- 属性与字段的关系
- 一般情况下,它们都用于表示实体(对象或类型)的状态
- 属性大多数情况下是字段的包装器(wrapper)
- 建议:永远使用属性(而不是字段)来暴露数据,即字段永远都是private或protected的
三、索引器
- 什么是索引器
- 索引器(indexer)是这样一种成员:它使对象能够用与数组相同的方式(即使用下标)进行索引
- 索引器声明
- 参见C#语言定义文档
- 注意:没有静态索引器
class Student
{
private Dictionary<string, int> socoreDictionary = new Dictionary<string, int>();
public int? this[string subject]
{
get
{
if (this.socoreDictionary .ContainsKey (subject))
{
return this.socoreDictionary[subject];
}
else
{
return null;
}
/* return the specified index here */
}
set
{
if (value.HasValue==false )
{
throw new Exception("Score is null");
}
if (this.socoreDictionary.ContainsKey(subject ))
{
this.socoreDictionary[subject] = value.Value ;
}
else
{
this.socoreDictionary.Add(subject, value.Value );
}
/* set the specified index to value here */
}
}
}
四、常量
- 什么是常量
- 常量(constant)是表示常量值(即、可以再编译时进行计算的值)的类成员
- 常量隶属于类型而不是对象,即没有“实例常量”
- 实例常量“”的角色由只读字段来担当
- 注意区分成员常量与局部常量
- 常量的声明
- 各种“只读”的应用场景
- 为了提高程序可读性和执行效率---常量
- 为了防止对象的值被改变---只读字段
- 向外暴露不允许修改的数据--只读属性(静态或非静态),功能与常量有一些重叠
- 当希望称为常量的值其类型不能被常量声明接受时(类/自定以结构体)--静态只读字段