C#是什么?
C#发音为“C-Sharp”。它是由Microsoft开发提供的面向对象的编程语言,它在.Net Framework上运行。
我们可以使用C#编程语言开发不同类型的安全和强大的应用程序,这些应用程序包括:
- 窗口应用程序
- Web应用程序
- 分布式应用
- Web服务应用程序
- 数据库应用等C# 是被ECMA和ISO认可为标准。 C# 是为CLI(通用语言基础设施)设计的。 CLI是描述可执行代码和运行时环境的规范。C# 编程语言的语法和设计思想受C++,Java,Eiffel,Modula-3,Pascal等语言的影响。
与C++比较
C++编程语言和 C# 之间存在许多差异和相似之处。C++和 C# 之间的最大区别,如列表中所示:
| 序号 | C++语言 | C#语言 |
|---|---|---|
| 1 | C++是一种通用的,区分大小写的自由格式的编程语言,支持面向对象,程序和通用编程。 | C# 发音为“C-Sharp”。它是由Microsoft开发提供的面向对象的编程语言,它在.Net Framework上运行。 |
| 2 | 在C++中,可以使用多重继承。 | 在 C# 中,不可以使用多重继承。 |
| 3 | 在C++中,内存管理是手动处理的。 | 在 C# 中,内存管理被自动处理。 |
| 4 | 在C++中,指针可以在程序的任何地方使用。 | 在 C# 中,指针只能在不安全模式下使用。 |
| 5 | C++编程基于面向对象(OOPs)概念。 | C# 编程基于组件(Component)和面向对象(OOPs)概念。 |
| 6 | C++是一种在所有平台上运行的编程语言。 | C# 是Windows之外很少使用的编程语言。 |
| 7 | C++编程可用于创建控制台应用程序。 | C# 编程可用于创建控制台应用程序,Windows应用程序,移动应用程序等。 |
与Java比较
JAVA编程语言和 C# 之间存在许多差异和相似之处。Java和 C# 之间的最大区别,如列表中所示:
| 序号 | JAVA语言 | C#语言 |
|---|---|---|
| 1 | Java是由Sun公司开发的高级,强大,安全和面向对象的编程语言。现已被Oracle收购 | C# 是由Microsoft开发的面向对象编程语言,它运行在.Net Framework上。 |
| 2 | Java编程语言程序是通过Java运行时环境(JRE)的帮助下,在Java平台上运行。 | C# 编程语言是在一种叫作公共语言运行时(CLR)上运行。 |
| 3 | Java类型的安全是安全的。 | C# 型安全是不安全的。 |
| 4 | 在java中,通过值传递的内置数据类型称为基本类型。 | 在 C# 中,通过值传递的内置数据类型称为简单类型。 |
| 5 | Java中的数组是由Object直接指定。 | C# 中的数组是System直接指定。 |
| 6 | Java不支持条件编译。 | C# 支持使用预处理指令的条件编译。 |
| 7 | Java不支持goto语句。 | C# 支持goto语句。 |
| 8 | Java不支持通过类的多重继承,它可以通过java中的接口来实现。 | C# 支持使用类的多继承。 |
| 9 | Java不支持结构体和联合体。 | C# 支持结构体和联合体。 |
| 10 | Java支持检查异常和未检查的异常。 | C# 支持未经检查的异常。 |
历史
C# 语言的历史很有意思。但这里我们将讨论 C# 语言的简史。
C# 发音为“C-Sharp”。它是由Microsoft开发提供的面向对象的编程语言,它在.Net Framework上运行。
C# 它基于C++和Java,但它有许多额外的扩展用于执行面向组件的编程方法。
自从2002年第一次发布以来, C# 已经开发很多功能并成熟。它是由.NET Framework 1.0引入的, C# 当前版本是:C# 5.0。
下面来看看 C# 每个版本中的重要功能 -
- 简单
- 现代编程语言
- 面向对象
- 类型安全
- 互通性
- 可扩展和可更新
- 面向组件
- 结构化编程语言
- 丰富类库
- 速度快
入门程序
在 C# 编程语言中,可以通过多种方式编写一个简单的“hello world”程序。 我们来看看创建简单 C# 示例的4种方法:
- 简单的例子
- using System
- using public修饰符
- using namespace
1. C# 简单的例子
首先打开Visual Studio 2017社区版,如下图所示 -
点击“文件”->“新建”->“项目”,创建一个名称为:helloworld的项目,如下图所示 -
创建完成项目后,也会自动生成文件及代码,如下所示 -
现在将源文件:Program.cs的代码修改为以下 -
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine("Hello World!");
}
}
点击顶上的主菜单:调试(D)->开始执行(不调试),执行编译并运行得到以下结果 -
有关上面简单程序的说明 -
- class:这是用于定义类的关键字。
- Program:这是一个类的名称。类是创建对象的蓝图或模板,它可以有数据成员和方法。 在上面代码中,它只有一个
Main方法。 - static:是一个关键字,意味着对象不需要访问静态成员,所以可以节省内存。
- void:方法的返回类型。 它没有返回任何值。 在这种情况下,不需要使用
return语句。 - Main:是方法名称。它是任何 C# 程序的切入点。每当运行 C# 程序时,都会先调用
Main()方法。它表示了程序的启动点。 - string [] args:用于 C# 中的命令行参数。在运行 C# 程序时,可以传递值。这些值称为参数,它们可在程序中使用。
- System.Console.WriteLine(“Hello World!”):这里,
System是命名空间。Console是在System命名空间中定义的类。WriteLine()是Console类的静态方法,用于在控制台上写入文本并显示。
2. C# 示例:using System
如果我们在类之前编写using System语句,这意味着不需要指定System命名空间来访问此命名空间的任何类。在这里,可直接使用Console类而不需要再指定System.Console。参考如下代码 -
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World! - By using System. ");
}
}
点击顶上的主菜单:调试(D)->开始执行(不调试),执行编译并运行得到以下结果 -
3. C# 示例:使用public修辞符
还可以在类和Main()方法之前指定public修辞符。现在,也可以从类外访问了。如下示例代码 -
using System;
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World! - By using public modifier. ");
}
}
点击顶上的主菜单:调试(D)->开始执行(不调试),执行编译并运行得到以下结果 -
4. C# 示例:使用命名空间
可以在命名空间内创建类,用于分组相关类。它用于对类进行分类,以使其易于维护。
using System;
namespace ConsoleApplication1
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World! - By using namespace. ");
}
}
}
点击顶上的主菜单:调试(D)->开始执行(不调试),执行编译并运行得到以下结果 -
程序结构
在学习 C# 编程语言的基本构建块之前,先来看一下最简单的 C# 程序结构,以便将其作为即后续章节的学习参考。
创建Hello World程序
这个简单的 C# 程序由以下部分组成:
- 命名空间声明
- 一个类
- 类方法
- 类属性
- 主(Main)方法
- 声明和表达
- 注释
下面让我们来看一个打印“Hello World”的简单代码:
using System;
namespace HelloWorldApplication{
class HelloWorld{
static void Main(string[] args){
/* my first program in C# */
Console.WriteLine("Hello World");
Console.ReadKey();
}
}
}
当编译和执行这段代码时,它产生以下结果:
Hello World
下面来看看给定的示例程序的各个部分:
- 程序的第一行
using System;-using关键字用于在程序中包含System命名空间。程序中通常有多个using语句。 - 第二行是命名空间(
namespace)声明。namespace是类的集合。HelloWorldApplication命名空间包含HelloWorld类。 - 第三行是一个类声明,
HelloWorld类包含程序使用的数据和方法定义。类通常包含多种方法。方法定义类的行为。 但是这定义的HelloWorld类只有一个Main方法。 - 第四行定义了
Main方法,它是所有 C# 程序的入口点。Main方法执行该类的操作。 - 第五行是只是一个程序代码注释,编译器忽略代码中的
/*...*/之间的内容。 - 第六行是
Main方法的具体功能实现,这里只是使用语句Console.WriteLine(“Hello World”)指定其行为; WriteLine是在System命名空间中定义的Console类的一个方法。此方法将消息“Hello, World!”显示在屏幕上。- 最后一行
Console.ReadKey();是用于使程序等待按键,并且当从Visual Studio .NET启动程序时,它可以防止屏幕快速运行和关闭。
需要注意的是:
- C# 区分大小写。
- 所有语句和表达式必须以分号(
;)结尾。 - 程序执行从
Main方法开始。 - 与Java不同,程序文件名可以与类名不同。
编译和执行程序
如果使用Visual Studio.Net编译和执行 C# 程序,请执行以下步骤:
- 启动Visual Studio。
- 在菜单栏上,选择文件 -> 新建 -> 项目。
- 从模板中选择Visual C# ,然后选择Windows。
- 选择控制台应用(Console Application)。
- 指定项目的名称,然后单击确定(Ok)按钮。
- 这将在解决方案资源管理器(Solution Explorer)中创建一个新项目。
- 在代码编辑器中编写代码。
- 单击启动按钮或按F5键执行项目。将出现一个包含
"Hello World"行的命令提示符窗口。
可以使用命令行(而不是Visual Studio IDE)来编译 C# 程序:
- 打开文本编辑器并添加上述代码。
- 将文件保存为helloworld.cs
- 打开命令提示符工具,并转到保存文件的目录。
- 键入
csc helloworld.cs,然后按Enter键编译代码。 - 如果您的代码没有错误,命令提示符将转到下一行并生成
helloworld.exe可执行文件。 - 键入
helloworld来执行你的程序。 - 这时可在屏幕上看到输出的
"Hello World"字符串了。
基本语法
C# 是面向对象的编程语言。在面向对象编程方法中,程序由通过动作相互交互的各种对象组成。 对象可能采取的操作称为方法。具有相同类型的对象认为是相同的类型,或者说是在同一个类。
例如,假设有一个Rectangle对象。 它有长度(length)和宽度(width)的属性。 根据设计,它可能需要接受这些属性的值,计算面积和显示细节的方法。
下面我们来看看Rectangle类是如何实现上述功能,并以此学习 C# 的基本语法:
using System;
namespace RectangleApplication
{
class Rectangle
{
// member variables
double length;
double width;
public void Acceptdetails()
{
length = 10.0;
width = 20.1;
}
public double GetArea()
{
return length * width;
}
public void Display()
{
Console.WriteLine("Length: {0}", length);
Console.WriteLine("Width: {0}", width);
Console.WriteLine("Area: {0}", GetArea());
}
}
class ExecuteRectangle
{
static void Main(string[] args)
{
Rectangle r = new Rectangle();
r.Acceptdetails();
r.Display();
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Length: 10.0
Width: 20.1
Area: 201
using关键字
任何 C# 程序中的第一个语句一般是:
using System;
using关键字用于在程序中包含命名空间。程序可以包括多个using语句。
class关键字
class关键字用于声明一个类。
C# 中的注释
注释用于解释代码。编译器忽略注释中的任何内容。 C# 程序中的多行注释以/*开始,并以*/结尾,如下所示:
/* This program demonstrates
The basic syntax of C# programming
Language */
单行注释由“//”符号表示。 例如,
}//end class Rectangle
// 另一个行注释
成员变量
变量是用于存储类的属性或数据成员的数据。在前面的程序中,Rectangle类有两个名为length和width的成员变量。
成员函数
函数是执行特定任务的语句集合。类的成员函数在类中声明。我们的示例类Rectangle包含三个成员函数:AcceptDetails,GetArea和Display。
实例化类
在上述程序中,ExecuteRectangle类包含Main()方法,并实例化了一个Rectangle类的实例:r。
标识符
标识符是用于标识类,变量,函数或任何其他用户定义项目的名称。 C# 中命名类的基本规则如下:
- 名称必须以字母开头,后面可以有一系列字母,数字(
0 - 9)或下划线(_)。 标识符中的第一个字符不能为数字。 - 它不能包含任何嵌入的空格或符号,如:
?,-,+,!,@,#,%,^,&,*,(,),[,],{,},.,;,:,",',/和\。但是,可以使用下划线(_)。 - 它不能是 C# 关键字。
C# 关键字
关键字是预定义为 C# 编译器的保留字。 这些关键字不能用作标识符。 但是,如果要使用这些关键字作为标识符,但可以使用@字符将关键字前缀来表示某一标识符。
在 C# 中,一些标识符在代码的上下文中具有特殊意义,例如get和set被称为上下文关键字。
下表列出了 C# 中的保留关键字和上下文关键字:
保留关键字
| abstract | as | base | bool | break | byte | case |
|---|---|---|---|---|---|---|
| catch | char | checked | class | const | continue | decimal |
| default | delegate | do | double | else | enum | event |
| explicit | extern | false | finally | fixed | float | for |
| foreach | goto | if | implicit | in | in (generic modifier) | int |
| interface | internal | is | lock | long | namespace | new |
| null | object | operator | out | out (generic modifier) | override | params |
| private | protected | public | readonly | ref | return | sbyte |
| sealed | short | sizeof | stackalloc | static | string | struct |
| switch | this | throw | true | try | typeof | uint |
| ulong | unchecked | unsafe | ushort | using | virtual | void |
| volatile | while | - | - | - | - | - |
上下文关键字
| add | alias | ascending | descending | dynamic | from | get |
|---|---|---|---|---|---|---|
| global | group | into | join | let | orderby | partial (type) |
| partial(method) | remove | select | set | - | - | - |
变量
变量是内存位置的名称。 它用于存储数据。 其值可以更改,可以重复使用多次。
它是通过符号表示存储器位置的方式,以便可以容易地识别。
C# 中的每个变量都有一个特定的类型,它决定了变量内存的大小和布局,可以存储在该存储器中的值的范围以及可应用于该变量的一组操作。
C# 中提供的基本值类型可以分为:
| 类型 | 示例 |
|---|---|
| 整型 | sbyte, byte, short, ushort, int, uint, long, ulong, 和 char |
| 浮点型 | float 和 double |
| 十进制类型 | decimal |
| 布尔类型 | true 或 false, 作为分配 |
| 可空类型 | 可空(null)数据类型 |
C# 还允许定义变量的其他值类型,例如:枚举和引用类型的变量,如类,我们将在后续章节中介绍。
定义变量
C# 中变量定义的语法是:
data_type variable_list;
这里,data_type必须是一个有效的 C# 数据类型,包括:char,int,float,double或任何用户定义的数据类型,而variable_list可能由一个或多个以逗号分隔的标识符名称组成。
一些有效的变量定义如下所示:
int i, j, k;
char c, ch;
float f, salary;
double d;
可以在定义时将变量初始化为:
int i = 1999;
初始化变量
变量可以初始化(使用一个等号=来赋值),后跟一个常量表达式。初始化的一般形式是:
variable_name = value;
变量可以在其声明中进行初始化。初始化程序包含一个等号(=),后跟一个常量表达式为:
<data_type> <variable_name> = value;
变量初始化的一些例子:
int d = 3, f = 5; /* initializing d and f. */
byte z = 22; /* initializes z. */
double pi = 3.14159; /* declares an approximation of pi. */
char x = 'x'; /* the variable x has the value 'x'. */
正确初始化变量是一个很好的编程实践,否则程序可能会产生意想不到的结果。
以下示例使用各种类型的变量:
using System;
namespace VariableDefinition
{
class Program
{
static void Main(string[] args)
{
short a;
int b ;
double c;
/* actual initialization */
a = 10;
b = 20;
c = a + b;
Console.WriteLine("a = {0}, b = {1}, c = {2}", a, b, c);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
a = 10, b = 20, c = 30
从用户接受值
System命名空间中的Console类提供了一个用于接受用户输入并将其存储到变量中的ReadLine()函数。
示例
int num;
num = Convert.ToInt32(Console.ReadLine());
函数Convert.ToInt32()将用户输入的数据转换为int数据类型,因为Console.ReadLine()函数是接受字符串格式的数据。
C# 中的左值和右值表达式:
C# 中有两种表达式:
- 左值(
lvalue):一个左值或右值的表达式可表示为左值或右侧。 - 右值(
rvalue):一个右值表达式可出现在赋值的右侧,而不是左侧。
变量是左值,因此它们可能出现在赋值的左侧。数字文字值是右值,因此它们可能不被赋值,不能出现在左侧。 以下是一个有效的 C# 语句:
int g = 20;
但是以下不是有效的语句,并且会生成编译时错误:
10 = 20;
定义变量的规则
有关定义变量的规则如下所示 -
- 一个变量可以有字母,数字和下划线。
- 变量名称只能以字母和下划线开头。
- 它不能以数字开头。
- 变量名称内不允许有空格。
- 变量名称不能是任何保留字或关键词。如:
char,float等
下面是一些有效的变量名:
int x;
int _x;
int k20;
下面是一些无效的变量名:
int 4;
int x y;
int double;
数据类型
数据类型指定变量可以存储的数据的类型,如:整数,浮点,字符等。
C# 语言中有3种类型的数据类型。如下表中所示 -
| 类型 | 数据类型 |
|---|---|
| 值数据类型 | int, char, float, Boolean等 |
| 引用数据类型 | 字符串,类,对象和接口 |
| 指针数据类型 | 指针 |
值数据类型
值数据类型是基于整数和基于浮点数。 C# 语言支持有符号和无符号文字值。
C# 语言中有两种类型的值数据类型。
- 预定义的数据类型 - 如整型,布尔型,浮点型等
- 用户定义的数据类型 - 如结构,枚举等
数据类型的内存大小可能会根据32位或64位操作系统而不同。我们来看看值数据类型。它的大小根据32位操作系统给出。
| 数据类型 | 内存大小 | 范围 |
|---|---|---|
| char | 1 byte | -128 to 127 |
| signed char | 1 byte | -128 to 127 |
| unsigned char | 1 byte | 0 to 127 |
| short | 2 byte | -32,768 to 32,767 |
| signed short | 2 byte | -32,768 to 32,767 |
| unsigned short | 2 byte | 0 to 32,767 |
| int | 2 byte | -32,768 to 32,767 |
| signed int | 2 byte | -32,768 to 32,767 |
| unsigned int | 2 byte | 0 to 32,767 |
| short int | 2 byte | -32,768 to 32,767 |
| signed short int | 2 byte | -32,768 to 32,767 |
| unsigned short int | 2 byte | 0 to 32,767 |
| long int | 4 byte | |
| signed long int | 4 byte | |
| unsigned long int | 4 byte | |
| float | 4 byte | |
| double | 8 byte | |
| long double | 10 byte | - |
要在特定平台上获取类型或变量的确切大小,可以使用sizeof方法。 表达式sizeof(type)产生对象或类型的存储大小(以字节为单位)。以下是在任何机器上获取double类型的大小的示例:
using System;
namespace DataTypeApplication
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Size of double: {0}", sizeof(double));
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Size of double: 8
引用数据类型
引用数据类型不包含存储在变量中的实际数据,但它们包含对变量的引用。如果一个变量的数据值被更改,则这个变量将自动反映该值的变化。
C# 语言中有两种类型的引用数据类型。
- 预定义类型 - 如对象,字符串。
- 用户定义的类型 - 如类,接口。
内置引用类型的示例有:object,dynamic和string。
对象类型
对象类型是 C# 通用类型系统(CTS)中所有数据类型的最终基类。
当一个值类型转换为对象类型时,它被称为装箱,另一方面,当对象类型转换为值类型时,称为拆箱。
object obj;
obj = 100; // this is boxing
动态类型
可以在动态数据类型变量中存储任何类型的值。这些类型的变量的类型检查在运行时进行。
声明动态类型的语法是:
dynamic <variable_name> = value;
例如,
dynamic d = 20;
字符串类型
字符串类型允许为变量分配任何字符串值。String类型是System.String类的别名。 它是从Object类型派生的。可以使用两种形式的字符串文字来分配字符串类型的值:quoted和@quoted。
示例
String str = "Yiibai Point";
@quoted字符串文字如下所示:
String str = "Yiibai Point";
指针数据类型
C# 语言中的指针是变量,也称为定位符或指示符,指向值的地址。
指针中使用的符号
| 符号 | 名称 | 说明 |
|---|---|---|
& |
地址运算符 | 获取变量的地址 |
* |
间接运算符 | 访问地址的值 |
声明一个指针
C# 语言中的指针可以使用*(星号符号)声明。
int * a; //pointer to int
char * c; //pointer to char
类型转换
类型转换可将一种类型的数据转换为另一种类型。它也被称为类型铸造。在 C# 中,类型转换有两种形式:
- 隐式类型转换 - 这种类型的转换由 C# 以类型安全的方式执行。例如,从小到大的整数类型的转换和从派生类到基类的转换。
- 显式类型转换 - 这种类型的转换由使用预定义函数的用户明确定义来完成,显式转换需要转换运算符。
以下示例显示了显式类型转换用法:
using System;
namespace TypeConversionApplication
{
class ExplicitConversion
{
static void Main(string[] args)
{
double d = 9999.98;
int i;
// cast double to int.
i = (int)d;
Console.WriteLine(i);
Console.ReadKey();
}
}
}
当编译和执行上述代码时,会产生以下结果:
9999
C# 类型转换方法
C# 提供以下内置类型转换方法:
| 序号 | 方法 | 描述 |
|---|---|---|
| 1 | ToBoolean() |
如果可能,将类型转换为布尔值。 |
| 2 | ToByte() |
将类型转换为字节类型值。 |
| 3 | ToChar() |
如果可能,将类型转换为单个Unicode字符。 |
| 4 | ToDateTime() |
将类型(整数或字符串类型)转换为日期时间结构。 |
| 5 | ToDecimal() |
将浮点或整数类型转换为十进制类型。 |
| 6 | ToDouble() |
将类型转换为Double类型。 |
| 7 | ToInt16() |
将类型转换为16位整数。 |
| 8 | ToInt32() |
将类型转换为32位整数。 |
| 9 | ToInt64() |
将类型转换为64位整数。 |
| 10 | ToSbyte() |
将类型转换为有符号字节类型。 |
| 11 | ToSingle() |
将类型转换为小浮点数。 |
| 12 | ToString() |
将类型转换为字符串。 |
| 13 | ToType() |
将类型转换为指定的类型。 |
| 14 | ToUInt16() |
将类型转换为unsigned int类型。 |
| 15 | ToUInt32() |
将类型转换为unsigned double类型。 |
| 16 | ToUInt64() |
将类型转换为无符号大整数。 |
以下示例将各种值类型转换为字符串类型:
using System;
namespace TypeConversionApplication
{
class StringConversion
{
static void Main(string[] args)
{
int i = 75;
float f = 53.005f;
double d = 2345.7652;
bool b = true;
Console.WriteLine(i.ToString());
Console.WriteLine(f.ToString());
Console.WriteLine(d.ToString());
Console.WriteLine(b.ToString());
Console.ReadKey();
}
}
}
当编译和执行上述代码时,会产生以下结果:
75
53.005
2345.7652
True
常量和文字
常量是指程序在执行过程中可能不会改变的固定值。这些固定值也称为文字。 常量可以是任何基本数据类型,如整数常量,浮点常量,字符常量或字符串文字。还有枚举常数。
常量被视为常规变量,常量的值在定义之后是不能被修改的。
整数文字
整数文字(常量)可以是十进制或十六进制常数。前缀指定基数:十六进制的0x或0X,十进制的前缀不存在。
整数常量也可以具有分别为unsigned和long,使用U和L后缀来表示。 后缀可以是大写或小写,可以是任何顺序。
以下是一些整数文字的例子:
212 /* 合法 */
215u /* 合法 */
0xFeeL /* 合法 */
以下是各种类型的整数文字的其他示例:
浮点文字
浮点文字具有整数部分,小数点,小数部分和指数部分。 您可以以十进制形式或指数形式表示浮点文字。
以下是浮点文字的一些示例:
3.14159 /* Legal */
314159E-5F /* Legal */
510E /* Illegal: incomplete exponent */
210f /* Illegal: no decimal or exponent */
.e55 /* Illegal: missing integer or fraction */
以十进制格式表示,则必须包括小数点,指数或两者; 并且在使用指数形式表示时,必须包括整数部分,小数部分或两者。有符号指数由e或E引入表示。
字符常数
字符文字用单引号括起来。例如,'x'可以存储在char类型的简单变量中。字符文字可以是一个简单的字符(如'x'),一个转义序列(如'\t')或一个通用字符(如'\u02C0')表示。
在 C# 前面有一个反斜杠,有一些字符。 它们具有特殊的含义,它们用于表示像换行符(\n)或标签(\t)。下面列出的是一些转义序列码的列表:
| 转义序列 | 含义 |
|---|---|
\\ |
\字符 |
\' |
'字符 |
\" |
"字符 |
\? |
?字符 |
\a |
警戒或响铃 |
\b |
退格符 |
\f |
换页 |
\n |
新行 |
\r |
回车 |
\t |
水平制表 |
\v |
水直制表 |
\xhh . . . |
一个或多个数字的十六进制数字 |
以下是几个转义序列字符的示例:
using System;
namespace EscapeChar
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello\tWorld\n\n");
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Hello World
字符串文字
字符串文字或常量用双引号""或@""括起来。字符串包含与字符文字类似的字符:纯字符,转义序列和通用字符。
可以使用字符串文字将长行分成多行,并使用空格分隔部分。
以下是字符串文字的一些示例。以下这三种形式都是表示相同的字符串。
"hello, dear"
"hello, \
dear"
"hello, " "d" "ear"
@"hello dear"
定义常量
常量是使用const关键字来定义的。定义常量的语法是:
const <data_type> <constant_name> = value;
以下程序演示如何在程序中定义和使用常量:
using System;
namespace DeclaringConstants
{
class Program
{
static void Main(string[] args)
{
const double pi = 3.14159;
// constant declaration
double r;
Console.WriteLine("Enter Radius: ");
r = Convert.ToDouble(Console.ReadLine());
double areaCircle = pi * r * r;
Console.WriteLine("Radius: {0}, Area: {1}", r, areaCircle);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Enter Radius:
100
Radius: 100, Area: 31415.9
运算符
运算符只是一个用于执行操作的符号。可以有许多类型的操作,如算术,逻辑,按位等运算操作。
有以下类型的运算符可以在 C# 语言中执行不同类型的操作运算。
- 算术运算符
- 关系运营商
- 逻辑运算符
- 按位运算符
- 赋值运算符
- 其它运算符
1. 算术运算符
下面示例代码演示 C# 如何使用算术运算符。假设变量A的值为:10,变量B的值为:20,参考以下示例代码:
using System;
namespace OperatorsAppl
{
class Program
{
static void Main(string[] args)
{
int a = 21;
int b = 10;
int c;
c = a + b;
Console.WriteLine("Line 1 - Value of c is {0}", c);
c = a - b;
Console.WriteLine("Line 2 - Value of c is {0}", c);
c = a * b;
Console.WriteLine("Line 3 - Value of c is {0}", c);
c = a / b;
Console.WriteLine("Line 4 - Value of c is {0}", c);
c = a % b;
Console.WriteLine("Line 5 - Value of c is {0}", c);
c = a++;
Console.WriteLine("Line 6 - Value of c is {0}", c);
c = a--;
Console.WriteLine("Line 7 - Value of c is {0}", c);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Line 1 - Value of c is 31
Line 2 - Value of c is 11
Line 3 - Value of c is 210
Line 4 - Value of c is 2
Line 5 - Value of c is 1
Line 6 - Value of c is 22
Line 7 - Value of c is 20
2. 关系运算符
下面示例代码演示 C# 如何使用关系运算符。 假设变量A的值为:10,变量B的值为:20,参考以下示例代码:
using System;
class Program
{
static void Main(string[] args)
{
int a = 21;
int b = 10;
if (a == b)
{
Console.WriteLine("Line 1 - a is equal to b");
}
else
{
Console.WriteLine("Line 1 - a is not equal to b");
}
if (a < b)
{
Console.WriteLine("Line 2 - a is less than b");
}
else
{
Console.WriteLine("Line 2 - a is not less than b");
}
if (a > b)
{
Console.WriteLine("Line 3 - a is greater than b");
}
else
{
Console.WriteLine("Line 3 - a is not greater than b");
}
/* Lets change value of a and b */
a = 5;
b = 20;
if (a <= b)
{
Console.WriteLine("Line 4 - a is either less than or equal to b");
}
if (b >= a)
{
Console.WriteLine("Line 5-b is either greater than or equal to b");
}
}
}
当编译和执行上述代码时,会产生以下结果:
Line 1 - a is not equal to b
Line 2 - a is not less than b
Line 3 - a is greater than b
Line 4 - a is either less than or equal to b
Line 5 - b is either greater than or equal to b
3. 逻辑运算符
下面示例代码演示 C# 如何使用逻辑运算符。 假设变量A是一个布尔值:true,变量B是一个布尔值:false,参考以下示例代码:
using System;
namespace OperatorsAppl
{
class Program
{
static void Main(string[] args)
{
bool a = true;
bool b = true;
if (a && b)
{
Console.WriteLine("Line 1 - Condition is true");
}
if (a || b)
{
Console.WriteLine("Line 2 - Condition is true");
}
/* lets change the value of a and b */
a = false;
b = true;
if (a && b)
{
Console.WriteLine("Line 3 - Condition is true");
}
else
{
Console.WriteLine("Line 3 - Condition is not true");
}
if (!(a && b))
{
Console.WriteLine("Line 4 - Condition is true");
}
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Line 1 - Condition is true
Line 2 - Condition is true
Line 3 - Condition is not true
Line 4 - Condition is true
4. 位运算符
下面将通过示例来演示 C# 如何使用按位运算符。 假设变量A的值为:60,变量B的值为:13,参考以下示例代码:
using System;
namespace OperatorsAppl
{
class Program
{
static void Main(string[] args)
{
int a = 60; /* 60 = 0011 1100 */
int b = 13; /* 13 = 0000 1101 */
int c = 0;
c = a & b; /* 12 = 0000 1100 */
Console.WriteLine("Line 1 - Value of c is {0}", c );
c = a | b; /* 61 = 0011 1101 */
Console.WriteLine("Line 2 - Value of c is {0}", c);
c = a ^ b; /* 49 = 0011 0001 */
Console.WriteLine("Line 3 - Value of c is {0}", c);
c = ~a; /*-61 = 1100 0011 */
Console.WriteLine("Line 4 - Value of c is {0}", c);
c = a << 2; /* 240 = 1111 0000 */
Console.WriteLine("Line 5 - Value of c is {0}", c);
c = a >> 2; /* 15 = 0000 1111 */
Console.WriteLine("Line 6 - Value of c is {0}", c);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Line 1 - Value of c is 12
Line 2 - Value of c is 61
Line 3 - Value of c is 49
Line 4 - Value of c is -61
Line 5 - Value of c is 240
Line 6 - Value of c is 15
5. 赋值运算符
有关 C# 如何使用赋值运算符,请参考以下示例代码:
using System;
namespace OperatorsAppl
{
class Program
{
static void Main(string[] args)
{
int a = 21;
int c;
c = a;
Console.WriteLine("Line 1 - = Value of c = {0}", c);
c += a;
Console.WriteLine("Line 2 - += Value of c = {0}", c);
c -= a;
Console.WriteLine("Line 3 - -= Value of c = {0}", c);
c *= a;
Console.WriteLine("Line 4 - *= Value of c = {0}", c);
c /= a;
Console.WriteLine("Line 5 - /= Value of c = {0}", c);
c = 200;
c %= a;
Console.WriteLine("Line 6 - %= Value of c = {0}", c);
c <<= 2;
Console.WriteLine("Line 7 - <<= Value of c = {0}", c);
c >>= 2;
Console.WriteLine("Line 8 - >>= Value of c = {0}", c);
c &= 2;
Console.WriteLine("Line 9 - &= Value of c = {0}", c);
c ^= 2;
Console.WriteLine("Line 10 - ^= Value of c = {0}", c);
c |= 2;
Console.WriteLine("Line 11 - |= Value of c = {0}", c);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Line 1 - = Value of c = 21
Line 2 - += Value of c = 42
Line 3 - -= Value of c = 21
Line 4 - *= Value of c = 441
Line 5 - /= Value of c = 21
Line 6 - %= Value of c = 11
Line 7 - <<= Value of c = 44
Line 8 - >>= Value of c = 11
Line 9 - &= Value of c = 2
Line 10 - ^= Value of c = 0
Line 11 - |= Value of c = 2
6. 其他运算符
还有其他几个重要的操作符,包括sizeof,typeof和?:等也被 C# 支持。请参考以下示例代码:
using System;
namespace OperatorsAppl
{
class Program
{
static void Main(string[] args)
{
/* example of sizeof operator */
Console.WriteLine("The size of int is {0}", sizeof(int));
Console.WriteLine("The size of short is {0}", sizeof(short));
Console.WriteLine("The size of double is {0}", sizeof(double));
/* example of ternary operator */
int a, b;
a = 10;
b = (a == 1) ? 20 : 30;
Console.WriteLine("Value of b is {0}", b);
b = (a == 10) ? 20 : 30;
Console.WriteLine("Value of b is {0}", b);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
The size of int is 4
The size of short is 2
The size of double is 8
Value of b is 30
Value of b is 20
7. C# 中的运算符优先级
运算符的优先级指定哪个运算符将被首先评估计算。关联性指定要评估的操作符方向,可以是左到右,或从右到左。
下面给出一个优先级的例子代码:
int data= 10+ 5*5 ;
data变量最后的计算值为:35,因为*(乘法运算符)在+(加法运算符)之前求值。
C语言运算符的优先级和关联性如下:
| 分类 | 运算符 | 关联性 |
|---|---|---|
| 后缀 | () [] -> . ++ - - |
左到右 |
| 一元 | + - ! ~ ++ - - (type)* & sizeof |
右到左 |
| 乘法 | * / % |
左到右 |
| 加法 | + - |
左到右 |
| 位移 | << >> |
左到右 |
| 关系 | < <= > >= |
左到右 |
| 等于 | == != |
左到右 |
| 按位与 | & |
左到右 |
| 位异或 | ^ |
左到右 |
| 按位或 | / |
左到右 |
| 逻辑与 | && |
左到右 |
| 逻辑或 | // |
左到右 |
| 条件 | ?: |
右到左 |
| 赋值 | = += -= *= /= %=>>= <<= &= ^= /= |
右到左 |
| 逗号 | , |
左到右 |
示例
using System;
namespace OperatorsAppl
{
class Program
{
static void Main(string[] args)
{
int a = 20;
int b = 10;
int c = 15;
int d = 5;
int e;
e = (a + b) * c / d; // ( 30 * 15 ) / 5
Console.WriteLine("Value of (a + b) * c / d is : {0}", e);
e = ((a + b) * c) / d; // (30 * 15 ) / 5
Console.WriteLine("Value of ((a + b) * c) / d is : {0}", e);
e = (a + b) * (c / d); // (30) * (15/5)
Console.WriteLine("Value of (a + b) * (c / d) is : {0}", e);
e = a + (b * c) / d; // 20 + (150/5)
Console.WriteLine("Value of a + (b * c) / d is : {0}", e);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Value of (a + b) * c / d is : 90
Value of ((a + b) * c) / d is : 90
Value of (a + b) * (c / d) is : 90
Value of a + (b * c) / d is : 50
关键字
关键字是保留字,在程序代码中不能将其用作变量名称,常量名称等。
在 C# 关键字不能用作标识符。但是,如果要使用关键字作为标识符,我们可以使用@字符加到关键字的前面,如:@class,@private等。
C# 编程语言中可用的保留关键字如下列表:
| abstract | base | as | bool | break | catch | case |
|---|---|---|---|---|---|---|
| byte | char | checked | class | const | continue | decimal |
| private | protected | public | return | readonly | ref | sbyte |
| explicit | extern | false | finally | fixed | float | for |
| foreach | goto | if | implicit | in | in (generic modifier) | int |
| ulong | ushort | unchecked | using | unsafe | virtual | void |
| null | object | operator | out | out (generic modifier) | override | params |
| default | delegate | do | double | else | enum | event |
| sealed | short | sizeof | stackalloc | static | string | struct |
| switch | this | throw | true | try | typeof | uint |
| abstract | base | as | bool | break | catch | case |
| volatile | while | - | - | - | - | - |
决策结构
决策结构要求程序员指定要由程序评估求值或测试一个或多个条件,如果条件被确定为真(True),则要执行语句;可选地,如果条件确定为假(False)则执行的其他语句。
以下是大多数编程语言中典型的决策结构的一般形式:
C# 提供以下类型的决策语句。点击下面相应链接查看细节。
| 语句 | 描述 |
|---|---|
| if语句 | if语句由一个布尔表达式,后跟一个或多个语句组成。 |
| if-else语句 | 一个if语句可以跟随一个可选的else语句,当布尔表达式为false时,它将执行else块中的代码。 |
| 嵌套if语句 | 可以在另一个if或else语句中使用一个if或else if语句。 |
| switch语句 | switch语句允许测试一个变量相对于一个值的列表。 |
| 嵌套switch语句 | 在另一个switch语句中可以使用另一个switch语句。 |
if语句
if语句由一个布尔表达式,后跟一个或多个语句组成。
语法
C# 中if语句的语法是:
if(boolean_expression)
{
/* statement(s) will execute if the boolean expression is true */
}
如果布尔表达式(boolean_expression)求值计算为true,则执行if语句中的代码块。 如果布尔表达式(boolean_expression)求值计算结果为false,则执行if语句结束后的第一组代码(在闭合大括号之后)。
流程图
例子
using System;
namespace DecisionMaking
{
class Program
{
static void Main(string[] args)
{
/* local variable definition */
int a = 1;
/* check the boolean condition using if statement */
if (a < 10)
{
/* if condition is true then print the following */
Console.WriteLine("a is less than 10");
}
Console.WriteLine("value of a is : {0}", a);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
a is less than 10;
value of a is : 1
if-else语句
一个if语句可以跟随一个可选的else语句,当布尔表达式为false时,则将执行else块中的代码。
语法
C# 中if...else语句的语法是:
if(boolean_expression)
{
/* statement(s) will execute if the boolean expression is true */
}else
{
/* statement(s) will execute if the boolean expression is false */
}
如果布尔表达式(boolean_expression)的值为true,则执行if代码块,否则执行else代码块。
流程图
示例代码
using System;
namespace DecisionMaking
{
class Program
{
static void Main(string[] args)
{
/* local variable definition */
int a = 199;
/* check the boolean condition */
if (a < 10)
{
/* if condition is true then print the following */
Console.WriteLine("a is less than 10");
}
else
{
/* if condition is false then print the following */
Console.WriteLine("a is not less than 10");
}
Console.WriteLine("value of a is : {0}", a);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
a is not less than 19;
value of a is : 199
if…else if…else语句
一个if语句可以跟随一个可选的else if...else语句,这对于使用单个if...else if语句来测试各种条件非常有用。
当使用if,else if,else语句时要注意以下几点 -
- 一个
if语句可以有零个或一个else语句,但它必须放在else if语句之后。 - 一个
if语句可以有零到多个else if语句,但必须放在else语句之前。 - 一旦有一个
else if条件测试成功,剩下的其他if else或else将不会再被测试。
语法
C# 中if...else if...else语句的语法是:
if(boolean_expression 1)
{
/* Executes when the boolean expression 1 is true */
}
else if( boolean_expression 2)
{
/* Executes when the boolean expression 2 is true */
}
else if( boolean_expression 3)
{
/* Executes when the boolean expression 3 is true */
}
else
{
/* executes when the none of the above condition is true */
}
示例
using System;
namespace DecisionMaking
{
class Program
{
static void Main(string[] args)
{
/* local variable definition */
int a = 199;
/* check the boolean condition */
if (a == 19)
{
/* if condition is true then print the following */
Console.WriteLine("Value of a is 19");
}
else if (a == 29)
{
/* if else if condition is true */
Console.WriteLine("Value of a is 29");
}
else if (a == 39)
{
/* if else if condition is true */
Console.WriteLine("Value of a is 39");
}
else
{
/* if none of the conditions is true */
Console.WriteLine("None of the values is matching");
}
Console.WriteLine("Exact value of a is: {0}", a);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
None of the values is matching
Exact value of a is: 199
嵌套if语句
在 C# 中嵌套if-else语句总是合法的,这意味着您可以在一个if或else语句中使用另一个if或else if语句。
语法
嵌套if语句的语法如下:
if( boolean_expression 1)
{
/* Executes when the boolean expression 1 is true */
if(boolean_expression 2)
{
/* Executes when the boolean expression 2 is true */
}
}
可以使用与嵌套if语句相似的方式来嵌套else if...else语句。
示例
using System;
namespace DecisionMaking
{
class Program
{
static void Main(string[] args)
{
//* local variable definition */
int a = 199;
int b = 299;
/* check the boolean condition */
if (a == 199)
{
/* if condition is true then check the following */
if (b == 299)
{
/* if condition is true then print the following */
Console.WriteLine("Value of a is 199 and b is 299");
}
}
Console.WriteLine("Exact value of a is : {0}", a);
Console.WriteLine("Exact value of b is : {0}", b);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Value of a is 100 and b is 299
Exact value of a is : 199
Exact value of b is : 299
switch语句
一个switch语句允许使用一个变量测试来相对于一个值的列表。每个值都称为一种情况(case),并且每个switch情况都检查是否匹配变量的值。
语法
C# 中的switch语句的语法如下:
switch(expression) {
case constant-expression :
statement(s);
break; /* optional */
case constant-expression :
statement(s);
break; /* optional */
/* you can have any number of case statements */
default : /* Optional */
statement(s);
}
以下规则适用于switch语句:
switch语句中使用的表达式(expression)必须具有一个整数或枚举类型,或者是类类型,该类具有单个转换函数为整数或枚举类型。- 可以在
switch语句内有任意数量的case语句。 每个case语句后跟要比较的值和冒号。 case语句中的常量表达式必须与switch中变量的数据类型相同,它必须是常量或字面值。- 当接通的变量等于其中一个
case语句中的值时,这个case语句中代码块将被执行,直到达到break语句。 - 当达到
break语句时,switch语句块终止,并且控制流程跳转到switch语句之后的下一行。 - 不是每个
case都需要包含break语句(可选)。 如果不没有break语句,控制流程将执行到在后续case语句中,直至遇到break语句。 switch语句可以具有可选的default语句,必须出现在switch语句的末尾。 默认情况下可以用于在没有任何情况为真时执行任务。在default语句不需要使用break语句。
流程图
示例代码
using System;
namespace DecisionMaking
{
class Program
{
static void Main(string[] args)
{
/* local variable definition */
char grade = 'B';
switch (grade)
{
case 'A':
Console.WriteLine("Excellent!");
break;
case 'B':
case 'C':
Console.WriteLine("Well done");
break;
case 'D':
Console.WriteLine("You passed");
break;
case 'F':
Console.WriteLine("Better try again");
break;
default:
Console.WriteLine("Invalid grade");
break;
}
Console.WriteLine("Your grade is {0}", grade);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Well done
Your grade is B
嵌套switch语句
可以将switch语句作为另外一个switch语句序列的一部分。即使内部和外部switch的case常数包含公共值,也不会产生任何冲突。
语法
嵌套switch语句的语法如下:
switch(ch1)
{
case 'A':
Console.WriteLine("This A is part of outer switch" );
switch(ch2)
{
case 'A':
Console.WriteLine("This A is part of inner switch" );
break;
case 'B': /* inner B case code */
}
break;
case 'B': /* outer B case code */
}
示例代码
using System;
namespace DecisionMaking
{
class Program
{
static void Main(string[] args)
{
int a = 199;
int b = 299;
switch (a)
{
case 199:
Console.WriteLine("This is part of outer switch ");
switch (b)
{
case 299:
Console.WriteLine("This is part of inner switch ");
break;
}
break;
}
Console.WriteLine("Exact value of a is : {0}", a);
Console.WriteLine("Exact value of b is : {0}", b);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
This is part of outer switch
This is part of inner switch
Exact value of a is : 199
Exact value of b is : 299
?: 运算符
在上一章中我们已经涵盖了条件运算符?:,可以用它来替换if...else语句。它具有以下一般形式:
Exp1 ? Exp2 : Exp3;
其中Exp1,Exp2和Exp3是表达式。请注意冒号的使用和位置。
首先,对Exp1表达式进行评估求值,如果求值结果是真,那么Exp2被评估并返回作为整个的值。如果Exp1求值结果为假(false),则对Exp3表达式进行求值,其值返回作为表达式的值。
int a = 1;
int b = 2;
int c = 0;
c = (a>b)? a: b; // 执行后,变量c的值为:2
循环
一般来说,这些语句是顺序执行的:函数中的第一个语句先执行,后跟第二个,依此类推。当需要执行一段代码多次时,编写代码时要一条一条语句地写,是非常低效的。
编程语言提供了允许更复杂的执行路径的各种控制结构。
循环语句允许多次执行语句或一组语句,以下是大多数编程语言中的循环语句的一般流程:
C# 提供以下类型的循环来处理循环需求。可通过点击下面的链接查看来了解和学习。
| 循环类型 | 描述 |
|---|---|
| while循环 | 在给定条件为真时,它重复一个语句或一组语句。它在执行循环体之前测试条件状态。 |
| for循环 | 它多次执行一系列代码语句,并缩写管理循环变量。 |
| do…while循环 | 它类似于while语句,只不过它在循环体末尾处测试条件 |
| 嵌套循环 | 可以使用一个或多个循环在一个while,for或do..while循环。 |
while循环
只要给定的条件为真, C# 中的while循环语句重复执行目标语句。
语法
C# 中while循环的语法是:
while(condition)
{
statement(s);
}
在这里,声明(statement(s))可能是单一声明或一组声明。条件(condition)可以是任何表达式,true是任何非零值,循环在条件(condition)为真时执行循环。
当条件(condition)变为false时,程序控制传递到循环后面的行。
流程图
在这里,while循环的关键是循环可能不会运行。因为当条件测试结果为假时,循环体会被跳过,并且执行了while循环体之后的第一个语句。
例子
using System;
namespace Loops
{
class Program
{
static void Main(string[] args)
{
/* local variable definition */
int a = 19;
/* while loop execution */
Console.WriteLine("Start while loop ");
while (a < 29)
{
Console.WriteLine("value of a: {0}", a);
a++;
}
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Start while loop
value of a: 19
value of a: 20
value of a: 21
value of a: 22
value of a: 23
value of a: 24
value of a: 25
value of a: 26
value of a: 27
value of a: 28
for循环
for循环是一种重复控制结构,可以让您有效地编写一个需要执行特定次数的循环。
语法
C# 中for循环的语法是:
for ( init; condition; increment )
{
statement(s);
}
以下是for循环中的控制流程:
init步骤首先执行,只执行一次。此步骤允许您声明和初始化任何循环控制变量。- 接下来,评估计算条件(
condition)。如果评估计算结果为真,则执行循环体。如果 为假,则不执行循环体,并且控制的流程跳转到for循环之后的下一个语句。 - 在
for循环体执行之后,控制流程跳回到增量(increment)语句。此语句可更新任何循环控制变量,也可以留空。 - 现在再次评估计算条件(
condition)。如果计算结果为真,则循环执行并且该过程重复(循环体,然后到增量(increment)语句,然后再次测试条件)。直到条件变为false后,for循环终止执行。
流程图
示例
using System;
namespace Loops
{
class Program
{
static void Main(string[] args)
{
/* for loop execution */
for (int a = 1; a < 10; a = a + 1)
{
Console.WriteLine("value of a: {0}", a);
}
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
value of a: 1
value of a: 2
value of a: 3
value of a: 4
value of a: 5
value of a: 6
value of a: 7
value of a: 8
value of a: 9
do…while循环
不同于for循环,以及while循环在循环开始时测试循环条件,do...while循环在循环结束时检查其条件。
do...while循环类似于while循环,唯一的区别是do...while循环保证至少执行一次循环体中的代码块。
语法
C# 中的do...while循环的语法是:
do
{
statement(s);
}while( condition );
请注意,条件表达式(condition)放置在循环的末尾,因此循环体中的语句在判断测试条件之前就已经执行了一次。
如果条件(condition)为真,则控制流程将重新开始执行,循环体中的语句将再次执行。重复该过程,直到给定条件变为假。
流程图
实例代码
using System;
namespace Loops
{
class Program
{
static void Main(string[] args)
{
/* local variable definition */
int a = 10;
/* do loop execution */
do
{
Console.WriteLine("value of a: {0}", a);
a = a + 1;
}while (a < 20);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15
value of a: 16
value of a: 17
value of a: 18
value of a: 19
嵌套循环
C# 允许在一个循环中使用另一个循环。下面使用几个例子来说明这个概念。
语法
C# 中的嵌套for循环语句的语法如下:
for ( init; condition; increment )
{
for ( init; condition; increment )
{
statement(s);
}
statement(s);
}
C# 中的嵌套while循环语句的语法如下:
while(condition)
{
while(condition)
{
statement(s);
}
statement(s);
}
C# 中的嵌套do...while循环语句的语法如下:
do
{
statement(s);
do
{
statement(s);
}while( condition );
}while( condition );
可以将任何类型的循环放在任何其他类型的循环中。例如,for循环可以在while循环内,反之亦然。
示例
以下程序使用嵌套for循环来查找从2到100内的素数:
using System;
namespace Loops
{
class Program
{
static void Main(string[] args)
{
/* local variable definition */
int i, j;
for (i = 2; i < 100; i++)
{
for (j = 2; j <= (i / j); j++)
if ((i % j) == 0) break; // if factor found, not prime
if (j > (i / j))
Console.WriteLine("{0} is prime", i);
}
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
2 is prime
3 is prime
5 is prime
7 is prime
11 is prime
13 is prime
17 is prime
19 is prime
23 is prime
29 is prime
31 is prime
37 is prime
41 is prime
43 is prime
47 is prime
53 is prime
59 is prime
61 is prime
67 is prime
71 is prime
73 is prime
79 is prime
83 is prime
89 is prime
97 is prime
循环控制语句
循环控制语句从其正常顺序更改执行。当执行离开范围时,在该循环体范围内创建的所有自动对象都将被销毁。
C# 提供以下控制语句。可通过点击以下链接来查看了解和学习。
| 控制语句 | 说明 |
|---|---|
| break语句 | 终止循环或switch语句,并将执行转移到循环或切换后立即执行。 |
| continue语句 | 跳过循环体的剩余部分,并在重申之前立即重新测试循环状态。 |
break语句
C# 中的break语句主要有两个用法:
- 在循环中使用,当循环中遇到
break语句时,循环将立即终止,程序控制在循环之后的下一个语句中恢复。 - 它可以用于终止
switch语句中的case语句。
如果使用嵌套循环(即在一个循环中使用另一个循环),则break语句将停止执行最内循环,并在块之后开始执行外循环的下一行代码。
语法
C# 中的break语句的语法如下:
break;
流程图
例子
using System;
namespace Loops
{
class Program
{
static void Main(string[] args)
{
/* local variable definition */
int a = 10;
/* while loop execution */
while (a < 20)
{
Console.WriteLine("value of a: {0}", a);
a++;
if (a > 15)
{
/* terminate the loop using break statement */
break;
}
}
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 15
continue语句
C# 中的continue语句有点类似于break语句。 但不是强制终止,而是继续强制循环的下一次迭代发生,跳过其间的任何代码。
对于for循环,continue语句将导致循环的条件测试和增量部分执行。对于while和do...while循环,continue语句导致程序控制传递到条件测试。
语法
C# 中的continue语句的语法如下:
continue;
流程图
示例
using System;
namespace Loops
{
class Program
{
static void Main(string[] args)
{
/* local variable definition */
int a = 10;
/* do loop execution */
do
{
if (a == 15)
{
/* skip the iteration */
a = a + 1;
continue;
}
Console.WriteLine("value of a: {0}", a);
a++;
}
while (a < 20);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
value of a: 10
value of a: 11
value of a: 12
value of a: 13
value of a: 14
value of a: 16
value of a: 17
value of a: 18
value of a: 19
无限循环
如果一个条件永远是true,则循环变成无限循环。一般来说,for循环用于此目的。 因为形成for循环的三个表达式都不是必需的,所以可以通过将条件表达式留空来实现无限循环的目的。
示例代码
using System;
namespace Loops
{
class Program
{
static void Main(string[] args)
{
for (; ; )
{
Console.WriteLine("Hey! I am Trapped");
}
}
}
}
当条件表达式不存在时,则假定为真(true),有时可能要初始化和递增表达式,但是程序员更常使用for(;;)构造来表示无限循环。
封装
封装是一种被定义为在物理或逻辑包中包含一个或多个项目的过程。封装在面向对象的编程方法中,是用来阻止访问具体的实现细节。
抽象和封装是面向对象编程中的相关特征。抽象允许相关信息可见,封装使程序员能够实现所需的抽象级别。
封装通过使用访问说明符来实现。访问说明符定义了一个类成员的范围和可见性 C# 支持以下访问说明符:
- 公共访问说明符
- 私有访问说明符
- 受保护访问说明符
- 内部访问说明符
- 保护内部访问说明符
公共访问说明符
公共访问说明符允许类将成员变量和成员函数公开到其他函数和对象。任何公共会员都可以从类的外部来访问。
以下示例说明了这一点:
using System;
namespace RectangleApplication
{
class Rectangle
{
//member variables
public double length;
public double width;
public double GetArea()
{
return length * width;
}
public void Display()
{
Console.WriteLine("Length: {0}", length);
Console.WriteLine("Width: {0}", width);
Console.WriteLine("Area: {0}", GetArea());
}
}//end class Rectangle
class ExecuteRectangle
{
static void Main(string[] args)
{
Rectangle r = new Rectangle();
r.length = 14.5;
r.width = 10.5;
r.Display();
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Length: 14.5
Width: 10.5
Area: 152.25
在前面的例子中,成员变量:length和width被声明为public,因此可以使用名为r的Rectangle类的实例从Main()函数访问它们。
成员函数Display()和GetArea()也可以直接访问这些变量,而不用通过该类的任何实例。
成员函数Display()也被声明为public,因此也可以使用名为r的Rectangle类的实例从Main()访问它。
私有访问说明符
私有访问说明符允许类从其他函数和对象中隐藏其成员变量和成员函数。只有同一个类的函数才能访问其私有成员。即使是类的实例也无法访问其私有成员。
以下示例说明了这一点:
using System;
namespace RectangleApplication
{
class Rectangle
{
//member variables
private double length;
private double width;
public void Acceptdetails()
{
Console.WriteLine("Enter Length: ");
length = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter Width: ");
width = Convert.ToDouble(Console.ReadLine());
}
public double GetArea()
{
return length * width;
}
public void Display()
{
Console.WriteLine("Length: {0}", length);
Console.WriteLine("Width: {0}", width);
Console.WriteLine("Area: {0}", GetArea());
}
}//end class Rectangle
class ExecuteRectangle
{
static void Main(string[] args)
{
Rectangle r = new Rectangle();
r.Acceptdetails();
r.Display();
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Enter Length:
12.5
Enter Width:
8.25
Length: 12.5
Width: 8.25
Area: 103.125
在前面的例子中,成员变量:length和width被声明为私有的,所以不能从函数Main()访问它们。成员函数AcceptDetails()和Display()可以访问这些变量。由于成员函数AcceptDetails()和Display()被声明为public,因此可以使用名为r的Rectangle类的实例从Main()访问它们。
受保护访问指定符
受保护的访问说明符允许子类访问其基类的成员变量和成员函数。这样就有助于实现继承。我们将在后续章节中详细讨论。
内部访问指定符
内部访问说明符允许类将其成员变量和成员函数公开到当前程序集中的其他函数和对象。换句话说,具有内部访问说明符的任何成员都可以从定义成员的应用程序中定义的任何类或方法访问。
以下程序说明了这一点:
using System;
namespace RectangleApplication
{
class Rectangle
{
//member variables
internal double length;
internal double width;
double GetArea()
{
return length * width;
}
public void Display()
{
Console.WriteLine("Length: {0}", length);
Console.WriteLine("Width: {0}", width);
Console.WriteLine("Area: {0}", GetArea());
}
}//end class Rectangle
class ExecuteRectangle
{
static void Main(string[] args)
{
Rectangle r = new Rectangle();
r.length = 12.5;
r.width = 8.25;
r.Display();
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Length: 12.5
Width: 8.25
Area: 103.125
在上面的示例中,请注意,成员函数GetArea()没有使用任何访问说明符声明。如果没有使用任何一个访问说明符的类成员,它的默认访问说明符是什么呢? 默认使用的是私有的。
受保护内部访问指定符
受保护的内部访问说明符允许类从其他类对象和函数中隐藏其成员变量和成员函数,但同一应用程序中的子类除外。这也是在实现继承时要使用的。
方法
C#中的方法是一组执行任务的语句。 每个 C# 程序至少有一个类包含一个名称为Main()的方法。
要使用方法,需要:
- 定义方法
- 调用方法
C# 中定义方法
当要定义一个方法时,需要声明它的结构元素。 C# 中定义方法的语法如下:
<Access Specifier> <Return Type> <Method Name>(Parameter List)
{
Method Body
}
以下是方法中的各种元素说明:
- 访问说明符(Access Specifier):这决定了一个类的变量或方法的可见性。
- 返回类型(Return type):方法可能返回一个值。返回类型是方法返回的值的数据类型。 如果方法没有返回任何值,则返回类型为
void。 - 方法名称(Method Name):方法名称是唯一标识符,区分大小写。它不能与在类中声明的任何其他标识符相同。
- 参数列表(Parameter list):括号内的参数用于从方法传递和接收数据。参数列表是指方法参数的类型,顺序和编号。参数是可选的; 也就是说,方法可能不使用参数。
- 方法体(Method body):这包含完成所需操作的一组代码语句和具体实现。
例子
以下代码片段显示了一个函数FindMax,它使用两个整数值,并返回两者中较大的一个。 它具有公共访问说明符,因此可以使用类的实例从类外部访问它。
class NumberManipulator
{
public int FindMax(int num1, int num2)
{
/* local variable declaration */
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
...
}
C# 中的调用方法
可以使用方法的名称调用方法。以下示例说明了这一点:
using System;
namespace CalculatorApplication
{
class NumberManipulator
{
public int FindMax(int num1, int num2)
{
/* local variable declaration */
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
static void Main(string[] args)
{
/* local variable definition */
int a = 101;
int b = 199;
int ret;
NumberManipulator n = new NumberManipulator();
//calling the FindMax method
ret = n.FindMax(a, b);
Console.WriteLine("Max value is : {0}", ret );
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Max value is : 199
还可以使用该类的实例从其他类调用public方法。 例如,FindMax方法属于NumberManipulator类的成员,可以从另一个类Test中调用它。
using System;
namespace CalculatorApplication
{
class NumberManipulator
{
public int FindMax(int num1, int num2)
{
/* local variable declaration */
int result;
if(num1 > num2)
result = num1;
else
result = num2;
return result;
}
}
class Test
{
static void Main(string[] args)
{
/* local variable definition */
int a = 100;
int b = 200;
int ret;
NumberManipulator n = new NumberManipulator();
//calling the FindMax method
ret = n.FindMax(a, b);
Console.WriteLine("Max value is : {0}", ret );
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Max value is : 200
递归方法调用
递归方法是一种可以调用自身的方法。以下是使用递归函数来计算给定数值的阶乘的示例:
using System;
namespace CalculatorApplication
{
class NumberManipulator
{
public int factorial(int num)
{
/* local variable declaration */
int result;
if (num == 1)
{
return 1;
}
else
{
result = factorial(num - 1) * num;
return result;
}
}
static void Main(string[] args)
{
NumberManipulator n = new NumberManipulator();
//calling the factorial method
Console.WriteLine("Factorial of 6 is : {0}", n.factorial(6));
Console.WriteLine("Factorial of 7 is : {0}", n.factorial(7));
Console.WriteLine("Factorial of 8 is : {0}", n.factorial(8));
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Factorial of 6 is: 720
Factorial of 7 is: 5040
Factorial of 8 is: 40320
将参数传递给方法
调用参数的方法时,需要将参数传递给方法。有三种方式可以将参数传递给方法,分别如下表格中所列:
| 机制 | 简介 |
|---|---|
| 按值传递参数 | 将参数的实际值复制到函数的形式参数中。在函数内对参数所做的更改对参数没有影响。 |
| 按引用传递参数 | 将对参数的内存位置的引用复制到形式参数中,在函数内对参数的更改会影响参数值。 |
| 输出参数 | 此方法用于返回多个值。 |
按值传递参数
这是将参数传递给方法的默认机制。在这种机制中,当调用一个方法时,会为每个值参数创建一个新的存储位置(拷贝值)。
实际参数的值被复制到方法体中。因此,方法中的参数所做的更改对参数没有影响。 以下示例演示了以下概念:
using System;
namespace CalculatorApplication
{
class NumberManipulator
{
public void swap(int x, int y)
{
int temp;
temp = x; /* save the value of x */
x = y; /* put y into x */
y = temp; /* put temp into y */
}
static void Main(string[] args)
{
NumberManipulator n = new NumberManipulator();
/* local variable definition */
int a = 100;
int b = 200;
Console.WriteLine("Before swap, value of a : {0}", a);
Console.WriteLine("Before swap, value of b : {0}", b);
/* calling a function to swap the values */
n.swap(a, b);
Console.WriteLine("After swap, value of a : {0}", a);
Console.WriteLine("After swap, value of b : {0}", b);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Before swap, value of a :100
Before swap, value of b :200
After swap, value of a :100
After swap, value of b :200
它表明,尽管函数内部已经发生了变化,但参数值并没有改变。
按引用传递参数
引用参数是对变量的内存位置的引用。按引用传递参数与按值传递参数不同,不会为这些参数创建新的存储位置。引用参数表示与传递给方法的实际参数具有相同的存储位置。
可以使用ref关键字声明引用参数。如下示例:
using System;
namespace CalculatorApplication
{
class NumberManipulator
{
public void swap(ref int x, ref int y)
{
int temp;
temp = x; /* save the value of x */
x = y; /* put y into x */
y = temp; /* put temp into y */
}
static void Main(string[] args)
{
NumberManipulator n = new NumberManipulator();
/* local variable definition */
int a = 100;
int b = 200;
Console.WriteLine("Before swap, value of a : {0}", a);
Console.WriteLine("Before swap, value of b : {0}", b);
/* calling a function to swap the values */
n.swap(ref a, ref b);
Console.WriteLine("After swap, value of a : {0}", a);
Console.WriteLine("After swap, value of b : {0}", b);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Before swap, value of a : 100
Before swap, value of b : 200
After swap, value of a : 200
After swap, value of b : 100
它显示了在swap()函数中的值已经更改,并且此更改在Main()函数中有反映。
输出参数
return语句可用于从函数中返回一个值。 但是,使用输出参数,可以从函数返回两个值。输出参数与引用参数相似,不同之处在于它们将数据从方法中传输出去,而不是传入其中。
以下示例说明了这一点:
using System;
namespace CalculatorApplication
{
class NumberManipulator
{
public void getValue(out int x )
{
int temp = 5;
x = temp;
}
static void Main(string[] args)
{
NumberManipulator n = new NumberManipulator();
/* local variable definition */
int a = 100;
Console.WriteLine("Before method call, value of a : {0}", a);
/* calling a function to get the value */
n.getValue(out a);
Console.WriteLine("After method call, value of a : {0}", a);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Before method call, value of a : 100
After method call, value of a : 5
为输出参数提供的变量不需要分配值。当需要通过参数返回值时,输出参数特别有用,而无需为参数分配初始值。参考以下示例来了解:
using System;
namespace CalculatorApplication
{
class NumberManipulator
{
public void getValues(out int x, out int y )
{
Console.WriteLine("Enter the first value: ");
x = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter the second value: ");
y = Convert.ToInt32(Console.ReadLine());
}
static void Main(string[] args)
{
NumberManipulator n = new NumberManipulator();
/* local variable definition */
int a , b;
/* calling a function to get the values */
n.getValues(out a, out b);
Console.WriteLine("After method call, value of a : {0}", a);
Console.WriteLine("After method call, value of b : {0}", b);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Enter the first value:
17
Enter the second value:
19
After method call, value of a : 17
After method call, value of b : 19
可空类型((nullable)
C# 提供了一个特殊的数据类型,可空(nullable)类型,可以为其分配正常范围的值以及null值。
例如,可以将-2147483648到2147483647的任何值或者null值存储到可空(nullable)类型的变量中。类似地,可以在可空(nullable)类型的变量中分配true,false或null。声明可空(nullable)类型的语法如下:
< data_type> ? <variable_name> = null;
以下示例演示了使用可空(nullable)数据类型:
using System;
namespace CalculatorApplication
{
class NullablesAtShow
{
static void Main(string[] args)
{
int? num1 = null;
int? num2 = 45;
double? num3 = new double?();
double? num4 = 3.14157;
bool? boolval = new bool?();
// display the values
Console.WriteLine("Nullables at Show: {0}, {1}, {2}, {3}", num1, num2, num3, num4);
Console.WriteLine("A Nullable boolean value: {0}", boolval);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Nullables at Show: , 45, , 3.14157
A Nullable boolean value:
null合并运算符(??)
null合并运算符与可空(nullable)类型值和引用类型一起使用。它用于将操作数转换为另一个可空(或不)值类型操作数的类型,它是进行隐式转换的。
如果第一个操作数的值为null,则运算符返回第二个操作数的值,否则返回第一个操作数的值。以下示例代码将解释说明这个概念:
using System;
namespace CalculatorApplication
{
class NullablesAtShow
{
static void Main(string[] args)
{
double? num1 = null;
double? num2 = 3.14157;
double num3;
num3 = num1 ?? 5.34;
Console.WriteLine(" Value of num3: {0}", num3);
num3 = num2 ?? 5.34;
Console.WriteLine(" Value of num3: {0}", num3);
Console.ReadLine();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Value of num3: 5.34
Value of num3: 3.14157
数组
数组是一种存储相同类型元素的固定大小顺序集合。数组用于存储数据集合,但一般会将数组视为存储在连续存储器位置的相同类型的变量的集合。
如果要存储表示100名称学生的分数,需要独立地声明100整数变量。例如:number0,number1,...,number100这样单个独立变量。而如果使用一个数组变量来表示就省事多了。例如,首先声明数组:numbers,使用numbers[0],numbers[1]和...,numbers[99]来表示单个变量,数组中的元素可通过索引来访问。
所有数组是由连续的内存位置组成。最低的地址对应于第一个元素,而最后一个元素的地址最高。
声明数组
要在 C# 中声明一个数组,可以使用以下语法:
datatype[] arrayName;
其中 -
- datatype - 用于指定数组中元素的类型。
- [] - 指定数组序号,
rank指定数组的大小。 - arrayName - 指定数组的名称。
例如,
double[] balance;
初始化数组
声明数组不会将的数组初始化到内存中。将数组变量初始化时,可以为数组指定值。
数组是一个引用类型,因此需要使用new关键字来创建数组的实例。 例如,
double[] balance = new double[10];
数组赋值
可以通过使用索引数为各个数组元素分配值,如:
double[] balance = new double[10];
balance[0] = 1500.0;
balance[1] = 1000.0;
balance[2] = 2000.0;
也可以在声明时为数组指定值,如下所示:
double[] balance = { 240.08, 523.19, 121.01};
还可以在创建时初始化数组,如下所示:
int [] marks = new int[5] { 89, 98, 97, 87, 85};
也可以省略数组的大小,如下所示:
int [] marks = new int[] { 100, 97, 96, 97, 95};
可以将数组变量复制到另一个目标数组变量中。在这种情况下,目标和源都指向相同的内存位置:
int [] marks = new int[] { 99, 98, 92, 97, 95};
int[] score = marks;
创建数组时, C# 编译器会根据数组类型将每个数组元素初始化为默认值。 例如,对于int类型的数组,所有元素都将初始化为0。
访问数组元素
通过索引和数组名称来访问数组的元素。这是通过将元素的索引放在数组的名称后面的方括号内完成的。 例如,
double salary = balance[9];
以下示例演示了如何声明,赋值和访问数组:
using System;
namespace ArrayApplication
{
class MyArray
{
static void Main(string[] args)
{
int [] n = new int[10]; /* n is an array of 10 integers */
int i,j;
/* initialize elements of array n */
for ( i = 0; i < 10; i++ )
{
n[ i ] = i + 100;
}
/* output each array element's value */
for (j = 0; j < 10; j++ )
{
Console.WriteLine("Element[{0}] = {1}", j, n[j]);
}
Console.ReadKey();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Element[0] = 100
Element[1] = 101
Element[2] = 102
Element[3] = 103
Element[4] = 104
Element[5] = 105
Element[6] = 106
Element[7] = 107
Element[8] = 108
Element[9] = 109
使用foreach循环
在前面的例子中,我们使用for循环访问每个数组元素。还可以使用foreach语句来遍历数组。参考以下代码 -
using System;
namespace ArrayApplication
{
class MyArray
{
static void Main(string[] args)
{
int [] n = new int[10]; /* n is an array of 10 integers */
/* initialize elements of array n */
for ( int i = 0; i < 10; i++ )
{
n[i] = i + 100;
}
/* output each array element's value */
foreach (int j in n )
{
int i = j-100;
Console.WriteLine("Element[{0}] = {1}", i, j);
}
Console.ReadKey();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Element[0] = 100
Element[1] = 101
Element[2] = 102
Element[3] = 103
Element[4] = 104
Element[5] = 105
Element[6] = 106
Element[7] = 107
Element[8] = 108
Element[9] = 109
C# 数组类型
C# 程序员应该要清楚以下几个与数组有关的重要概念:
| 概念 | 描述 |
|---|---|
| 多维数组 | C# 支持多维数组,多维数组的最简单形式是二维数组。 |
| 锯齿数组 | C# 支持多维数组,它们是数组的数组。 |
| 将数组传递给函数 | 可以通过指定数组的名称而不使用索引,将数组传递给函数。 |
| 参数数组 | 这用于将未知数量的参数传递给函数。 |
| Array类 | 在System命名空间中定义,它是所有数组的基类,并提供了处理数组的各种属性和方法。 |
多维数组
C# 允许多维数组,多维数组也称为矩阵。可以声明一个2维数组的字符串:
string [,] names;
或者,int变量3维数组为:
int [ , , ] m;
二维数组
多维数组的最简单形式是二维数组。二维数组是一维数组的列表。
可以将二维数组认为是一个表,它有x行数和y列数。以下是一个二维数组,它包含3行和4列:
因此,数组a中的每个元素由形式a [i,j]的元素名称标识,其中a是数组的名称,i和j是唯一标识数组a中的每个元素的下标。
初始化二维数组
可以通过为每一行指定括号值来初始化多维数组。以下数组有3行,每行有4列。
int [,] a = new int [3,4] {
{0, 1, 2, 3} , /* initializers for row indexed by 0 */
{4, 5, 6, 7} , /* initializers for row indexed by 1 */
{8, 9, 10, 11} /* initializers for row indexed by 2 */
};
访问二维数组元素
通过使用下标来访问二维数组中的元素。 也就是数组的行索引和列索引。 例如,
int val = a[2,3];
上述语句从数组的第3行获取第4个元素。下面来看看示例程序如何处理二维数组:
using System;
namespace ArrayApplication
{
class MyArray
{
static void Main(string[] args)
{
/* an array with 5 rows and 2 columns*/
int[,] a = new int[5, 2] {{0,0}, {1,2}, {2,4}, {3,6}, {4,8} };
int i, j;
/* output each array element's value */
for (i = 0; i < 5; i++)
{
for (j = 0; j < 2; j++)
{
Console.WriteLine("a[{0},{1}] = {2}", i, j, a[i,j]);
}
}
Console.ReadKey();
}
}
}
当编译和执行上述代码时,会产生以下结果:
a[0,0]: 0
a[0,1]: 0
a[1,0]: 1
a[1,1]: 2
a[2,0]: 2
a[2,1]: 4
a[3,0]: 3
a[3,1]: 6
a[4,0]: 4
a[4,1]: 8
锯齿数组
锯齿(Jagged)数组是数组的数组。可以声明一个类型为int的名为score的锯齿数组,如下:
int [][] scores;
声明数组,它不会在内存中创建数组。要创建上面的数组,参考以下代码:
int[][] scores = new int[5][];
for (int i = 0; i < scores.Length; i++)
{
scores[i] = new int[4];
}
可以将锯齿数组初始化为:
int[][] scores = new int[2][]{new int[]{92,93,94},new int[]{85,66,87,88}};
其中,scores是两个整数数组的数组 -score [0]是一个3个整数的数组,score [1]是一个4个整数的数组。
示例
以下示例说明了锯齿数组的使用:
using System;
namespace ArrayApplication
{
class MyArray
{
static void Main(string[] args)
{
/* a jagged array of 5 array of integers*/
int[][] a = new int[][]{new int[]{0,0},new int[]{1,2},new int[]{2,4},new int[]{ 3, 6 }, new int[]{ 4, 8 } };
int i, j;
/* output each array element's value */
for (i = 0; i < 5; i++)
{
for (j = 0; j < 2; j++)
{
Console.WriteLine("a[{0}][{1}] = {2}", i, j, a[i][j]);
}
}
Console.ReadKey();
}
}
}
当编译和执行上述代码时,会产生以下结果:
a[0][0]: 0
a[0][1]: 0
a[1][0]: 1
a[1][1]: 2
a[2][0]: 2
a[2][1]: 4
a[3][0]: 3
a[3][1]: 6
a[4][0]: 4
a[4][1]: 8
将数组传递给函数
在 C# 中将数组作为函数参数传递。以下是一个演示如何将数组传递到函数的示例:
using System;
namespace ArrayApplication
{
class MyArray
{
double getAverage(int[] arr, int size)
{
int i;
double avg;
int sum = 0;
for (i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = (double)sum / size;
return avg;
}
static void Main(string[] args)
{
MyArray app = new MyArray();
/* an int array with 5 elements */
int [] balance = new int[]{1000, 2, 3, 17, 50};
double avg;
/* pass pointer to the array as an argument */
avg = app.getAverage(balance, 5 ) ;
/* output the returned value */
Console.WriteLine( "Average value is: {0} ", avg );
Console.ReadKey();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Average value is: 214.4
参数数组
有时,在声明一个方法时,不能确定传递给函数的参数的数量。可通过 C# 参数数组来实现。
示例代码:
using System;
namespace ArrayApplication
{
class ParamArray
{
public int AddElements(params int[] arr)
{
int sum = 0;
foreach (int i in arr)
{
sum += i;
}
return sum;
}
}
class TestClass
{
static void Main(string[] args)
{
ParamArray app = new ParamArray();
int sum = app.AddElements(512, 720, 250, 567, 889);
Console.WriteLine("The sum is: {0}", sum);
Console.ReadKey();
}
}
}
当编译和执行上述代码时,会产生以下结果:
The sum is: 2938
Array类
Array类是 C# 中所有数组的基类。它在System命名空间中定义。Array类提供了各种属性和方法来处理数组。
Array类的属性
下表描述了Array类的一些最常用的属性:
| 编号 | 属性 | 描述 |
|---|---|---|
| 1 | IsFixedSize | 获取一个值,指示Array是否具有固定大小。 |
| 2 | IsReadOnly | 获取一个值,指示Array是否为只读。 |
| 3 | Length | 获取一个32位整数,表示Array的所有维度中的元素总数。 |
| 4 | LongLength | 获取一个64位整数,表示Array的所有维度中的元素总数。 |
| 5 | Rank | 获取数组的等级(维数)。 |
数组Array类的方法
下表介绍了Array类最常用的一些方法:
| 编号 | 方法 | 描述 |
|---|---|---|
| 1 | Clear | 根据元素类型,将Array中的元素范围设置为0,false或null。 |
| 2 | Copy(Array, Array, Int32) | 从第一个元素开始,从Array开始复制一系列元素,并将它们粘贴到从第一个元素开始的另一个Array中。长度指定为32位整数。 |
| 3 | CopyTo(Array, Int32) | |
| 4 | GetLength | 获取一个32位整数,表示Array指定维度中的元素数。 |
| 5 | GetLongLength | 获取一个64位整数,表示Array指定维度中的元素数。 |
| 6 | GetLowerBound | 获取Array中指定维度的下限。 |
| 7 | GetType | 获取当前实例的类型(从Object继承。) |
| 8 | GetUpperBound | 获取Array中指定维度的上限。 |
| 9 | GetValue(Int32) | 获取一维数组中指定位置的值,索引指定为32位整数。 |
| 10 | IndexOf(Array, Object) | 搜索指定的对象并返回整个一维数组中第一次出现的索引。 |
| 11 | Reverse(Array) | 反转整个一维数组中元素的顺序。 |
| 12 | SetValue(Object, Int32) | 将值设置为一维数组中指定位置的元素。索引指定为32位整数。 |
| 13 | Sort(Array) | Array的每个元素使用IComparable实现对整个一维数组中的元素进行排序。 |
| 14 | ToStringk() | 返回一个表示当前对象的字符串(从Object继承) |
有关Array类属性和方法的完整列表,请参阅Microsoft C# 文档。
示例
以下程序演示了使用Array类的一些方法:
using System;
namespace ArrayApplication
{
class MyArray
{
static void Main(string[] args)
{
int[] list = { 34, 72, 13, 44, 25, 30, 10 };
int[] temp = list;
Console.Write("Original Array: ");
foreach (int i in list)
{
Console.Write(i + " ");
}
Console.WriteLine();
// reverse the array
Array.Reverse(temp);
Console.Write("Reversed Array: ");
foreach (int i in temp)
{
Console.Write(i + " ");
}
Console.WriteLine();
//sort the array
Array.Sort(list);
Console.Write("Sorted Array: ");
foreach (int i in list)
{
Console.Write(i + " ");
}
Console.WriteLine();
Console.ReadKey();
}
}
}
当编译和执行上述代码时,会产生以下结果:
Original Array: 34 72 13 44 25 30 10
Reversed Array: 10 30 25 44 13 72 34
Sorted Array: 10 13 25 30 34 44 72


