1,c#程序结构:
using System;
namespace HelloWorldApplication
{
class HelloWorld
{
static void Main(string[] args)
{
/* 我的第一个 C# 程序*/
Console.WriteLine("Hello World");
Console.ReadKey();
}
}
}
程序各个部分的意思:
· 程序的第一行 usingSystem; - using 关键字用于在程序中包含 System 命名空间。一个程序一般有多个 using 语句。
· 下一行是 namespace 声明。一个 namespace 是一系列的类。HelloWorldApplication 命名空间包含了类 HelloWorld。
· 下一行是 class 声明。类 HelloWorld 包含了程序使用的数据和方法声明。类一般包含多个方法。方法定义了类的行为。在这里,HelloWorld 类只有一个 Main 方法。
· 下一行定义了 Main 方法,是所有 C# 程序的 入口点。Main 方法说明当执行时类将做什么动作。
· 下一行/*...*/将会被编译器忽略,且它会在程序中添加额外的 注释。
· Main方法通过语句 Console.WriteLine("Hello World"); 指定了它的行为。
WriteLine 是一个定义在 System 命名空间中的 Console 类的一个方法。该语句会在屏幕上显示消息 "Hello, World!"。
· 最后一行 Console.ReadKey(); 是针对 VS.NET 用户的。这使得程序会等待一个按键的动作,防止程序从 Visual Studio .NET启动时屏幕会快速运行并关闭。
以下几点值得注意:
· C#是大小写敏感的。
· 所有的语句和表达式必须以分号(;)结尾。
· 程序的执行从Main方法开始。
· 与Java不同的是,文件名可以不同于类的名称。
编译执行c#程序(VS);
· 启动Visual Studio。
· 在菜单栏上,选择File -> New -> Project。
· 从模板中选择Visual C#,然后选择 Windows。
· 选择Console Application。
· 为您的项目制定一个名称,然后点击 OK按钮。
· 新项目会出现在解决方案资源管理器(Solution Explorer)中。
· 在代码编辑器(CodeEditor)中编写代码。
· 点击Run按钮或者按下F5 键来运行程序。会出现一个命令提示符窗口(Command Prompt window),显示 Hello World。
2,c#基本语法:
(1)数据类型:
1):值类型:
bool | 布尔值 | True 或 False | False |
byte | 8 位无符号整数 | 0 到 255 | 0 |
char | 16 位 Unicode字符 | U +0000 到 U +ffff | '\0' |
decimal | 128 位精确的十进制值,28-29有效位数 | (-7.9 x 1028 到 7.9 x 1028) / 100到 28 | 0.0M |
double | 64 位双精度浮点型 | (+/-)5.0 x 10-324 到 (+/-)1.7 x 10308 | 0.0D |
float | 32 位单精度浮点型 | -3.4 x 1038 到 + 3.4 x 1038 | 0.0F |
int | 32 位有符号整数类型 | -2,147,483,648 到 2,147,483,647 | 0 |
long | 64 位有符号整数类型 | -923,372,036,854,775,808 到 9,223,372,036,854,775,807 | 0L |
sbyte | 8 位有符号整数类型 | -128 到 127 | 0 |
short | 16 位有符号整数类型 | -32,768 到 32,767 | 0 |
uint | 32 位无符号整数类型 | 0 到 4,294,967,295 | 0 |
ulong | 64 位无符号整数类型 | 0 到 18,446,744,073,709,551,615 | 0 |
ushort | 16 位无符号整数类型 | 0 到 65,535 | 0 |
2):引用类型
引用类型不包含存储在变量中的实际数据,但它们包含对变量的引用。
换句话说,它们指的是一个内存位置。使用多个变量时,引用类型可以指向一个内存位置。如果内存位置的数据是由一个变量改变的,其他变量会自动反映这种值的变化。内置的 引用类型有:object、dynamic 和 string。其实引用类型就是c++中的别名。
对象类型(Object):对象(Object)类型 是 C# 通用类型系统(Common Type System - CTS)中所有数据类型的终极基类。Object是 System.Object类的别名。所以对象(Object)类型可以被分配任何其他类型(值类型、引用类型、预定义类型或用户自定义类型)的值。但是,在分配值之前,需要先进行类型转换。当一个值类型转换为对象类型时,则被称为 装箱;另一方面,当一个对象类型转换为值类型时,则被称为 拆箱。
object obj; obj = 100; // 这是装箱 int a =(int) obj;//这是拆箱
动态(Dynamic)类型:您可以存储任何类型的值在动态数据类型变量中。这些变量的类型检查是在运行时发生的。
声明动态类型的语法:
dynamic <variable_name> = value;
例如:
dynamic d = 20;
动态类型与对象类型相似,但是对象类型变量的类型检查是在编译时发生的,而动态类型变量的类型检查是在运行时发生的。
字符串(String)类型:允许您给变量分配任何字符串值。字符串(String)类型是 System.String 类的别名。它是从对象(Object)类型派生的。字符串(String)类型的值可以通过两种形式进行分配:引号和 @引号。
例如:
String str = "runoob.com"; 一个 @引号字符串: @"runoob.com"; C# string 字符串的前面可以加 @(称作"逐字字符串")将转义字符(\)当作普通字符对待,比如: string str = @"C:\Windows"; 等价于: string str = "C:\\Windows"; @ 字符串中可以任意换行,换行符及缩进空格都计算在字符串长度之内。 string str = @"<script type=""text/javascript""> <!-- --> </script>";
用户自定义引用类型有:class、interface或 delegate。我们将在以后的章节中讨论这些类型。
3):指针类型
指针类型变量存储另一种类型的内存地址。C#中的指针与 C 或 C++ 中的指针有相同的功能。
声明指针类型的语法:
type* identifier; 例如: char* cptr; int* iptr;
(2)c#类型转换
类型转换方法:
1 | ToBoolean |
2 | ToByte |
3 | ToChar |
4 | ToDateTime |
5 | ToDecimal |
6 | ToDouble |
7 | ToInt16 |
8 | ToInt32 |
9 | ToInt64 |
10 | ToSbyte |
11 | ToSingle |
12 | ToString |
13 | ToType |
14 | ToUInt16 |
15 | ToUInt32 |
16 | ToUInt64 |
eg:
using System;
usingSystem.Collections.Generic;
using System.Linq;
using System.Text;
usingSystem.Threading.Tasks;
namespace One
{
classProgram
{
staticvoid Main(string[] args)
{
int i = 1;
Console.WriteLine(i.ToString());//显示转换
int num;
//函数 Convert.ToInt32() 把用户输入的数据转换为 int 数据类型,因为 Console.ReadLine() 只接受字符串格式的数据。
num = Convert.ToInt32(Console.ReadLine());//等价于:int.Parse(Console.ReadLine());
long b = i;//隐式转换
Console.WriteLine(b);
Console.WriteLine("你输入的值为(显示转换):{0},隐式转换:{1}", num,b);
//Console.WriteLine("hello{0}!","world");
//Console.WriteLine("int{0},decimal {1}",sizeof(int),sizeof(decimal));
Console.ReadKey();
}
}
}
(3)变量和常量:操作和c++差不多
1)变量
类型 | 举例 |
整数类型 | sbyte、byte、short、ushort、int、uint、long、ulong和 char |
浮点型 | float 和 double |
十进制类型 | decimal |
布尔类型 | true 或 false值,指定的值 |
空类型 | 可为空值的数据类型 |
2)常量:
和Java中的一样,不过就是常量的起名不一样而已,java是命名都是大写字母,而c#就比较随意,值得一提的就是字符串常量。
字符常量是括在双引号"" 里,或者是括在@"" 里。字符串常量包含的字符与字符常量相似,可以是:普通字符、转义序列和通用字符
使用字符串常量时,可以把一个很长的行拆成多个行,可以使用空格分隔各个部分。这里是一些字符串常量的实例。下面所列的各种形式表示相同的字符串。
eg:
String a = “hello \t c#”;//输出为:hello c#
String b = @“hello \t c#”;//输出为:hello \t c#
(3)c#运算符
c#运算符与其他编程语言差不多,也分为算术运算符,关系运算符,逻辑运算符,位运算符,赋值运算符和其他运算符,至于其他运算符如下:
运算符 | 描述 | 实例 |
sizeof() | 返回数据类型的大小。 | sizeof(int),将返回 4. |
typeof() | 返回 class 的类型。 | typeof(StreamReader); |
& | 返回变量的地址。 | &a; 将得到变量的实际地址。 |
* | 变量的指针。 | *a; 将指向一个变量。 |
? : | 条件表达式 | 如果条件为真 ? 则为 X : 否则为 Y |
is | 判断对象是否为某一类型。 | If( Ford is Car) // 检查 Ford是否是 Car 类的一个对象。 |
as | 强制转换,即使转换失败也不会抛出异常。 | Object obj = new StringReader("Hello"); |
比较重要的就是运算符优先级了,不建议死记,以后用到了,查看即可。下表将按运算符优先级从高到低列出各个运算符,具有较高优先级的运算符出现在表格的上面,具有较低优先级的运算符出现在表格的下面。在表达式中,较高优先级的运算符会优先被计算。
类别 | 运算符 | 结合性 |
后缀 | () [] -> . ++ - - | 从左到右 |
一元 | + - ! ~ ++ - - (type)* & sizeof | 从右到左 |
乘除 | * / % | 从左到右 |
加减 | + - | 从左到右 |
移位 | << >> | 从左到右 |
关系 | < <= > >= | 从左到右 |
相等 | == != | 从左到右 |
位与 AND | & | 从左到右 |
位异或 XOR | ^ | 从左到右 |
位或 OR | | | 从左到右 |
逻辑与 AND | && | 从左到右 |
逻辑或 OR | || | 从左到右 |
条件 | ?: | 从右到左 |
赋值 | = += -= *= /= %=>>= <<= &= ^= |= | 从右到左 |
逗号 | , | 从左到右 |
(4)判断循环
1)判断:
判断和其他语言一样就不重复了,值得一提的是?:运算符。条件运算符 ? :,可以用来替代 if...else 语句。它的一般形式如下:
Exp1 ? Exp2 : Exp3;
其中,Exp1、Exp2 和 Exp3 是表达式。请注意,冒号的使用和位置。
? 表达式的值是由 Exp1 决定的。如果 Exp1 为真,则计算 Exp2 的值,结果即为整个 ? 表达式的值。如果 Exp1 为假,则计算 Exp3 的值,结果即为整个 ? 表达式的值。
2)循环:
在循环的时候,也有while循环,for/foreach循环,do…while循环,嵌套循环,循环控制语句:break;continue语句;
(5)c#可空类型(Nullable)
早循环C# 提供了一个特殊的数据类型,nullable 类型(可空类型),可空类型可以表示其基础值类型正常范围内的值,再加上一个 null 值。
例如,Nullable<Int32 >,读作"可空的 Int32",可以被赋值为 -2,147,483,648 到 2,147,483,647 之间的任意值,也可以被赋值为 null 值。类似的,Nullable< bool > 变量可以被赋值为 true 或 false 或 null。
在处理数据库和其他包含可能未赋值的元素的数据类型时,将 null 赋值给数值类型或布尔型的功能特别有用。例如,数据库中的布尔型字段可以存储值 true 或 false,或者,该字段也可以未定义。
声明一个 nullable 类型(可空类型)的语法如下:
< data_type> ? <variable_name>= null;
Null合并运算:
Null 合并运算符用于定义可空类型和引用类型的默认值。Null 合并运算符为类型转换定义了一个预设值,以防可空类型的值为 Null。Null 合并运算符把操作数类型隐式转换为另一个可空(或不可空)的值类型的操作数的类型。
如果第一个操作数的值为 null,则运算符返回第二个操作数的值,否则返回第一个操作数的值。下面的实例演示了这点:
eg:
double? num1 = null; double? num2 = 3.14157; double num3; num3 = num1 ?? 5.34; Console.WriteLine("num3 的值: {0}", num3); num3 = num2 ?? 5.34; Console.WriteLine("num3 的值: {0}", num3); Console.ReadLine();
3,数组(Array)
数组是一个存储相同类型元素的固定大小的顺序集合。数组是用来存储数据的集合,通常认为数组是一个同一类型变量的集合。在声明数组(datatype[] arrayName),初始化,数组,赋值和遍历操作都是和java差不多的。
(1)多维数组
在定义和使用多维数组的时候,和其他语言有点不同在此,展示下c#的定义,访问方式。
eg:
//定义一个string的二维数组
string [,] names =new string[2,3] {
{1,2,3},
{4,5,6}
};
//访问第二行的第三个数据
Console.WriteLine(names[1,2]);//6
//定义一个Int的三维数组
int [,,] m;
(2)交错数组
交错数组就是数组的数组。在此申明一下他和多维数组的区别个人理解,在进行多维数组的定义的时候,举例说明吧,二维数组,二行三列(int a [,] = new int[2,3];)如果定义定义二维的交错数组,int [][] a = new int [5][]; a[0]=new int [3];a[1]=new int[5];看出来区别了吧,在定义二维数组的时候,他的行一定,而且列也是固定的,但是使用交错数组就不一样了,行一定,但是列是可变的。
其在定义的方式也有所不同,用的时候,注意下。
(3)传递数组给函数
通过指定不带索引的数组名来给函数传递一个指向数组的指针。
eg:
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();
/* 一个带有 5 个元素的 int 数组 */
int [] balance = new int[]{1000, 2, 3, 17, 50};
double avg;
/* 传递数组的指针作为参数 */
avg = app.getAverage(balance, 5 ) ;
/* 输出返回值 */
Console.WriteLine( "平均值是: {0} ", avg );
Console.ReadKey();
}
}
}
(4)参数数组
用于传递未知数量的参数给函数。有时,当声明一个方法时,您不能确定要传递给函数作为参数的参数数目。C# 参数数组解决了这个问题,参数数组通常用于传递未知数量的参数给函数。在这里c#提供了arams 关键字,使调用数组为形参的方法时,既可以传递数组实参,也可以只传递一组数组。params 的使用格式为:
public 返回类型方法名称( params 类型名称[] 数组名称 )
eg:
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("总和是: {0}", sum);
Console.ReadKey();
}
}
}
(5)Array类
Array 类是 C#中所有数组的基类,它是在 System命名空间中定义。Array类提供了各种用于数组的属性和方法。
属性:
序号 | 属性 & 描述 |
1 | IsFixedSize |
2 | IsReadOnly |
3 | Length |
4 | LongLength |
5 | Rank |
方法:
序号 | 方法 & 描述 |
1 | Clear |
2 | Copy(Array, Array, Int32) |
3 | CopyTo(Array, Int32) |
4 | GetLength |
5 | GetLongLength |
6 | GetLowerBound |
7 | GetType |
8 | GetUpperBound |
9 | GetValue(Int32) |
10 | IndexOf(Array, Object) |
11 | Reverse(Array) |
12 | SetValue(Object, Int32) |
13 | Sort(Array) |
14 | ToString |
eg:
// 逆转数组
Array.Reverse(temp);
Console.Write("逆转数组: ");
// 排序数组
Array.Sort(list);
4,c#结构
c#的结构和以前c++中的不一样,但是和类也不一样,下面具体说下结构的特点;
- 结构可带有方法、字段、索引、属性、运算符方法和事件。
- 结构可定义构造函数,但不能定义析构函数。但是,您不能为结构定义默认的构造函数。默认的构造函数是自动定义的,且不能被改变。
- 与类不同,结构不能继承其他的结构或类。
- 结构不能作为其他结构或类的基础结构。
- 结构可实现一个或多个接口。
- 结构成员不能指定为 abstract、virtual 或 protected。
- 当您使用 New 操作符创建一个结构对象时,会调用适当的构造函数来创建结构。与类不同,结构可以不使用 New 操作符即可被实例化。
- 如果不使用 New 操作符,只有在所有的字段都被初始化之后,字段才被赋值,对象才被使用。
和类的不同点:
- 类是引用类型,结构是值类型。
- 结构不支持继承。
- 结构不能声明默认的构造函数。
eg:
using System;
struct Books
{
private string title;
private string author;
public void getValues(string t, string a)
{
title = t;
author = a;
}
public void display()
{
Console.WriteLine("Title : {0}", title);
Console.WriteLine("Author : {0}", author);
}
};
public class testStructure
{
public static void Main(string[] args)
{
Books Book1 = new Books(); /* 声明 Book1,类型为 Book */
Books Book2 = new Books(); /* 声明 Book2,类型为 Book */
/* book 1 详述 */
Book1.getValues("C Programming", "Nuha Ali");
/* book 2 详述 */
Book2.getValues("Telecom Billing","Zara Ali");
/* 打印 Book1 信息 */
Book1.display();
/* 打印 Book2 信息 */
Book2.display();
Console.ReadKey();
}
}
5,c#枚举
枚举是一组命名整型常量。枚举类型是使用 enum 关键字声明的。C# 枚举是值数据类型。换句话说,枚举包含自己的值,且不能继承或传递继承。
声明 enum 变量
声明枚举的一般语法:
enum <enum_name>
{
enumeration list
};
其中,
- enum_name 指定枚举的类型名称。
- enumeration list 是一个用逗号分隔的标识符列表。
eg:
using System; namespace EnumApplication { class EnumProgram { enum Days { Sun, Mon, tue, Wed, thu, Fri, Sat }; static void Main(string[] args) { int WeekdayStart = (int)Days.Mon; int WeekdayEnd = (int)Days.Fri; Console.WriteLine("Monday: {0}", WeekdayStart); Console.WriteLine("Friday: {0}", WeekdayEnd); Console.ReadKey(); } } }