变量的基本概念
变量本身被用来存储特定类型的数据,可以根据需要随时改变变量中所存储的数据值
变量具有名称、类型和值
变量名是变量在程序源代码中的标识
变量类型确定它所代表的内存的大小和类型
变量值是指它所代表的内存块中的数据
在程序执行过程中,变量的值可以发生变化
变量使用之前需要先声明变量,即指定变量的类型和名称
变量的声明及赋值
变量在使用之前,必须进行声明并赋值
声明变量
变量的使用是程序设计中一个十分重要的环节
为什么要声明变量呢?简而言之,就是告诉编译器这个变量是属于哪一种数据类型,这样子编译器才知道需要分配多少内存空间给它,以及能存放什么样的数据
在程序运行过程中,空间内的值是变化的,这个内存空间就称为变量
声明变量就是指定变量的名称和类型,变量的声明非常重要,未经声明的变量本身并不合法,也因此没有办法在程序中使用
在C#中,声明一个变量是由一个类型和跟在后面的一个或多个变量名组成的,多个变量之间用逗号分开,声明变量以分号结束
类型 变量名_1, 变量名_2, 变量名_3;
声明变量时,还可以初始化变量,即在每个变量名后面加上给变量赋初值的指令
类型 变量名_1 = 变量值_1, 变量名_2 = 变量值_2, 变量名_3 = 变量值_3;
在声明变量时,要注意变量名的命名规则
C#的变量名是一种标识符,应该符合标识符的命名规范
变量名是区分大小写的
下面列出变量的命名规则:
- 变量名只能由数字、字母和下划线组成
- 变量名的第一个符号只能是字母和下划线,不能是数字
- 不能使用关键字作为变量名
- 一旦在一个语句块中定义了一个变量名,那么在变量的作用域内都不能再定义同名的变量
在C#中允许使用汉字或其他语言文字作为变量名,在程序运行中是不会出现错误的,但是尽量是避免使用文字作为变量名
变量赋值
在C#中,使用赋值运算符=
来给变量赋值,将赋值运算符右边的值赋给左边的变量
在对多个同类型的变量赋同一个值时,为了节省代码行数,可以同时对多个变量进行初始化
变量的作用域
由于变量被定义出来后只是暂存在内存中,等到程序执行到某一个节点后,该变量会被释放掉,也就是说变量有它的生命周期
变量的作用域是指程序源代码能够访问该变量的区域,若超出该区域,则在编译时会出现错误
在程序中,一般会根据变量的“有效范围”将变量分为“成员变量”和“局部变量”
成员变量
在类体中定义的变量称为成员变量
成员变量在整个类中都有效
类的成员变量在整个类中都有效
类的成员变量又可分为两种:静态变量和实例变量
如果在成员变量的类型前面加上关键字static
这样的成员变量称为静态变量
静态变量的有效范围可以跨类,甚至可达到整个应用程序之内
对于静态变量,除了能在定义它的类内存取,还能直接以“类名.静态变量”的方式在其他类内使用
局部变量
在类的方法体中定义的变量称为局部变量
局部变量只在当前代码块中有效
在类的方法中声明的变量,包括方法的参数,都属于局部变量
局部变量只有在当前定义的方法内有效,不能用于类的其他方法中
局部变量的生命周期取决于方法,当方法被调用时,C#编译器为方法中的局部变量分配内存空间,当该方法调用结束后,则会释放方法中局部变量占用的内存空间,局部变量也将会销毁
数据类型
C#中的变量类型根据其定义可以分为两种:一种是值类型;另外一种是引用类型
这两种类型的差异在于数据的存储方式
值类型的变量本身直接存储数据
引用类型则存储实际数据的引用,程序通过此引用找到真正的数据
值类型
值类型变量直接存储其数据值,主要包含整数类型、浮点类型以及布尔类型等
值类型变量在栈中进行分配,因此效率很高,使用值类型主要目的是为了提高性能
值类型具有以下特性:
- 值类型变量都存储在栈中
- 访问值类型变量时,一般都是直接访问其实例
- 每个值类型变量都有自己的数据副本,因此对一个值类型变量的操作不会影响其他变量
- 复制值类型变量时,复制的是变量的值,而不是变量的地址
- 值类型变量不能为null,必须具有一个确定的值
值类型是从System.ValueType
类继承而来的类型
整数类型
整数类型用来存储整数数值,即没有小数部分的数值
可以是正数,可以是负数,还可以是0
整型数据在C#中有3种表示形式:十进制、八进制以及十六进制
- 十进制:123,456
- 八进制:0123(转换为十进制为83)
- 十六进制:0x25(转换为十进制为37),0Xb01e(转换为十进制为45086)
不能以0作为十进制的开头(0除外)
八进制必须以0开头
十六进制必须以0X或0x开头
类型 | 说明(8位等于1个字节) | 范围 |
sbyte | 8位有符号整数 | -128~127 |
short | 16位有符号整数 | -32768~32767 |
int | 32位有符号整数 | -2147483648~2147483647 |
long | 64位有符号整数 | -9223372036854775808~9223372036854775807 |
byte | 8位无符号整数 | 0~255 |
ushort | 16位无符号整数 | 0~65535 |
uint | 32位无符号整数 | 0~4294967295 |
ulong | 64位无符号整数 | 0~18446744073709551615 |
byte类型以及short类型是范围比较小的整数
如果正整数的范围没有超过65535,声明为ushort
类型即可,更小的数值直接以byte
类型处理
浮点类型
浮点类型变量主要用于处理含有小数的数值数据,浮点类型主要包含float
和double
两种数值类型
类型 | 说明 | 范围 |
float | 精确到7位数 | ±1.5 * 10-45 ~ ±3.4 * 1038 |
double | 精确到15~16位数 | ±5.0 * 10-324 ~ ±1.7 * 10308 |
如果不做任何设置,包含小数点的数值都被认为是double
类型
如果要将小数数值以float
类型来处理,就应该强制使用f
或者F
将其指定为float
类型
如果要将数值强制指定为double
类型,则应该使用d
或者D
进行设置,但加不加d
或者D
没有硬性规定,可以加也可以不加
如果需要使用float
类型变量时,必须在数值的后面跟随f
或者F
,否则编译器会直接将其作为double
类型处理,也可以在double
类型的值前面加上(float)
,对其进行强制转换
布尔类型
布尔类型主要用来表示true
和false
值,一个布尔类型的变量,其值只能是true
或者false
,不能将其他的值指定给布尔类型变量,布尔类型变量不能与其他类型之间进行转换
布尔类型通常被用在流程控制中作为判断条件
在定义全局变量时,如果没有特定的要求不用对其进行初始化,整数类型和浮点类型的默认初始化为0
,布尔类型的初始化为false
引用类型
引用类型是构建C#应用程序的主要对象类型数据
在应用程序执行过程中,预先定义的对象类型以new
创建对象实例,并且存储在堆中
堆是一种由系统弹性配置的内存空间,没有特定大小及存活时间,因此可以被弹性的运用于对象的访问
引用类型具有如下特征:
- 必须在托管堆中为引用类型变量分配内存
- 使用
new
关键字来创建引用类型变量 - 在托管堆中分配的每个对象都有与之相关联的附件成员,这些成员必须初始化
- 引用类型变量可以引用同一个对象,在这种情形下,对一个变量的操作会影响另一个变量所引用的同一个对象
- 引用类型被赋值前的值都是
null
所有被称作“类”的都是引用类型,主要包括类、接口、数组和委托
值类型和引用类型的区别
值类型直接存储其值,而引用类型储存对其值的引用
值类型是在栈中操作,而引用类型是在堆中分配存储单元,可以根据程序的运行情况动态的分配内存大小
栈在编译时就分配好内存空间,在代码中又栈的明确定义,而堆是程序运行中动态分配的内存空间,可以根据程序的运行情况动态的分配内存的大小
值类型总是在内存中占用一个预定义的字节数
引用类型的变量则在堆中分配一个内存空间,这个内存空间包含的是对另一个内存位置的引用,这个位置是托管堆中的一个地址,即存放此变量实际值的地方
C#的所有值类型均隐式派生自System.ValueType
,而System.ValueType
直接派生于System.Object
即System.ValueType
本身是一个类类型,而不是值类型,其关键在于ValueType
重写了Equals()
方法,从而对值类型按照实例的值来比较,而不是引用地址来比较
枚举类型
枚举类型是一种独特的值类型,用于声明一组具有相同性质的常量
使用枚举类型可以增加程序的可读性和可维护性,同时,枚举类型可以避免类型错误
在定义枚举类型时,如果不对其进行赋值,默认情况下,第一个枚举变量的值为0
,后面每个枚举变量的值依次递增1
在C#中使用关键字enum
类声明枚举
enum 枚举名
{
list1 = value1,
list2 = value2,
list3 = value3,
...
listN = valueN,
}
类型转换
类型转换就是将一种类型转换为另一种类型,转换可以是隐式转换,也可以是显示转换
隐式转换
所谓隐式转换就是不需要声明就能进行的转换
进行隐式转换时,编辑器不需要进行检查就能自动进行转换
源类型 | 目标类型 |
sbyte | short、int、long、float、double、decimal |
byte | short、ushort、int、uint、long、ulong、float、double 或 decimal |
short | int、long、float、double 或 decimal |
ushort | int、uint、long、ulong、float、double 或 decimal |
int | long、float、double 或 decimal |
uint | long、ulong、float、double 或 decimal |
char | ushort、int、uint、long、ulong、float、double 或 decimal |
float | double |
ulong | float、double 或 decimal |
long | float、double 或 decimal |
从int
、uint
、long
或ulong
到float
,以及从long
或ulong
到double
的转换可能导致精度损失,但是不会影响其数量级
其他的隐式转换不会丢失任何信息
当一种类型的值转换为大小相同或更大的另一类型时,则发生扩大转换
当一种类型的值转换为较小的一种类型时,则发生收缩转换
显示转换
显示转换也可以成为强制转换,需要在代码中明确的声明要转换的类型
如果要把高精度的变量的值赋给较低精度的变量,就需要使用显示转换
源类型 | 目标类型 |
sbyte | byte、ushort、uint、ulong 或 char |
byte | sbyte 和 char |
short | sbyte、byte、ushort、uint、ulong 或 char |
ushort | sbyte、byte、short 或 char |
int | sbyte、byte、short、ushort、uint、ulong 或 char |
uint | sbyte、byte、short、ushort、int 或 char |
char | sbyte、byte 或 short |
float | sbyte、byte、short、ushort、int、uint、long、ulong、char 或 decimal |
ulong | sbyte、byte、short、ushort、int、uint、long 或 char |
long | sbyte、byte、short、ushort、int、uint、ulong 或 char |
double | sbyte、byte、short、ushort、int、uint、ulong、long、float、char 或 decimal |
decimal | sbyte、byte、short、ushort、int、uint、ulong、long、float、char 或 double |
由于显示转换包括所有的隐式转换和显示转换,因此总是可以使用强制转换表达式从任何数值类型转换为任何其他的数值类型
也可以通过Convert
关键字进行显示类型转换
装箱和拆箱
将值类型转换为引用类型的过程叫做装箱,装箱允许将值类型隐式转换成引用类型
将引用类型转换为值类型的过程叫做拆箱,拆箱允许将引用类型显示转换为值类型
装箱是将一个值类型转换为一个对象类型(object)
拆箱则是将一个对象类型显示转换为一个值类型
对于装箱而言,它是将被装箱的值类型复制一个副本来转换;对于拆箱而言,需要注意类型的兼容性
常量
常量就是其值固定不变的量,而常量的值在编译时,就已经确定了
常量的类型只能为下列类型之一:sbyte
byte
short
ushort
int
uint
long
ulong
char
float
double
decimal
bool
string
等
C#使用关键字const
来定义常量,并且在创建常量时必须设置它的初始值
常量一旦设置就不允许修改
与变量不同,常量在整个程序中只能被赋值一次
来源链接:https://www.cnblogs.com/EricsT/p/18870378
没有回复内容