1,变量的分类:
C#是一种类型安全的语言。每一个变量都要求定义为一个特定的类型,并且要求存储在变量中的值只能是这种类型的值。
值类型
在C#中你可以通过声明枚举类型或是结构类型来定义你自己的值类型。C#以同样的方式处理用户自定义的类型和C#预定义的值类型,不过C#编译器可能更优于处理后者。下面的表列出了C#中预定义的值类型的一些信息。因为在C#中所有的基本值类型都是从object类型(最终基类)发展而来,所以下表中还显示了与这些预定义类型相对应的.Net框架中的System类型。
C# 类型 |
.Net 框架类型 |
有无符号 |
占据位数 |
取值范围 |
sbyte |
System.Sbyte |
是 |
1 |
-128 到 127 |
short |
System.Int16 |
是 |
2 |
-32768 到32767 |
int |
System.Int32 |
是 |
4 |
-2147483648 到 2147483647 |
long |
System.Int64 |
是 |
8 |
-9223372036854775808 到 9223372036854775807 |
byte |
System.Byte |
否 |
1 |
0 到 255 |
ushort |
System.Uint16 |
否 |
2 |
0 到 65535 |
uint |
System.UInt32 |
否 |
4 |
0 到 4294967295 |
ulong |
System.Uint64 |
否 |
8 |
0 到18446744073709551615 |
float |
System.Single |
是 |
4 |
可能值从 ±1.5 x 10-45 到 ±3.4 x 1038,小数点后7位有效数字 |
double |
System.Double |
是 |
8 |
可能值从 ±5.0 x 10-324 to ±1.7 x 10308 小数点后15到16位有效数字 |
decimal |
System.Decimal |
是 |
12 |
可能值从 ±1.0 x 10-28 到±7.9 x 1028小数点后28到29位有效数字 |
char |
System.Char |
N/A |
2 |
任何16位Unicode字符 |
bool |
System.Boolean |
N/A |
1 / 2 |
true 或者false |
在下面的代码中,两个变量都声明为整形,并得到赋值:
int x = 10;
int y = x;
y = 20; // 这条语句运行后x的值为10,y的值为20;
引用类型
C#预定义的引用类型包括object和string类型。正如我们在上面提到的,object类型是所有其他类型的最终基类。用户定义的引用类型可以是接口类型、类类型和委托类型(第12课会有具体介绍)。
引用类型事实上保存一个指向它引用的对象的内存地址。下面的代码段中有两个变量引用了同一个对象(本例中,假设这个对象有一个数据成员’myValue’):
object x = new object();
x.myValue = 10;
object y = x;
y.myValue = 20; // 这条语句执行后,x.myValue和y.myValue的值都为20。
上面的这段代码演示了引用类型的一个特点:改变某一个引用指向的对象的属性同时也会影响到所有其他指向这个对象的引用。不过,strings类型虽然也是引用类型,但它的工作方式更象值类型。当一个字符串被指定了另一个字符串的值时,例如:
string s1 = "hello";
string s2 = s1;
s2和s1都引用了同一个字符串类型,但是当s1的值发生改变时,例如s1=”goodbye”;s2的值仍然是”hello”。之所以会这样,是因为当改变s1的值是,新创建了一个string对象,s1引用这个新的string对象;s2仍然引用原来string对象。产生这种行为的原因是string对象是恒定的,也就是说,一旦一个string对象被创建,它的值就不能再修改,所以当改变一个字符串变量的值的时候,仅仅是新创建了一个包含修改内容的新的string对象。
2,变量的作用域
按我的理解,变量的作用域简单点说就是变量能使用的范围。它可分为局部变量,和全局变量。
局部变量:
局部变量可理解为在同一个大括号内的变量,如:
static void Main(string [] args)
{
int mynumber=0;
Console.Write(Convert.ToString(mynumber));
}
其中mynumber就为局部变量,当在Main方法外使用时就会出现错误。
局部变量在使用之前必须初始化。
全局变量:
static int mynumber;
static void Main(string [] args)
{
Console.Write(Convert.ToString(mynumber));
}
其中mynumber就为全局变量,可在包含该变量大括号内的所有区域使用,可不初始化,系统默认赋值,上面例子中的mynumber值为0;
当有全局变量与局部变量重名的时候,全局变量会被屏蔽。如下面所示。
static int mynumber=0;
static void Main(string [] args)
{
int mynumber=5;
Console.Write(Convert.ToString(mynumber));//程序将输出数据为5
Console.Write(Convert.ToString(Program.mynumber));//程序将输出数据为0
}
分析下面代码可以明白变量的作用域问题。
代码一:
string text;
for (int i = 0; i < 10; i++)
{
text = "Line" + Convert.ToString(i);
Console.WriteLine("{0}",text);
}
Console.WriteLine("The Last text:{0}",text);
Console.ReadKey();
其中代码一将会报使用了未赋值的局部变量,对于刚入门的人来说很容易混淆,明明在for循环中赋值了,为什么说未赋值呢?
原因在于,声明一个简单类型的变量,并不会引起其他变化,只有赋值后,才会占用一块存储空间。如果赋值在循环或其他独立块中发生,则该值实际被定义为局部值。
也就是说,该变量本身没有被局部化,但是该值已经被局部化了。需在声明该变量时就对其赋值。
string text=“”;
for (int i = 0; i < 10; i++)
{
text = "Line" + Convert.ToString(i);
Console.WriteLine("{0}",text);
}
Console.WriteLine("The Last text:{0}",text);
Console.ReadKey();