C#是一种区分大小写的语言,每行代码都以分号结束。
如果计算机程序是对数据执行操作,则说明我们需要以某种方式来存储数据,需要某些方法来处理它们。这两种功能是由变量和表达式来提供的。
1 变量
变量是有名称和类型的数据块。要使用变量,需要先声明它们,即给变量指定类型和名称。声明变量后,就可以把它们用作存储单元,存储所声明的数据类型的数据。
声明变量的C#语法仅指定类型和变量名,如下所示:
<type><name>;
1.1 简单类型
简单类型就是组成应用程序中基本构件的类型,没有子类型或特性。大多数简单类型都是存储数值的。
对于整数值,用一定的位(单个数字,可以是0或者1)来存储,用二进制格式来表示。以N位来存储的变量可以表示任何介于0或(2^N-1)之间的数。
在计算机内存中,把数字作为一系列的0或1来存储。不同的整数类型可用于存储不同范围的数值,占用不同的内存空间(至多64位)。
整数类型
类型 | 别名 | 允许的值 |
sbyte | System.SByte | 介于-128~127之间的整数 |
byte | System.Byte | 介于0~255之间的整数 |
short | System.Int16 | 介于-32768~32767的整数 |
ushort | System.UInt16 | 介于0~65535之间的整数 |
int | System.Int32 | 介于-2147483648~2147483647之间的整数 |
uint | System.UInt32 | 介于0~4294967295之间的整数 |
long | System.Int64 | 介于-9223372036854775808~9223372036854775807之间的整数 |
ulong | System.UInt64 | 介于0~18446744073709551615之间的整数 |
注:“u”是unsigned的缩写,表示不能在这些类型的变量中存储负数。
还需要存储浮点数,可以使用的浮点变量类型有三种:float、double和decimal。前两种可以用±m×2^e的形式存储浮点数。decimal使用另一种形式:±m×10^e。这三种类型所允许的m和e值,以及它们在实数中的上下限如下表所示:
浮点类型
类型 | 别名 | m的最小值 | m的最大值 | e的最小值 | e的最大值 | 近似的最小值 | 近似的最大值 |
float | System.Single | 0 | 2^24 | -149 | 104 | 1.5*×10^-45 | 3.4×10^38 |
double | System.Double | 0 | 2^53 | -1075 | 970 | 5.0×10^-324 | 1.7×10^308 |
decimal | System.Decimal | 0 | 2^96 | -28 | 0 | 1.0×10^-28 | 7.9×10^28 |
除数值类型外,还有三种简单类型,如下表所示:
类型 | 别名 | 允许的值 |
char | System.Char | 一个Unicode字符,存储0~65535之间的整数 |
bool | System.Boolean | 布尔值:true或false |
string | System.String | 一个字符序列 |
注:组成string的字符数量没有上限,因为它可以使用可变大小的内存。
1.2 变量的命名
基本的变量命名规则如下:
- 变量名的第一个字符必须是字母、下划线(_)或@。
- 其后的字符可以是字母、下划线(_)或数字。
1.3 字面值
使用=赋值运算符给变量分配固定的值(在代码中称为字面值)。字面值的后面添加一些字符类型来指定想要的类型。一些字面值有多种类型,在编译时由编译器根据它们的上下文确定其类型。
字面值
类型 | 类别 | 后缀 | 示例/允许的值 |
bool | 布尔 | 无 | true 或 false |
int、uint、long、ulong | 整数 | 无 | 100 |
uint、ulong | 整数 | u或U | 100U |
long、ulong | 整数 | l或L | 100L |
ulong | 整数 | ul、uL、Ul、UL、lu、lU、Lu或LU | 100UL |
float | 实数 | f或F | 1.5F |
double | 实数 | 无、d或D | 1.5 |
decimal | 实数 | m或M | 1.5M |
char | 字符 | 无 | ‘a’或转义序列 |
string | 字符串 | 无 | ‘a…a’,可以包含转义序列 |
1.3.1 数字分隔符
适用于二进制、十进制、浮点数和双精度数。下面的代码在表示Pi的值时,每三位使用了一个分隔符。使用数字分隔符有助于增强代码的可读性。
public const double Pi = 3.141_592_653_589_793_238_462_643_383_279_502;
1.3.2 字符串字面值
可以一字不变的指定字符串,即两个双引号之间的所有字符都包含在字符串中,包括行末字符和原本需要转义的字符。唯一的例外是必须指定双引号字符的转义序列,以免结束字符串。这种方法需要在字符串之前加一个@字符。
一字不变的字符串在文件名中非常有用,因为文件名中大量使用了反斜杠字符。如果使用一般字符串,就必须在字符串中使用两个反斜杠,例如:
“C:\\Temp\\MyDir\\MyFile.doc”
而有了一字不变的字符串字面值,这段代码更便于阅读。下面的字符串与上面的等价:
@“C:\Temp\MyDir\MyFile.doc”
必须使用@字符的情况:
@“A short list:
item 1
item 2”
注:字符串是引用类型,而本章的其他类型都是值类型。所以,字符串也可以被赋予null值,表示字符串变量不引用字符串(或其他任何东西)。
2 表达式
把变量和字面值(在使用运算符时,它们都称为操作数)与运算符组合起来,就可以创建表达式,它是计算的基本构件。
运算符大致分为如下三类:
- 一元运算符,处理一个操作数;
- 二元运算符,处理两个操作数;
- 三元运算符,处理三个操作数。
2.1 数学运算符
数学运算符对数值进行操作。
简单的数学运算符
运算符 | 类别 | 示例表达式 | 结果 |
+ | 二元 | var 1 = var 2 + var 3; | var 1的值是var 2和var 3的和 |
- | 二元 | var 1 = var 2 - var 3; | var 1的值是从var 2减去var 3所得的值 |
* | 二元 | var 1 = var 2 * var 3; | var 1的值是var 2与var 3的乘积 |
/ | 二元 | var 1 = var 2 / var 3; | var 1的值是var 2除以var 3所得的值 |
% | 二元 | var 1 = var 2 % var 3; | var 1的值是var 2除以var 3所得的余数 |
+ | 一元 | var 1 = +var 2; | var 1的值等于var 2的值 |
- | 一元 | var 1 = -var 2; | var 1的值等于var 2的值乘以-1 |
二元运算符+在用于字符串类型变量时,也是有意义的。但其他数学运算符不能用于处理字符串。
运算符 | 类别 | 示例表达式 | 结果 |
+ | 二元 | var 1 = var 2 + var 3; | var 1的值是存储在var 2和var 3中的两个字符串的连接值。 |
递增和递减运算符都是一元运算符,可通过两种方式来使用它们:放在操作数的前面或后面。
递增和递减运算符
运算符 | 类别 | 示例表达式 | 结果 |
++ | 一元 | var 1 = ++var 2; | var 1的值是var 2 + 1,var2 递增1 |
-- | 一元 | var 1 = --var 2; | var 1的值是var 2 - 1,var2 递减1 |
++ | 一元 | var 1 = var 2++; | var 1的值是var 2,var 2递增1 |
-- | 一元 | var 1 = var 2--; | var 1的值是var 2,var 2递减1 |
这些运算符会改变存储在操作数中的值:
- ++总是使操作数加1
- --总是使操作数减1
var 1中存储的结果有区别,其原因是运算符的位置决定了它什么时候发挥作用。把运算符放在操作数的前面,则操作数是在进行任何其他计算前受到运算符的影响;而如果把运算符放在操作数的后面,则操作数是在完成表达式的计算后受到运算符的影响。
2.2 赋值运算符
赋值运算符,与=一样,它们都是根据运算符和右边的操作数,把一个值赋给左边的变量。(把表达式的结果放到变量中)
赋值运算符
运算符 | 类别 | 示例表达式 | 结果 |
= | 二元 | var1 = var2; | var1被赋予var2的值 |
+= | 二元 | var1 += var2; | var1被赋予var1与var2的和 |
-= | 二元 | var1 -= var2; | var1被赋予var1与var2的差 |
*= | 二元 | var1 *= var2; | var1被赋予var1与var2的乘积 |
/= | 二元 | var1 /= var2; | var1被赋予var1与var2相除所得的结果 |
%= | 二元 | var1 %= var2; | var1被赋予var1与var2相除所得的余数 |
注:与+运算符一样,+=运算符也可以用于字符串。
2.3 运算符的优先级
优先级相同的运算符按照从左到右的顺序计算。括号可用于重写优先级顺序。
运算符的优先级
优先级 | 运算符 |
优先级由高到低 | ++、--(用作前缀)、+、-(一元) |
*、/、% | |
+、- | |
=、*=、/=、%=、+=、-= | |
==、--(用作后缀) |
3 名称空间
.NET应用程序中定义的所有名称,包括变量名,都包含在名称空间中。
命名空间是.NET中提供应用程序代码容器的方式,可以唯一的标识代码及其内容。名称空间也用作.NET Framework中给项分类的一种方式。大多数项都是类型定义。可使用namespace关键字为花括号中的代码块显式定义名称空间。
如果在该名称空间代码的外部使用名称空间中的名称,就必须写出该名称空间中的限定名称。限定名称包括它所有的分层信息。(名称空间采用层次结构)
扩展:二进制模式匹配、位掩码