C#菜鸟教程学习笔记
C#简介
C# 是一种编程语言,它是由微软开发的。
C# 编程是基于 C 和 C++ 编程语言的,它与 Java 也非常相似。
C# 是 .Net 框架的一部分,且用于编写 .Net 应用程序。
.Net 框架(.Net Framework)能编写出下面类型的应用程序:
①Windows 应用程序
②Web 应用程序
③Web 服务
常用的C# 编程的开发工具:Visual Studio(VS:可视化工作室)
C#程序结构
一个 C# 程序(C# 文件的后缀为 .cs)主要包括以下部分:
①命名空间声明(Namespace declaration)
②一个 class(类)
③Class 方法
④Class 属性
⑤一个 Main 方法
⑥语句(Statements)& 表达式(Expressions)
⑦注释
以HelloWorld程序为例,下面分别是程序代码及程序运行结果:
using System;//在程序中包含System命名空间namespace HelloWorld//该行是 namespace 声明,HelloWorld命名空间包含了类Program。{ class Program//该行是 class 声明,类Program包含了程序使用的数据和方法声明,这里只有一个Main方法。 { static void Main(string[] args)//该行定义了Main方法,Main方法说明当执行时 类将做什么动作。 { Console.WriteLine("Hello World");/*Main 方法通过该语句指定了它的行为。 WriteLine是一个定义在System命名空间中的Console类的一个方法。 该语句会在屏幕上显示消息 "Hello World"。*/ Console.ReadKey();//该行使得程序会等待一个按键的动作,防止程序从VS.NET启动时屏幕会快速运行并关闭。 } }}
static void 和 void 的区别在于,static void 是一个静态函数,而 void 则是普通函数。
静态函数只能在定义它的类或文件内部使用,它不能被继承或重载,也不能被实例化。而普通函数可以在任何地方使用,可以被继承和重载,并且可以被实例化。
string:字符串, arg:参数, console:控制台
C#编程的注意事项:
①C# 是大小写敏感的。
②所有的语句和表达式必须以分号(;)结尾。
③程序的执行从 Main 方法开始。
④与 Java 不同的是,文件名可以不同于类的名称。
C#基本语法
C# 是一种面向对象的编程语言。
例如,以 Rectangle(矩形)对象为例。它具有 length 和 width 属性。根据设计,它可能需要接受这些属性值、计算面积和显示细节。
下面分别是Rectangle程序代码及程序运行结果:
using System;//在程序中包含 System 命名空间namespace RectangleApplication//命名空间声明{ class Rectangle//class声明 { double length;//double用来声明双精度浮点数类型的变量。 double width;//变量是类的属性或数据成员,用于存储数据。Rectangle 类有两个成员变量,名为 length 和 width。 public void Acceptdetails()//函数是一系列执行指定任务的语句。类的成员函数是在类内声明的。Rectangle包含了三个成员函数。 { length = 4.5;//长为4.5 width = 3.5;//宽为3.5 } public double GetArea()//public double用于声明可以被任何其他类或对象访问的双精度浮点数类型的变量或属性 { return length * width;//将矩形的长度和宽度相乘,得到矩形的面积,并将结果返回。 } public void Display() { Console.WriteLine("Length: {0}", length); Console.WriteLine("Width: {0}", width); Console.WriteLine("Area: {0}", GetArea());//在屏幕上显示消息"长" "宽" "面积" } } class ExecuteRectangle//类 ExecuteRectangle 是一个包含 Main() 方法和实例化 Rectangle 类的类。 { static void Main(string[] args) { Rectangle r = new Rectangle();//获得类的实例对象 r.Acceptdetails(); r.Display(); Console.ReadLine();//从控制台读取用户输入的一行文本,调用类的成员函数。 } }}
在C#中,public表示这个方法是公共的,可以在类的内部和外部访问。而void表示这个方法没有返回值。也就是说,这个方法执行完毕后不会返回任何值。如果一个方法有返回值,就需要指定返回值的类型,例如int、string等。而如果一个方法没有返回值,则需要使用void。
标识符
标识符是一种字符串。用来命名 变量、方法、参数和其他程序结构。例如Rectangle程序中的System,RectangleApplication,length,width,Main等都属于标识符。
在 C# 中,类的命名必须遵循如下基本规则:
①标识符必须以字母、下划线或 @ 开头,后面可以跟一系列的字母、数字( 0 - 9 )、下划线( _ )、@。
②标识符中的第一个字符不能是数字。
③标识符必须不包含任何嵌入的空格或符号,比如 ? - +! # % ^ & * ( ) [ ] { } . ; : " ’ / \。
④标识符不能是 C# 关键字。除非它们有一个 @ 前缀。 例如,@if 是有效的标识符,但 if 不是,因为 if 是关键字。
⑤标识符必须区分大小写。大写字母和小写字母被认为是不同的字母。
⑥不能与C#的类库名称相同。
关键字
关键字是 C# 编译器预定义的保留字。这些关键字不能用作标识符,但是,如果想使用这些关键字作为标识符,可以在关键字前面加上 @ 字符作为前缀。
下表列出了 C# 中的保留关键字(Reserved Keywords)和上下文关键字(Contextual Keywords):
Console.ReadKey()、Console.ReadLine()和Console.Read()的区别
①Console.ReadKey(): 从控制台读取一个单一的字符,不需要等待用户按下回车键,而且输入的字符不会显示在控制台上,只有按下特殊键(如方向键、功能键、控制键)时,输入的字符才会显示出来。通常用于读取单个按键(比如 Esc 键)。
②Console.ReadLine(): 从控制台读取用户输入的一行文本,等待用户按下回车键,然后返回用户输入的文本,包括回车符和换行符。通常用于读取多个字符和字符串类型的用户输入。
③Console.Read(): 从控制台读取一个字符,需要等待用户按下回车键才会返回字符,且用户输入的字符会显示在控制台上。返回的是整数类型的 Unicode 字符编码,如果需要读取字符,需要将其强制转换为 char 类型。通常用于读取单个字符类型的用户输入。
简单来说,Console.ReadKey() 用于读取单个按键,Console.ReadLine() 用于读取整行文本,Console.Read() 用于读取单个字符。
占位符
当 WriteLine() 函数有多个参数时,输出第一个参数中的内容,而第二个参数中的内容替换掉第一个参数中对应位置的占位符一起输出。代码及结果如下:
using System;namespace A65a97{ class A65a97 { static void Main(string[] args){ Console.WriteLine("A:{0},a:{1}",65,97); Console.ReadLine();} }}
如果第一个参数没有留占位符,那么第二个参数内容不输出。代码及结果如下:
using System;namespace A65a97{ class A65a97 { static void Main(string[] args){ Console.WriteLine("A:,a:",65,97); Console.ReadLine();} }}
占位符从零开始计数,且占位符中的数字不能大于第二个参数的个数减一(要求占位符必须有可替换的值)。
占位符数字与第二个参数字符位置一一对应。代码及结果如下:
using System;namespace A65a97{ class A65a97 { static void Main(string[] args){ Console.WriteLine("A:{1},a:{0}",65,97); Console.ReadLine();} }}
C#数据类型
在 C# 中,变量分为以下几种类型:
①值类型(Value types)
②引用类型(Reference types)
③指针类型(Pointer types)
值类型
值类型变量可以直接分配给一个值。它们是从类 System.ValueType 中派生的。
值类型直接包含数据。比如 int、char、float,它们分别存储数字、字符、浮点数。当声明一个 int 类型时,系统分配内存来存储值。
下表列出了 C# 2010 中可用的值类型:
如需得到一个类型或一个变量在特定平台上的准确尺寸,可以使用 sizeof 方法。表达式 sizeof(type) 产生以字节为单位存储对象或类型的存储尺寸。举例获取任何机器上 int 类型的存储尺寸的代码及运行结果如下:
using System;namespace DataTypeApplication{ class Program { static void Main(string[] args) { Console.WriteLine("Size of int: {0}", sizeof(int)); Console.ReadLine(); } }}
引用类型
引用类型不包含存储在变量中的实际数据,但它们包含对变量的引用。
换句话说,它们指的是一个内存位置。使用多个变量时,引用类型可以指向一个内存位置。如果内存位置的数据是由一个变量改变的,其他变量会自动反映这种值的变化。内置的 引用类型有:object、dynamic 和 string。
举个很形象的比喻,就像仓库,仓库里有货架,货架上有编号:A1,A2,A3…, 这些编号就可以看做是引用类型,现在来了一批货,有 “土豆,黄瓜,西红柿”,这些就是值类型,如果你想让 A1=土豆,那么就要把土豆搬到 A1 里面去,这就叫装箱,装箱需要耗费人力和工时(也就是耗费CPU和内存),同理拆箱就要把对应编号的货物搬出来,也是需要耗费人力和工时。
对象类型(object)
对象(Object)类型 是 C# 通用类型系统(Common Type System - CTS)中所有数据类型的终极基类。Object 是 System.Object 类的别名。所以对象(Object)类型可以被分配任何其他类型(值类型、引用类型、预定义类型或用户自定义类型)的值。但是,在分配值之前,需要先进行类型转换。
当一个值类型转换为对象类型时,则被称为 装箱;另一方面,当一个对象类型转换为值类型时,则被称为 拆箱。
装箱:值类型转换为对象类型, 实例:
int val = 8;object obj = val;//整型数据转换为了对象类型(装箱)
拆箱:之前由值类型转换而来的对象类型再转回值类型, 实例:
int val = 8;object obj = val;//先装箱int nval = (int)obj;//再拆箱
只有装过箱的数据才能拆箱
动态类型(Dynamic)
可以存储任何类型的值在动态数据类型变量中。这些变量的类型检查是在运行时发生的。
声明动态类型的语法:
dynamic <variable_name> = value;
例如:
dynamic d = 20;
动态类型与对象类型相似,但是对象类型变量的类型检查是在编译时发生的,而动态类型变量的类型检查是在运行时发生的。
字符串类型(String)
字符串(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>";
C# 中 String 跟 string 的区别
string 是 C# 中的类,String 是 .net Framework 的类(在 C# IDE 中不会显示蓝色) C# string 映射为 .net Framework 的String 如果用 string, 编译器会把它编译成 String,所以如果直接用 String 就可以让编译器少做一点点工作。
如果使用 C#,建议使用 string,比较符合规范 string 始终代表 System.String(1.x) 或 ::System.String(2.0) ,String 只有在前面有 using System;的时候并且当前命名空间中没有名为 String 的类型(class、struct、delegate、enum)的时候才代表 System.String string 是关键字,String 不是,也就是说 string 不能作为类、结构、枚举、字段、变量、方法、属性的名称,而 String 可以。
String 是 CLR 的类型名称(也算是关键字),而 string 是 C# 中的关键字。string 在编译时候 C# 编译器会默认将其转换为 String,在这里会多增加几行转换的代码。很多时候都是建议使用 CLR 的类型而不要使用 C# 的类型(这是专家的建议)。比如说还有:使用 int 的时候最好使用 Int32 等。很多时候都是一个习惯问题,规范问题。还有一个不同就是在 VS 中表现的颜色不一样:String 是绿色,string 是蓝色。
指针类型
指针类型变量存储另一种类型的内存地址。C# 中的指针与 C 或 C++ 中的指针有相同的功能。
声明指针类型的语法:
type* identifier;
例如:
char* cptr;int* iptr;
类型转换
类型转换从根本上说是类型铸造,或者说是把数据从一种类型转换为另一种类型。
C# 中的类型转换可以分为两种:隐式转换和显式转换。
隐式转换
隐式转换是指将一个较小范围的数据类型转换为较大范围的数据类型时,编译器会自动完成类型转换,这些转换是 C# 默认的以安全方式进行的转换, 不会导致数据丢失。
例如,从小的整数类型转换为大的整数类型,从派生类转换为基类。将一个 byte 类型的变量赋值给 int 类型的变量,编译器会自动将 byte 类型转换为 int 类型,不需要显示转换。
byte b = 10;int i = b; // 隐式转换,不需要显示转换
显式转换
显式类型转换,即强制类型转换。
显式转换是指将一个较大范围的数据类型转换为较小范围的数据类型时,或者将一个对象类型转换为另一个对象类型时,需要使用强制类型转换符号进行显示转换,强制转换会造成数据丢失。
例如,将一个 int 类型的变量赋值给 byte 类型的变量,需要显示转换。
int i = 10;byte b = (byte)i; // 显式转换,需要使用强制类型转换符号
下面的实例显示了一个显式的类型转换代码及运行结果:
using System;namespace TypeConversionApplication{ class ExplicitConversion { static void Main(string[] args) { double d = 5673.74; int i; // 强制转换 double 为 int i = (int)d; Console.WriteLine(i); Console.ReadKey(); } }}
C# 类型转换方法
C# 提供了下列内置的类型转换方法:
实例把不同值的类型转换为字符串类型的代码及运行结果如下:
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(); } }}
C#变量
一个变量只不过是一个供程序操作的存储区的名字。在 C# 中,每个变量都有一个特定的类型,类型决定了变量的内存大小和布局。范围内的值可以存储在内存中,可以对变量进行一系列操作。
C# 中提供的基本的值类型大致可以分为以下几类:
C# 允许定义其他值类型的变量,比如 enum,也允许定义引用类型变量,比如 class。
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;
C#变量初始化
变量通过在等号后跟一个常量表达式进行初始化(赋值)。初始化的一般形式为:
variable_name = value;
变量可以在声明时被初始化(指定一个初始值)。初始化由一个等号后跟一个常量表达式组成,如下所示:
<data_type> <variable_name> = value;
一些实例:
int d = 3, f = 5; /* 初始化 d 和 f. */byte z = 22; /* 初始化 z. */double pi = 3.14159; /* 声明 pi 的近似值 */char x = 'x'; /* 变量 x 的值为 'x' */
下面的实例,使用了各种类型的变量:
using System;namespace VariableDefinition{ class Program { static void Main(string[] args) { short a; int b ; double c; /* 实际初始化 */ a = 10; b = 20; c = a + b; Console.WriteLine("a = {0}, b = {1}, c = {2}", a, b, c); Console.ReadLine(); } }}
接受来自用户的值
System 命名空间中的 Console 类提供了一个函数 ReadLine(),用于接收来自用户的输入,并把它存储到一个变量中。
例如:
int num;num = Convert.ToInt32(Console.ReadLine());
函数 Convert.ToInt32() 把用户输入的数据转换为 int 数据类型,因为 Console.ReadLine() 只接受字符串格式的数据。
C# 中的 Lvalues 和 Rvalues
C# 中的两种表达式:
①lvalue:lvalue 表达式可以出现在赋值语句的左边或右边。
②rvalue:rvalue 表达式可以出现在赋值语句的右边,不能出现在赋值语句的左边。
变量是 lvalue 的,所以可以出现在赋值语句的左边。数值是 rvalue 的,因此不能被赋值,不能出现在赋值语句的左边。下面是一个有效的语句:
int g = 20;
下面是一个无效的语句,会产生编译时错误:
10 = 20;
不同类型变量进行运算的问题:
double a = 42.29;int b = 4229;int c = a + b;Console.WriteLine("c = {0}",c);Console.ReadKey();
上面这种编程方法是错误的,会出现错误提示:
"无法将类型'double'隐式转换为'int'。"
举例说明,当一个精度高的数据类型与一个精度低的数据类型进行运算时,定义运算结果的变量类型必须与精度最高的变量类型相同。这是为了防止在运算过程中造成数据丢失。
下面是正确代码:
double a = 42.29;int b = 4229;double c = a + b;Console.WriteLine("c = {0}",c);Console.ReadKey();
能输出运算结果:
c = 4271.29
C#常量
常量是固定值,程序执行期间不会改变。常量可以是任何基本数据类型,比如整数常量、浮点常量、字符常量或者字符串常量,还有枚举常量。
常量可以被当作常规的变量,只是它们的值在定义后不能被修改。
整数常量
整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,没有前缀则表示十进制。
整数常量也可以有后缀,可以是 U 和 L 的组合,其中,U 和 L 分别表示 unsigned 和 long。后缀可以是大写或者小写,多个后缀以任意顺序进行组合。
以下是各种类型的整数常量的实例:
85 /* 十进制 */0213 /* 八进制 */0x4b /* 十六进制 */30 /* int */30u /* 无符号 int */30l /* long */30ul /* 无符号 long */
浮点常量
一个浮点常量是由整数部分、小数点、小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量。
这里有一些浮点常量的实例:
3.14159 /* 合法 */314159E-5L /* 合法 */510E /* 非法:不完全指数 */210f /* 非法:没有小数或指数 */.e55 /* 非法:缺少整数或小数 */
使用浮点形式表示时,必须包含小数点、指数或同时包含两者。使用指数形式表示时,必须包含整数部分、小数部分或同时包含两者。有符号的指数是用 e 或 E 表示的。
字符常量
字符常量是括在单引号里,例如,‘x’,且可存储在一个简单的字符类型变量中。一个字符常量可以是一个普通字符(例如 ‘x’)、一个转义序列(例如 ‘\t’)或者一个通用字符(例如 ‘\u02C0’)。
在 C# 中有一些特定的字符,当它们的前面带有反斜杠时有特殊的意义,可用于表示换行符(\n)或制表符 tab(\t)。在这里,列出一些转义序列码:
以下是一些转义序列字符的实例:
using System;namespace EscapeChar{ class Program { static void Main(string[] args) { Console.WriteLine("Hello\nWorld\n\t"); Console.ReadLine(); } }}
字符串常量
字符串常量是括在双引号 “” 里,或者是括在 @“” 里。字符串常量包含的字符与字符常量相似,可以是:普通字符、转义序列和通用字符
使用字符串常量时,可以把一个很长的行拆成多个行,可以使用空格分隔各个部分。
这里是一些字符串常量的实例。下面所列的各种形式表示相同的字符串。
string a = "hello, world"; // hello, worldstring b = @"hello, world"; // hello, worldstring c = "hello \t world"; // hello worldstring d = @"hello \t world"; // hello \t worldstring e = "Joe said \"Hello\" to me"; // Joe said "Hello" to mestring f = @"Joe said ""Hello"" to me"; // Joe said "Hello" to mestring g = "\\\\server\\share\\file.txt"; // \\server\share\file.txtstring h = @"\\server\share\file.txt"; // \\server\share\file.txtstring i = "one\r\ntwo\r\nthree";string j = @"onetwothree";
定义常量
常量是使用 const 关键字来定义的 。定义一个常量的语法如下:
const <data_type> <constant_name> = value;
下面的代码演示了如何在程序中定义和使用常量:
using System;public class ConstTest{ class SampleClass { public int x; public int y; public const int c1 = 5; public const int c2 = c1 + 5; public SampleClass(int p1, int p2) { x = p1; y = p2; } } static void Main() { SampleClass mC = new SampleClass(11, 22); Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y); Console.WriteLine("c1 = {0}, c2 = {1}", SampleClass.c1, SampleClass.c2); }}
C# 运算符
运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。
C# 有丰富的内置运算符,分类如下:
①算术运算符
②关系运算符
③逻辑运算符
④位运算符
⑤赋值运算符
⑥其他运算符
算术运算符
下表显示了 C# 支持的所有算术运算符。假设变量 A 的值为 10,变量 B 的值为 20,则:
请看下面的实例,了解 C# 中所有可用的算术运算符:
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 - c 的值是 {0}", c); c = a - b; Console.WriteLine("Line 2 - c 的值是 {0}", c); c = a * b; Console.WriteLine("Line 3 - c 的值是 {0}", c); c = a / b; Console.WriteLine("Line 4 - c 的值是 {0}", c); c = a % b; Console.WriteLine("Line 5 - c 的值是 {0}", c); // ++a 先进行自增运算再赋值 c = ++a; Console.WriteLine("Line 6 - c 的值是 {0}", c); // 此时 a 的值为 22 // --a 先进行自减运算再赋值 c = --a; Console.WriteLine("Line 7 - c 的值是 {0}", c); Console.ReadLine(); } }}
当上面的代码被编译和执行时,它会产生下列结果:
Line 1 - c 的值是 31Line 2 - c 的值是 11Line 3 - c 的值是 210Line 4 - c 的值是 2Line 5 - c 的值是 1Line 6 - c 的值是 22Line 7 - c 的值是 21
①c = a++: 先将 a 赋值给 c,再对 a 进行自增运算。
②c = ++a: 先将 a 进行自增运算,再将 a 赋值给 c 。
③c = a–: 先将 a 赋值给 c,再对 a 进行自减运算。
④c = --a: 先将 a 进行自减运算,再将 a 赋值给 c 。
请看实例:
using System;namespace OperatorsAppl{ class Program { static void Main(string[] args) { int a = 1; int b; // a++ 先赋值再进行自增运算 b = a++; Console.WriteLine("a = {0}", a); Console.WriteLine("b = {0}", b); Console.ReadLine(); // ++a 先进行自增运算再赋值 a = 1; // 重新初始化 a b = ++a; Console.WriteLine("a = {0}", a); Console.WriteLine("b = {0}", b); Console.ReadLine(); // a-- 先赋值再进行自减运算 a = 1; // 重新初始化 a b= a--; Console.WriteLine("a = {0}", a); Console.WriteLine("b = {0}", b); Console.ReadLine(); // --a 先进行自减运算再赋值 a = 1; // 重新初始化 a b= --a; Console.WriteLine("a = {0}", a); Console.WriteLine("b = {0}", b); Console.ReadLine(); } }}
执行以上程序,输出结果为:
a = 2b = 1a = 2b = 2a = 0b = 1a = 0b = 0
关系运算符
下表显示了 C# 支持的所有关系运算符。
假设变量 A 的值为 10,变量 B 的值为 20,则:
请看下面的实例,了解 C# 中所有可用的关系运算符:
using System;class Program{ static void Main(string[] args) { int a = 21; int b = 10; if (a == b) { Console.WriteLine("Line 1 - a 等于 b"); } else { Console.WriteLine("Line 1 - a 不等于 b"); } if (a < b) { Console.WriteLine("Line 2 - a 小于 b"); } else { Console.WriteLine("Line 2 - a 不小于 b"); } if (a > b) { Console.WriteLine("Line 3 - a 大于 b"); } else { Console.WriteLine("Line 3 - a 不大于 b"); } /* 改变 a 和 b 的值 */ a = 5; b = 20; if (a <= b) { Console.WriteLine("Line 4 - a 小于或等于 b"); } if (b >= a) { Console.WriteLine("Line 5 - b 大于或等于 a"); } }}
当上面的代码被编译和执行时,它会产生下列结果:
Line 1 - a 不等于 bLine 2 - a 不小于 bLine 3 - a 大于 bLine 4 - a 小于或等于 bLine 5 - b 大于或等于 a
逻辑运算符
下表显示了 C# 支持的所有逻辑运算符。假设变量 A 为布尔值 true,变量 B 为布尔值 false,则:
请看下面的实例,了解 C# 中所有可用的逻辑运算符:
using System;namespace OperatorsAppl{ class Program { static void Main(string[] args) { bool a = true; bool b = true; if (a && b) { Console.WriteLine("Line 1 - 条件为真"); } if (a || b) { Console.WriteLine("Line 2 - 条件为真"); } /* 改变 a 和 b 的值 */ a = false; b = true; if (a && b) { Console.WriteLine("Line 3 - 条件为真"); } else { Console.WriteLine("Line 3 - 条件不为真"); } if (!(a && b)) { Console.WriteLine("Line 4 - 条件为真"); } Console.ReadLine(); } }}
当上面的代码被编译和执行时,它会产生下列结果:
Line 1 - 条件为真Line 2 - 条件为真Line 3 - 条件不为真Line 4 - 条件为真
位运算符
位运算符作用于位,并逐位执行操作。&、 | 和 ^ 的真值表如下所示:
假设如果 A = 60,且 B = 13,现在以二进制格式表示,它们如下所示:
A = 0011 1100
B = 0000 1101
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
~A = 1100 0011
下表列出了 C# 支持的位运算符。假设变量 A 的值为 60,变量 B 的值为 13,则:
请看下面的实例,了解 C# 中所有可用的位运算符:
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 - c 的值是 {0}", c ); c = a | b; /* 61 = 0011 1101 */ Console.WriteLine("Line 2 - c 的值是 {0}", c); c = a ^ b; /* 49 = 0011 0001 */ Console.WriteLine("Line 3 - c 的值是 {0}", c); c = ~a; /*-61 = 1100 0011 */ Console.WriteLine("Line 4 - c 的值是 {0}", c); c = a << 2; /* 240 = 1111 0000 */ Console.WriteLine("Line 5 - c 的值是 {0}", c); c = a >> 2; /* 15 = 0000 1111 */ Console.WriteLine("Line 6 - c 的值是 {0}", c); Console.ReadLine(); } }}
当上面的代码被编译和执行时,它会产生下列结果:
Line 1 - c 的值是 12Line 2 - c 的值是 61Line 3 - c 的值是 49Line 4 - c 的值是 -61Line 5 - c 的值是 240Line 6 - c 的值是 15
正数的补码=原码=反码,
负数的反码=原码的取反(二进制数的符号位除外,一般来说在二进制的左边的最高位)
负数的补码=反码+1
注意:若已知补码为 1111 1000,如何求其原码呢?
① 方法1:求负数 原码—>补码 的逆过程。
注意:符号位保持不变!
(A)先 - 1,得到 1111 0111
(B)取反(符号位保持不变,其他位置按位取反 ),得到 1000 1000
②方法2:
注意:符号位保持不变!
(A)将这个二进制数中(即 1111 1000),除了符号位,其余位置按位取反,得 1000 0111
(B)+ 1,得到 1000 1000
按位取反:二进制的每一位都取反(符号位+数据位)
公式法:
~x=-(x+1)
举两个例子:~11=-(11+1)=-12
~(-11)=10
公式法的内部是如何计算的呢:
以~11为例:
~11的计算步骤:
计算11的补码
①转二进制:0 1011
计算补码:0 1011
②按位取反:1 0100 (按位取反是在这进行的,即补码的形式进行按位取反) 注意:这里是补码
③将转为原码:
取其反码(因为补码是负数):1 1011
末位加一:1 1100
④符号位为1是负数,即-12
以~(-11)为例:
~(-11)的计算步骤:
①计算-11的补码
转二进制:1 1011
计算补码:1 0101
②按位取反:0 1010 (按位取反是在这进行的,即补码的形式进行按位取反) 注意:这里是补码
③将转为原码:
正数补码就是原码:0 1010
④符号位为0是正数,即10
赋值运算符
下表列出了 C# 支持的赋值运算符:
请看下面的实例,了解 C# 中所有可用的赋值运算符:
using System;namespace OperatorsAppl{ class Program { static void Main(string[] args) { int a = 21; int c; c = a; Console.WriteLine("Line 1 - = c 的值 = {0}", c); c += a; Console.WriteLine("Line 2 - += c 的值 = {0}", c); c -= a; Console.WriteLine("Line 3 - -= c 的值 = {0}", c); c *= a; Console.WriteLine("Line 4 - *= c 的值 = {0}", c); c /= a; Console.WriteLine("Line 5 - /= c 的值 = {0}", c); c = 200; c %= a; Console.WriteLine("Line 6 - %= c 的值 = {0}", c); c <<= 2; Console.WriteLine("Line 7 - <<= c 的值 = {0}", c); c >>= 2; Console.WriteLine("Line 8 - >>= c 的值 = {0}", c); c &= 2; Console.WriteLine("Line 9 - &= c 的值 = {0}", c); c ^= 2; Console.WriteLine("Line 10 - ^= c 的值 = {0}", c); c |= 2; Console.WriteLine("Line 11 - |= c 的值 = {0}", c); Console.ReadLine(); } }}
当上面的代码被编译和执行时,它会产生下列结果:
Line 1 - = c 的值 = 21Line 2 - += c 的值 = 42Line 3 - -= c 的值 = 21Line 4 - *= c 的值 = 441Line 5 - /= c 的值 = 21Line 6 - %= c 的值 = 11Line 7 - <<= c 的值 = 44Line 8 - >>= c 的值 = 11Line 9 - &= c 的值 = 2Line 10 - ^= c 的值 = 0Line 11 - |= c 的值 = 2
其他运算符
下表列出了 C# 支持的其他一些重要的运算符,包括 sizeof、typeof 和 ? :。
实例
using System;namespace OperatorsAppl{ class Program { static void Main(string[] args) { /* sizeof 运算符的实例 */ Console.WriteLine("int 的大小是 {0}", sizeof(int)); Console.WriteLine("short 的大小是 {0}", sizeof(short)); Console.WriteLine("double 的大小是 {0}", sizeof(double)); /* 三元运算符的实例 */ int a, b; a = 10; b = (a == 1) ? 20 : 30; Console.WriteLine("b 的值是 {0}", b); b = (a == 10) ? 20 : 30; Console.WriteLine("b 的值是 {0}", b); Console.ReadLine(); } }}
当上面的代码被编译和执行时,它会产生下列结果:
int 的大小是 4short 的大小是 2double 的大小是 8b 的值是 30b 的值是 20
typeof 关键字用于获取一个类型的类型对象,它通常用于反射和动态创建类型实例。
下面是一个使用 typeof 的简单示例:
using System;class Program{ static void Main(string[] args) { Type type = typeof(string); Console.WriteLine(type.FullName); Console.ReadKey(); }}
在上面的代码中,我们使用 typeof 关键字来获取 string 类型的类型对象,并将其存储在 Type 类型的变量 type 中,然后,我们使用 FullName 属性打印该类型的完全限定名。
当上面的代码被编译和执行时,它会产生下列结果:
System.String
C# 中的运算符优先级
运算符的优先级确定表达式中项的组合。这会影响到一个表达式如何计算。某些运算符比其他运算符有更高的优先级,例如,乘除运算符具有比加减运算符更高的优先级。
优先级简易概括:有括号先括号,后乘除在加减,然后位移再关系,逻辑完后条件,最后一个逗号 ,
C#判断
判断结构要求程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的)。
判断语句
C# 提供了以下类型的判断语句。
? : 运算符
条件运算符 ? :,可以用来替代 if…else 语句。它的一般形式如下:
Exp1 ? Exp2 : Exp3;
其中,Exp1、Exp2 和 Exp3 是表达式。
? 表达式的值是由 Exp1 决定的。如果 Exp1 为真,则计算 Exp2 的值,结果即为整个 ? 表达式的值。如果 Exp1 为假,则计算 Exp3 的值,结果即为整个 ? 表达式的值。
C#循环
循环类型
C# 提供了以下几种循环类型。
循环控制语句
C# 提供了下列的控制语句。
无限循环
如果条件永远不为假,则循环将变成无限循环。for 循环在传统意义上可用于实现无限循环。由于构成循环的三个表达式中任何一个都不是必需的,您可以将某些条件表达式留空来构成一个无限循环。
当条件表达式不存在时,它被假设为真。您也可以设置一个初始值和增量表达式,但是一般情况下,程序员偏向于使用 for(; ; ) 结构来表示一个无限循环。
C#封装
封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中"。在面向对象程序设计方法论中,封装是为了防止对实现细节的访问。
抽象和封装是面向对象程序设计的相关特性。抽象允许相关信息可视化,封装则使开发者实现所需级别的抽象。
C# 封装根据具体的需要,设置使用者的访问权限,并通过 访问修饰符 来实现。
一个 访问修饰符 定义了一个类成员的范围和可见性。C# 支持的访问修饰符如下所示:
①public:所有对象都可以访问;
②private:对象本身在对象内部可以访问;
③protected:只有该类对象及其子类对象可以访问
④internal:同一个程序集的对象可以访问;
⑤protected internal:访问限于当前程序集或派生自包含类的类型(③和④ 的并集,符合任意一条都可以访问)。
Public 访问修饰符
Public 访问修饰符允许一个类将其成员变量和成员函数暴露给其他的函数和对象。任何公有成员可以被外部的类访问。
下面的实例说明了这点:
using System;namespace RectangleApplication{ class Rectangle { //成员变量 public double length; public double width; public double GetArea() { return length * width; } public void Display() { Console.WriteLine("长度: {0}", length); Console.WriteLine("宽度: {0}", width); Console.WriteLine("面积: {0}", GetArea()); } }// Rectangle 结束 class ExecuteRectangle { static void Main(string[] args) { Rectangle r = new Rectangle(); r<