变量和常量
应用程序的开发离不开变量和常量。变量本身被用来存储特定类型的数据,而常量则存储不变的数据。
1.1 变量的基本概念
可以根据需要随时改变变量中存储的数据值。变量具有名称、类型和值。变量类型确定它所代表的内存的大小和类型,变量值是指它所代表的内存块中的数据。使用变量之前必须先声明变量,就是指定变量的类型和名称。
1.2变量的声明和赋值
变量使用之前,必须进行声明并赋值。
1.2.1 声明变量
为什么要声明变量呢?就是告诉编译器这个变量属于哪一种数据类型,只有这样编译器才知道需要给它配置多少空间,以及它能存放什么样的数据。未经声明的变量本身是不合法的,因此没有办法咋程序中使用。在C#中声明一个变量是由一个类型和跟在后面的一个或者多个变量名组成的,多个变量之间用逗号分开,声明变量以分号结束。例如:
int d; //声明一个变量 string a,b,c; //同时声明3个变量
声明变量时,还可以初始化变量,就是在每个变量名后面给变量附初始值的指令。例如:
int a=900; //初始化整型变量a string b="你好",c="大家好",d="你们好呀"; //初始化字符串变量b、c和d
在声明变量时,要注意变量名的命名规则。变量名是区分大小写的,下面我列出了一些变量名的规则:
1.变量名只能由数字、字母和下滑线组成。
2.变量名的第一个符号只能是字母和下划线,不能是数字。
3.不能使用关键字作为变量名。
4.一旦在一个语句中定义了一个变量名,那么在变量的作用域内都不能在定 义同名的变量。
说明:
在C#中也可以使用中文命名变量名比如:“int 年龄=21”但是不建议这样命名。
1.2.2 变量的赋值
在C#中,使用赋值运算符“=”来给变量赋值,将等号右边的值赋给左边的变量。例如:
int a; //声明一个变量 a=20; //使用赋值运算符“=”给变量赋值
在变量赋值的时候,也可以是一个已经赋值的变量对其他变量进行赋值。
int a,b; // 声明两个变量 a=92; //给变量a赋值 b=a; //将变量a赋值给变量b
误区:对多个同类型的变量赋同一个值,可以同时对对多个变量进行初始化,
int a,b,c; a=b=c=0;
一般不采用这种方法。
1.2.3 变量的作用域
变量被定义出来只是暂存在内存中,等到程序执行到某个点后,该变量就会被释放掉,变量也是有周期的。在程序中根据变量的范围被分为成员变量和局部变量。
1.成员变量
在类中定义的变量叫成员变量,在整个类中都有效。成员变量又分为两种,静态变量和实例变量。例如:
class Jl{ int a=4; static int b=90; }
其中a为实例变量,b为静态变量。在变量面前加上关键字 static,这样的变量就是静态变量,此变量只能以“类名.静态变量”的方式在其他类中调用。
2.局部变量
在类方法体中定义的变量(方法内部定义,“{”与“}”之间的代码声明的变量)称为局部变量。局部变量只在方法体中有效。在类中的方法中声明的变量,包括方法的参数,都属于局部变量。当该方法的调用结束后,会释放方法中局部变量的内存空间,局部变量也会被销毁。例如:
static void Main(string []args){ //调用for循环输出数字 for(int i=0;i<=30;i++){ Console.WriteLine(i.ToString()); //输出0~30的数字 } }
程序运行结果为0~30的数字。
1.3数据类型
C#中的变量类型根据其定义可分为两种:一种是值类型,另一种是引用类型。两种类型的差异在于数据的存储方式,值类型的变量本身直接存储数据;引用类型是实际村储存数据的引用,程序是通过引用找到真正的数据。
1.3.1 值类型
值类型变量直接存储数据值,包括整数类型、浮点类型和布尔类型等。值类型因为在栈中分配,所有效率很高,目的是为了提高程序的性能。特征如下:
1.值类型都存储在栈中。
2.访问值类型的变量,一般都是直接访问其实例。
3.每个值类型都有自己的数据副本,所以对一个值类型变量的操作不会影响其他变量。
4.复制值类型变量,复制的是变量的值,不是地址。
5.值类型不能为null,必须是一个确定的值。
6.值类型是从System.ValueType类中继承而来的类型。
1.整数类型
就是没有小数部分的数值。sbyte short int long byte ushort uint ulong我们最常用的就是int 他们的范围和说明我就不在这里啰嗦了。
2.浮点类型
浮点类型主要就是用于处理含小数的数值数据,浮点类型主要包括float和double两种数值类型。如果不做任何设置,包含小数点的数值都会被认为是double类型,例如:90.23,没有特别指定的情况下,这个数值就是double类型,如果将数值以float类型来处理,就应该通过强制使用F或f将其指定为float类型。例如:
float sum=90.23f; //使用f强制指定为float类型 float sums=1.23F; //使用F强制指定为float类型
如果要将数值强制指定为double类型,则应该使用d或D进行设置,但是不加也是可以的,没有强制的规定。
double a=90d; //使用d强制指定为double类型 double b=20D; //使用D强制指定为double类型
如果需要使用float类型,必须在数值后边加上F或f,编译器会默认为double类型。
3.decimal类型
decimal类型表示128位数据类型,它是更高精度的浮点类型,精确度可以达到28位。如果希望一个小数被当作decimal类型使用,需要在后面加上M或m;
decimal money=1.45m;
4.布尔类型
布尔类型主要用来表示true和false值,一个布尔类型的变量,其值只能是true或false,不能将其他的值指定给布尔类型变量,它也不能转换为其他类型。布尔类型通常被用在流程控制中作为判断条件。例如,将90赋值给布尔类型变量a,
bool a=90;
这样子赋值显然是错误的,编译器会返回提示错误“常量值90无法转换为bool。”正确的使用方式如下:
bool a=true; bool b=false;
在定义全局变量时,如果没有特殊的要求,不用对其惊醒初始化,整数类型和浮点类型的默认值初始化都是0,布尔类型的初始化为false。
1.3.2 引用类型
引用类型是构建C#应用程序的主要对象类型数据。在应用程序执行的过程中,预先定义的对象类型以new创建对象实例,并且存储在堆中。引用类型具有如下特征。
1. 必须在托管堆中为引用类型变量分配内存。 2. 使用new关键字来创建引用类型变量。 3. 在托管堆中分配的每个对象都有与之相关联的附加成员,这些成员必须初始化。 4. 引用类型变量是由垃圾回收机制来管理的。 5. 多个引用类型变量可以引用同一个对象,对一个变量的操作会影响另一个变量所引用的同一对象。 6. 引用类型被赋值前的值都是null。
所有被称为“类”的都是引用类型,主要包括类、接口、数组和委托。下面我进行一个简单的演示:
class Program { class B //创建一个B类 { public int a = 0; //声明一个公共int类型的变量a } static void Main(string[] args) { int c1 = 0; //声明一个int类型的变量 int c2 = c1; //声明一个int类型的变量,并赋值 c2 = 927; //重新将变量赋值 B b = new B(); //使用new关键字创建引用对象 B b2 = b; //使等式右边赋值给左边 b2.a = 112; //设置变量的值 Console.WriteLine("a:{0},{1}",c1,c2); //输出变量 Console.WriteLine("Re:{0},{1}",b.a,b2.a); //输出应用类型对象的值 Console.ReadLine(); } }
运行的结果:
a:0,927 Re:112,112
1.3.3 值类型与引用类型的区别
从概念上来讲,值类型直接存储其值,而引用类型存储对其值的引用,在设计类型时就要决定类型的实例行为,如果在编写代码时不能理解引用类型和值类型的区别就会导致没有必要的异常。从内存空间上看,值类型在栈中操作,而引用类型在堆中分配存储单元。也就是说,值类型相当于现金,要用直接就可以使用,而引用类型相当于存折,要使用还要去银行取。下面我以如下的代码进行一个简单的区分:
class Program { static void Main(string[] args) { ReferA.Demo(); //调用ReferA类中的Demo()方法 Console.ReadLine(); } public class stam //定义一个类 { public string Name { get; set; } //定义引用类型 public int Age { get; set; } //定义值类型 } public static class ReferA //定义一个静态类 { public static void Demo() //定义一个静态方法 { stam s1 = new stam { Name = "xiaoming", Age = 23 }; //实例化 stam s2 = new stam { Name = "xiaohua", Age = 24 }; int age = s1.Age; //获取值类型Age的值 s1.Age = 22; //修改值类型的值 stam gu = s2; //获取s2中的值 s2.Name = "xiaoni"; //修改s2中引用的Name的值 Console.WriteLine("s1 age:{0}",s1.Age); Console.WriteLine("age value:{0}", age); Console.WriteLine("s2 name:{0}", s2.Name); Console.WriteLine("gu name:{0}", gu.Name); } } }
可以从结果上看出:s1中Age的值改变时完全不影响age,因为再改变s1中Age的值时已经先一步赋值给了age所以无法改变age的值。得出结论:
1.程序是从上往下运行的。
2.引用类型和值类型是不想关联的两种类型。
1.3.4 枚举类型
它是一种独特的值类型,用于声明一组具有相同性质的常量。关键字enum定义枚举类型。定义枚举类型时,如果不对其进行赋值,默认情况下,第一个枚举数的值为0,后面每个枚举数的值依次递增1。语法:
enum 枚举名 { list1 =value1, list2 =value2, list3 =value3, list4 =value4, list5 =value5, .... listN =valueN, }
大括号"{}"中的内容为枚举值列表,每个枚举值均对应一个枚举值名称,value1—valueN为整数类型,list1~listN则为枚举类型的标识名称。下面进行一个简单的演示:
class Program { enum MyDate //使用enum创建枚举 { Sun = 0, //设置枚举值名称Sun,枚举值为0 Mon = 1, //设置枚举值名称Mon,枚举值为1 Tue = 2, //设置枚举值名称Tue,枚举值为2 Wed = 3, //设置枚举值名称Wed,枚举值为3 Thu = 4, //设置枚举值名称Thu,枚举值为4 Fri = 5, //设置枚举值名称Fri,枚举值为5 Sat = 6 //设置枚举值名称Sat,枚举值为6 } static void Main(string[] args) { int k = (int)DateTime.Now.DayOfWeek; //获取代表星期几的返回值 switch (k) { //如果k等于枚举变量MyDate中的Sun的枚举值,则输出今天是星期日 case (int)MyDate.Sun: Console.WriteLine("今天是星期日"); break; //如果k等于枚举变量MyDate中的Mon的枚举值,则输出今天是星期一 case (int)MyDate.Mon: Console.WriteLine("今天是星期一"); break; //如果k等于枚举变量MyDate中的Tue的枚举值,则输出今天是星期二 case (int)MyDate.Tue: Console.WriteLine("今天是星期二"); break; //如果k等于枚举变量MyDate中的Wed的枚举值,则输出今天是星期三 case (int)MyDate.Wed: Console.WriteLine("今天是星期三"); break; //如果k等于枚举变量MyDate中的Thu的枚举值,则输出今天是星期四 case (int)MyDate.Thu: Console.WriteLine("今天是星期四"); break; //如果k等于枚举变量MyDate中的Fri的枚举值,则输出今天是星期五 case (int)MyDate.Fri: Console.WriteLine("今天是星期五"); break; //如果k等于枚举变量MyDate中的Sat的枚举值,则输出今天是星期六 case (int)MyDate.Sat: Console.WriteLine("今天是星期六"); break; } Console.ReadLine(); } }
程序首先通过enum关键字建立一个枚举,枚举值名称分别代表一周的7天,如果枚举值名称是Sun,说明其代表的是一周中的星期日,其枚举值为0,以此类推。然后,声明一个int类型的变量k,用于获取当前表示的日期是星期几。最后,调用swith语句,输出当天是星期几。
1.3.5 类型转换
类型转换就是将一种类型转换成另一种类型,转换可以是隐式转换,也可以是显示转换。
1.隐式转换
就是不需要声明就能进行的转换。例如:
int i=90; //声明一个整型变量i并初始化为 90;long j=i; //隐式转换成long类型;
数据的精度没有发生变化,所以可以进行隐式转换。
1.隐式转换
也可以称为强制转换,需要在代码中明确要转换的类型。如果把高精度的变量值赋给低精度的变量,就需要使用显示转换。由于显示转换包含所有隐式转换和显示转换,因此总是可以使用强制转换表达式从任何数据值类型转换成任何其他的数据值类型。
class Program { static void Main(string[] args) { double x = 19.01; //建立double类型变量x int y = (int)x; //显示转换成整型变量y Console.WriteLine(y); //输出整型变量y Console.ReadLine(); } }
也可以通过Convert关键字进行显示类型转换。
double x = 19.01; //建立double类型变量x int y = Convert.ToInt(x); //通过Convert关键字转换 Console.WriteLine(y); //输出整型变量y Console.ReadLine();
3.装箱和拆箱
将值类型转换为引用类型的过程叫装箱,将引用类型转换为值类型的过程就叫拆箱。
1)装箱。装箱允许将值类型转换成引用类型,下面进行一个简单的演示,
class Program { static void Main(string[] args) { int i = 204; //声明一个int类型变量i,并初始化为204 object obj = i; //声明一个object类型obj,其初始化值为i Console.WriteLine("1、i的值为{0},装箱之后的对象为{1}", i, obj); i = 927; //重新将I赋值为927 Console.WriteLine("2、i的值为{0},装箱之后的对象为{1}", i, obj); Console.ReadLine(); } }
程序运行结果:
1、i的值为204,装箱之后的对象为204 2、i的值为927,装箱之后的对象为204
从程序的运行结果可以看出,值类型变量的值复制到装箱中的对象中,装箱后改变值类型变量的值,不会影响装箱对象的值。
2)拆箱。拆箱允许将引用类型显示转换为值类型。下面进行演示,
class Program { static void Main(string[] args) { int i = 11; //声明一个int类型的变量i,并初始化为11 object obj = i; //执行装箱操作 Console.WriteLine("装箱操作:值为{0},装箱之后对象为{1}", i, obj); int j = (int)obj; //执行拆箱操作 Console.WriteLine("拆箱操作:装箱对象为{0},值为{1}", obj, j); Console.ReadLine(); } }
程序运行结果为:
装箱操作:值为11,装箱之后对象为11 拆箱操作:装箱对象为11,值为11
拆箱后得到的值类型数据的值与装箱对象相等。所以需要注意,在执行拆箱操作时要符合类型一致的原则,否则会出现异常。
1.4 常量
常量就是其值固定不变的量,而且常量的值在编译时就已经确定了。常量的类型只能为下列类型之一:sbyte\byte\short\ushort\int\uint\long\ulong\char\float\double\decimal\bool\string等。使用关键字const定义常量,并且在创建时必须设置它的初始值。下面我声明两个常量,一个正确和一个不正确的;
const double p=3.14; //正确的声明方法 const int M; //错误:定义常量时没有初始化
常量在整个程序中只能被赋值一次。以上就是我对变量和常量的归纳和总结,希望能帮到你们。