C#学习(1)–基础语法与概念
C#概念以及.NET平台基本介绍
C#语言特色
- 简洁的语法
- 完全的面向对象程序设计
- 与Web紧密结合
- 充分的安全性与错误处理
- 灵活性
- 兼容性
C#编写应用程序
- 控制台应用程序
- Windows窗体应用程序
- ASP.NET Web窗体应用程序
- ……
.NET 平台概念
- 是微软推出的下一代软件开发和服务平台
- 是一种面向网络,支持各种用户终端的开发环境。
托管代码与非托管代码
- 托管代码(managed code)是指为.NET Framework编写的代码,在.NET Framework的公共语言运行库(CLR)控制之下运行,类似于JAVA的虚拟机机制。托管代码应用程序可以获得CLR服务,例如自动垃圾回收、类型检查和安全支持等。
- 非托管代码(unmanaged code)是指不在CLR控制之下运行的代码,如Win32 C/C++ DLL。非托管代码由操作系统直接运行,因此必须提供自己的垃圾回收、类型检查、安全支持等服务。
.NET Framework类库(FCL)
程序员可以十分方便地使用FCL中的类型及其成员,而不必编写大量代码来处理常见的低级编程操作。它是生成.NET Framework应用程序、组件和控件的基础。
FCL由命名空间组成。每个命名空间都包含可在程序中使用的类型,如类、结构、枚举、委托和接口等。
公共语言运行库(CLR)
CLR主要由CLS和CTS两部分组成。
CLR是.NET Framework的核心组件,它在操作系统的顶层,负责管理程序的执行。
(1)公共语言规范(Common Language Specification,简写为CLS)
各种编程语言之间不仅仅是数据类型的不同,语法也有非常大的区别。所以需要定义CLS,它定义了所有编程语言必须遵守的共同标准,包含函数调用方式、参数传递方式、数据类型和异常处理方式等。
(2)通用类型系统(Common Type System,简写为CTS)
CTS定义了一套可以在中间语言中使用的预定义数据类型,所有面向.NET Framework的语言都可以生成最终基于这些类型的编译代码。也就是说,通用类型系统用于解决不同编程语言的数据类型不同的问题,从而实现跨语言功能。
例如,无论VB中的integer类型(VB中的整型)还是C#中的int类型(C#中的整型),编译后都映射为System.Int32。所以CTS实现了不同语言数据类型的最终统一。
微软中间语言MSIL
- 使用.NET Framework语言编译器把源代码编译成与机器无关的中间语言MSIL
- 运行Microsoft中间语言(MSIL)之前,必须先根据CLR将其编译为适合目标计算机体系结构的本机代码
该机制使得.NET 平台可以实现跨平台
- .NET Framework 提供了使用JIT和NGen.exe两种方式来执行此类转换。
C#项目运行过程
C#语法
三种方式读入整数
a=int.Parse(Console.ReadLine());
b=int.TryParse(Console.ReadLine(),out a);
c=Convert.ToInt32(Console.ReadLine());
Console.WriteLine的格式化输出
object类
object是C#中所有类型(包括所有的值类型和引用类型)的基类,C#中的所有类型都直接或间接地从object类中继承而来。因此,对一个object的变量可以赋予任何类型的值。
在装箱拆箱是有用。
string类
- 注意!当使用@时后面的字符串不会转义
using System;
namespace _1._2
{
class Program
{
static void Main(string[] args)
{
string str1 = “123” + “abc”; //"+“运算符用于连接字符串
char c = “Hello World!”[2]; //”[]“运算符可以访问string中的单个字符,c=‘e’
string str2 = “\nChina”;
string str3 = @”\nChina"; // 字符串的另一种表示形式,用@引起来。
Console.WriteLine(str2);
Console.WriteLine(str3);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
值类型变量和引用类型变量的区别
值类型变量生活在栈空间中
值类型变量
C#中的值类型变量和C/C++语言中的普通变量(非指针变量)相似,这类变量直接包含它们的值。所有的值类型均隐式派生自 System.ValueType。
C#中在内存的栈空间中为值类型变量分配空间,而且没有单独的堆分配或垃圾回收开销。因此值类型变量会随着方法调用后栈空间的消亡而自动清除(C#中的值类型变量像C/C++语言中函数内的局部变量,函数执行完后由系统释放其存储空间)。
引用类型变量生存在堆空间中
引用类型变量
引用类型本身存在栈空间中,但是引用类型所指向的实例在堆空间中。
在C#中没有指针,而改为引用,引用表示某个对象的地址而不是变量或对象本身。
栈空间和堆空间
栈空间就是一个数据结构
- 栈空间是一种先进后出的数据结构。栈空间用于存储如下类型的数据
- 某些类型变量的值。
- 程序当前的执行环境。
- 传递给方法的参数。
堆空间是一块内存空间
- 在堆空间中可以分配大块的内存以存储某类型的数据对象。
- 与栈不同,堆里的空间能够以任意顺序存入和移除。
显式和隐式转换
显式类型转换
- 显式转换又叫强制类型转换,与隐式转换相反,显式转换需要用户明确地指定转换类型,一般在不存在该类型的隐式转换时才使用。
(类型标识符)表达式
隐式类型转换
- 隐式转换是系统默认的、不需要加以声明就可以进行的转换。
例子
using System;
namespace proj2_1
{ class Program
{ static void Main(string[] args)
{ int i=65,i1,i2;
double d = 66.3456,d1,d2;
char c = 'A',c1,c2;
Console.WriteLine("i={0:d5},d={1:f},c={2}", i, d, c);
i1 = (int)d; //强制类型转换
d1 = i; //隐式类型转换
c1 = (char)i; //强制类型转换
Console.WriteLine("i1={0:d5},d1={1:f},c1={2}", i1, d1, c1);
i2 = c; //隐式类型转换
d2 = (int)d; //强制类型转换,转换成整数后再隐式转为double类型
c2 = (char)d; //强制类型转换
Console.WriteLine("i2={0:d5},d2={1:f},c2={2}", i2, d2, c2);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
装箱与拆箱
装箱
- 装箱转换是指将一个值类型的数据隐式地转换成一个对象类型的数据。例如,下面语句就执行了装箱转换:
- int i=10;
- object obj=i;
拆箱
- 拆箱转换是指将一个引用类型的数据显式地转换成一个值类型数据。
- 拆箱操作分为两步:首先检查对象实例,确保它是给定值类型的一个装箱值,然后把实例的值复制到值类型数据中。例如,下面两条语句就执行了拆箱转换:
- object obj=10;
- int i=(int)obj; //拆箱
结构类型,枚举类型
结构类型
同C++中的结构体
如:
struct Student //声明结构类型Student
{ public int xh; //学号
public string xm; //姓名
public string xb; //性别
public int nl; //年龄
public string bh; //班号
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
枚举类型
枚举类型也是一种自定义数据类型,它允许用符号代表数据。
enum Color {Red,Green,Blue,White,Black}
- 1
/*在声明的枚举类型中,每一个枚举成员都有一个相对应的常量值,默认情况下C#规定第1个枚举成员的值取0,它后面的每一个枚举成员的值按加1递增*/
enum Color { Red=0, Green, Blue=3, White, Black=1};
/*可以为一个或多个枚举成员赋整型值,当某个枚举成员赋值后,其后的枚举成员没有赋值的话,自动在前一个枚举成员值之上加1作为其值。例如:*/
enum Color { Red=0, Green, Blue=3, White, Black=1};
/*1)枚举变量的赋值
枚举变量赋值的语法格式如下:
枚举变量=枚举名.枚举成员
例如:*/
c1=Color.Red;
/*
2)枚举变量的访问
枚举变量像普通变量一样直接访问。
*/
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
String、Math、Convert、DateTime类
静态方法与非静态方法区别
静态方法相当于类本身的方法,不需要实例化,相当于直接调用这个类包含的一个函数。
如:
string.Compare(mstr, sstr);
- 1
而非静态方法则更接近与C++中的类中的函数需要有实例才可以使用
如:
String mstr, sstr;
Console.Write("输入主串:");
mstr = Console.ReadLine();
Console.Write("输入子串:");
sstr = Console.ReadLine();
mstr.CompareTo(sstr);
- 1
- 2
- 3
- 4
- 5
- 6
String类
方法 | 说明 |
---|---|
Compare | 静态方法。比较两个指定的String对象 |
CompareTo | 非静态方法。将此字符串与指定的对象或String进行比较,并返回两者相对值的指示 |
Concat | 静态方法。连接String的一个或多个字符串 |
Contains | 非静态方法。返回一个值,该值指示指定的String对象是否出现在此字符串中 |
Equals | 非静态方法。确定两个String对象是否具有相同的值 |
Format | 静态方法。将指定的String中的每个格式项替换为相应对象的值的文本等效项 |
IndexOf | 非静态方法。返回String或一个或多个字符在此字符串中的第一个匹配项的索引 |
Insert | 非静态方法。在该String中的指定索引位置插入一个指定的String |
Remove | 非静态方法。从该String中删除指定个数的字符 |
Replace | 非静态方法。将该String中的指定String的所有匹配项替换为其他指定的 String |
Split | 非静态方法。返回包含该String中的子字符串(由指定Char或String数组的元素分隔)的String数组 |
Substring | 非静态方法。从此字符串中检索子字符串 |
ToLower | 非静态方法。返回该String转换为小写形式的副本 |
ToUpper | 非静态方法。返回该String转换为大写形式的副本 |
Trim | 非静态方法。从此字符串的开始位置和末尾移除一组指定字符的所有匹配项 |
Math类
Math类中都是静态方法,可以直接通过Math.方法,调用。
Convert类
都是静态方法,Convert.方法名(参数)调用。
具体看书…
控制语句
switch,if,while,for语句同C++
using System;
namespace proj3_4
{ class Program
{ static void Main(string[] args)
{ float x;
Console.Write("分数:");
x=float.Parse(Console.ReadLine());
if (x>=90) Console.WriteLine("等级为A");
else if (x >= 80) Console.WriteLine("等级为B");
else if (x >= 70) Console.WriteLine("等级为C");
else if (x >= 60) Console.WriteLine("等级为D");
else Console.WriteLine("等级为E");
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
using System;
namespace proj3_6
{ class Program
{ static void Main(string[] args)
{ int digit,num;
Console.Write( "输入一个整数:");
num=int.Parse(Console.ReadLine());
Console.Write( "反向显示结果:");
while (num!=0)
{ digit=num % 10; //依次求个位、十位、…上的数字digit
num=num / 10;
Console.Write(digit);
}
Console.WriteLine();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
using System;
namespace proj3_5
{ class Program
{ static void Main(string[] args)
{ char ch;
Console.Write("课程代号:");
ch=(char)Console.Read();
switch (ch)
{ case 'm': case 'M': case 'w': case 'W':
Console.WriteLine("8学分");
break;
case 'p': case 'P': case 'c': case 'C':
Console.WriteLine("5学分");
break;
case 'e': case 'E':
Console.WriteLine("6学分");
break;
default:
Console.WriteLine("输入的课程代号不正确");
break;
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
using System;
namespace proj3_8
{ class Program
{ static void Main(string[] args)
{ int i,j;
for (i = 1; i <= 9; i++)
{ for (j = 1; j <= i; j++)
Console.Write("{0}×{1}={2} ", i, j, i * j);
Console.WriteLine();
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13