首页 > 代码库 > 变量和常量
变量和常量
变量和常量的知识是一门编程语言的基础知识,而每一门编程语言都有自己对变量
和常量的命名和使用方式,可以将C#中的变量分为静态变量、实例变量、传值形参、引
用形参、输出参数、数组参数和局部变量共七种。
(一)变量
程序要对数据进行读、写、运算等操作。当需要保存特定的值或者计算结果时,就需
要用到变量,在用户看来,变量是用来描述一条信息的名称,在变量中可以存储各种类型
的信息,比如:姓名、地址等。
在计算机中,变量代表存储地址,变量的类型决定了存储在变量中的数值的类型。
C#是一种安全类型语言,它的编译器存储在变量中的数值具有适当的数据类型。同时变量的
值可以通过操作运算符进行运算并改变。
在C#中,使用变量的一个重要原则是:变量必须先定义后使用。
在C#语言中,定义了七种变量类别:静态变量(static variables)、实例变量(instance variables)、数组元素(array elements)、
值参数(value parameters)、引用参数(reference parameters)、输出参数(output parameters)以及局部变量(ocal variable)
示例:
class A { public static int x; int y; void F(int[] arr,int a,ref int b,out int c) { int i=1; c=a+b++; } }
在上面的例子中,
x是静态变量,y是实例变量,arr[0]是数组元素,a是值参数,b是引用参数,c是输出参数,i是局部变量。
静态变量:带有static修饰符声明的变量称为静态变量。一旦静态变量所属的类被装载,直到包含该类的程序运行结束时他一直存在。
静态变量的初始值就是改变量类型的默认值,为了便于定义赋值检查,最好是在定义静态变量时赋值。如:static int x=10;
实例变量:不带有static修饰符声明的变量称为实例变量。示例变量随着它所属类的实例的存在而存在。
同样为了便于赋值检查,最好是在定义变量时赋值,如:int x=20;
数组元素:数组元素也是变量的一种,改变量随该数组实例的存在而存在。同样为类便于赋值检查,数组元素最好是在初始时赋值。
局部变量:局部变量是指在一个独立的程序块,一个for语句,一个switch语句或者using语句中声明的变量,它只在该范围中有效(也就是大括弧中,因为作用域)。与其他便量类型不同的是,局部变量不会自动初始化,所以也就没有默认值。
(1)静态变量和实例变量主要是针对类或结构内的数据成员(又叫域)而言的。静态变量在它寄存的类或结构类型被装载后得到存储空间,如果没有对它进行初始化赋值,静态变量的初始值将是它的类型所持有的缺省值。对静态变量的访问只能通过类型名,而不能通过对象名访问。
(2)实例变量在它的类实例(对象)被创建后获得存储空间,如果没有经过初始化赋值,它的初始值与静态变量的定义相同(其初始值将是它的类型所持有的缺省值)。对实例变量的访问只能通过对象名访问。
(3)传值形参、引用形参、输出参数、数组参数主要针对方法的参数类型而言的。简单地讲传值形参是对变量的值的副本的一种传递,方法内对变量的改变在方法体外不起作用。
(4)引用形参是对变量的地址的一种传递,方法内对该变量的任何改变都将在方法体外保留。无论在定义还是在使用时,都必须采用ref修饰符加以说明。
传值参数传递的是调用参数的一份拷贝,而传地址参数(引用)传递的是调用参数的内存地址,该参数在方法内外指向的是同一个存储位置。
using System; namespace RefTest { class RefTest { static void Swap(ref int x, ref int y) { int temp = x; x = y; y = temp; //在方法内部对调x,y,其实是对调外边的i,j } } static void Main() { int i = 1, j = 2; Swap(ref i, ref j); Console.WriteLine("i = {0}, j = {1}", i, j); Console.ReadLine(); } //显示 i=2, j=1 }
(5)输出形参数是C#专门为有多个返回值的方法而量身定做的,它类似于引用变量,但可以在调用方法体之前不进行初始化但在被调用的方法返回前必须对该变量进行赋值,而其他的参数在进入方法体内C#都要求明确的初始化。无论在定义还是在使用时,都必须采用out修饰符。
在传值和传址情况下,C#强制要求参数在传入之前由用户明确初始化,否则编译器报错!但如果有一个并不依赖于参数初值的函数,只是需要函数返回时得到它的值时该怎么办呢?往往在我们的函数返回值不至一个时特别需要这种技巧!
但需要记住输出参数与通常的函数返回值有一定的区别:函数返回值往往存在堆栈里,在返回时弹出;而输出参数需要用户预先制定存储位置,也就是用户需要提前声明变量--当然也可以初始化。
using System; //对给定的文件路径分离出其文件名与目录名 namespace OutTest { class OutTest { static void SplitPath(string path, out string dir, out string name) { int i = path.Length; while (i > 0) { char ch = path[i - 1]; if (ch == ‘\\‘ || ch == ‘/‘ || ch == ‘:‘) break; i--; } dir = path.Substring(0, i); //i为字符长度(个数) name = path.Substring(i); //i为字符位置(从第几个字符开始) } public static void Main() { string dir, name; SplitPath("d:\\myDemo\\test.txt", out dir, out name); Console.WriteLine(dir); //调用后将输出形参的值 Console.WriteLine(name); Console.ReadLine(); } } }
在函数体内所有输出参数必须被赋值,否则编译器报错!除了充当返回值这一特殊的功能外,out修饰符与ref修饰符有很相似的地方:传址。
(6)数组形参是为传递大量的数组元素而专门设计的,它从本质上讲是一种引用型变量的传值参数。数组参数需要修饰符params。它可以是数组如:a,也可以是能够隐式转化为数组的参数如:10,20,30,40。params 关键字可以指定在实参数目可变处使用方法参数。在方法声明中的params 关键字之后不允许任何其它参数声明,并且在方法声明中只允许一个params 关键字。
using System; namespace ParamsTest { class ParamsTest { static void F(params int[] args) {
Console.WriteLine("Array contains {0} elements:", args.Length); foreach (int i in args) Console.Write(" {0}", i); Console.WriteLine(); } static void Main() {
int[] a = {1, 2, 3,4,5,6}; //利用初始化的方式创建出一个数组 F(a); F(10, 20, 30, 40,50,60,70,80); //利用一组参数隐含地创建出一个数组 F(); Console.ReadLine(); } } }
(7)局部变量严格的讲是在C#中的块语句、for语句、switch语句或函数内声明的变量,它的生命周期严格地被限制在这些语句块内部。局部变量不会被自动初始化,在使用前必须先给它赋值。
(二)常量
所谓常量,就是其值固定不变的量。从数据类型角度看,常量可以是任何值类型或引用类型。
例如:public const string strConst=”This is a const!”;
注意:常量的声明必须包含关键字const和数据类型、常量名称、常量值等要素。