C#快速入门(二):数据类型、变量与常量、数据类型转换

一、数据类型

C# 语言的数据类型分为值类型和引用类型。值类型包括整型、浮点型、字符型、布尔型、枚举型等;引用类型包括类、接口、数组、委托、字符串等。(引用类型后面会单独讲,现在只讲个大概)

1.1 值类型

C#值类型变量可以直接分配给一个值。它们是从类System.ValueType中派生的。

上图看起来有点多,但是分类开来就很好记了:
1.布尔型: bool
2.字符型: char
3.浮点型:根据精度分为
float:通常称为单精度
double:通常称为双精度
decimal:一般用于银行系统等精确数值处
4.整数型:整数型又分为有无符号两大类
无符号类:byte, ushort,uint, ulong
有符号类:sbyte, short, int, long
有无符号的区别就是无符号不能为负数。而有无符号中又根据位数分为四种不同类型,它们的默认值都是0。

值类型的特点:

  1. 不能从值类型派生新类型;
  2. 值类型不能包含 null 值;
  3. 每个值类型都具有一个初始化该类型的默认值的隐式默认构造函数。

1.2 引用类型

引用类型不包含存储在变量中的实际数据,但它们包含对变量的引用。

与值类型对比而言,它们指的是一个内存地址,使用多个变量是,引用类型可以指向一个内存地址。如果内存地址的数据由一个变量改变的,其他变量会自动反映这种值的变化。

C#内置的引用类型:object、dynamic 和 string。

Object对象类型:
Object类型是C#中所有数据类型的终极基类。所以Object类型可以被分配任何其他类型(包括值类型,引用类型和自定义类型)的 值。但是分配之前需要先进行类型转换。如:Object obj = 10; Object是 System.Object类的别名。
Dynamic动态类型:
动态类型可以存储任何类型的值在动态数组类型变量汇总。这些类型检是在运行时发生的。语法:dynamicd=10;
String字符串类型:
字符串类型是 System.String类的别名。它是对象类型(Object)的派生类。语法: string str = "Cznenya";

1.3 两者的区别

不需要太了解,后续开发中自然会理解的。

1.速度上的区别

值类型存取速度快,引用类型存取速度慢。

2.用途上的区别

值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针或引用。

3.来源上的区别

值类型继承自System.ValueType,引用类型继承自System.Object

4.位置上的区别

值类型的数据存储在内存的栈中,引用类型的数据存储在内存的堆中,而内存单元中只存放堆中对象的地址。

5.类型上的区别

值类型的变量直接存放实际的数据,而引用类型的变量存放的则是数据的地址,即对象的引用。

6.保存位置上的区别

值类型变量直接把变量的值保存在堆栈中,引用类型的变量把实际数据的地址保存在堆栈中,而实际数据则保存在堆中。

1.4 值类型案例

// ---------------- 布尔型 ----------------

bool bo = true; // 默认值:False
Console.WriteLine("布尔值:" + bo);

// ---------------- 字符型 ----------------

char ch = '1'; // 默认值:'\0'
Console.WriteLine("16 位 Unicode 字符:" + ch);

// ---------------- 浮点型 ----------------

float fl = 1.0f; // 默认值:0.0F
Console.WriteLine("32 位单精度浮点型:" + fl);

double dou = 1.0d; // 默认值: 0.0D
Console.WriteLine("64 位双精度浮点型:" + dou);

decimal de = 123; // 默认值:0.0M
Console.WriteLine("128 位精确的十进制值:" + de);

// ---------------- 整数型 ----------------

byte by = 1;   // 默认值:0
Console.WriteLine("8 位无符号整数:" + by);
sbyte sb = 1;  // 默认值:0
Console.WriteLine("8 位有符号整数类型:" + sb);

uint ui = 1;   // 默认值:0
Console.WriteLine("32 位无符号整数类型:" + ui);
int i = 1;     // 默认值:0
Console.WriteLine("32 位有符号整数类型:" + i);

ushort us = 1; // 默认值:0
Console.WriteLine("16 位无符号整数类型:" + us);
short sh = 1;  // 默认值:0
Console.WriteLine("16 位有符号整数类型:" + sh);

ulong ul = 1;  // 默认值:0
Console.WriteLine("64 位无符号整数类型:" + ul);
long lo = 1;  // 默认值:0
Console.WriteLine("64 位有符号整数类型:" + lo);

二、变量与常量

2.1 变量

一个变量就是存储区(内存)中的一个存储单元

变量可以理解为存放指定数据类型数据的容器。

变量和常量是相对的:变量是指所存放的值是允许改变的,而常量表示存入的值不允许改变。

2.1.1 变量的声明

1.声明一个变量: 根据类型分配空间

(1)根据指定的类型定义一个变量的名称

(2)语法:

int money = 5;  //变量类型  变量名 = 数值;

int money1; //变量类型  变量名;
money1 = 10;    //变量名  =  数值;

int money2, money3;//变量类型 变量名1,变量名2,...,变量名n;
money2 = 20;
money3 = 30;

Console.WriteLine(money);
Console.WriteLine(money1);
Console.WriteLine(money2);
Console.WriteLine(money3);

2.初始化变量: 将数据存入内存空间

不赋值就会报错

(1)定义时赋值:int money = 5;

(2)使用时赋值:int money1; money1 = 10;

3.使用变量: 取出数据的使用

2.1.2 变量命名规则

变量名的命名规则遵循C#中标识符的命名规则。
规则如下:

  • 变量首字符必须是字母,下划线或者“@"字符;
  • 其后可以是数字,字母或下划线;
  • 变量名不可与预留关键字重名。

比如:变量名不能是int,但是可以是_int或者@int。

2.2 常量

常量是固定值,程序执行期间不会改变。常量可以是任何基本数据类型。

常量可以被当作常规的变量,只是它们的值在定义后不能被修改。

2.2.1 const

在C#中,经常通过const关键字和数据类型来声明常量。

声明语法如下:

const 常量类型 常量名 = 常量值;

代码示例如下:

const double PI = 3.14;

被const关键字修饰的常量又被称为静态常量(编辑时常量):声明的常量必须在定义时赋值,经过编译后值被固定,任何在const符号常量定义之外的常量值修改都将引起编译错误;

2.2.2 readonly

被readonly修饰的常量又被成为 动态常量(运行时常量)

在运行时确定值,只能在声明时或构造函数中初始化,只能在类中定义。

声明语法如下:

readonly 常量类型 常量名 = 常量值;

代码示例如下:

using System;

namespace Program
{
    class MainClass
    {
        readonly int a = 1;  // 声明并初始化
        readonly int b;
        MainClass() // 构造函数中初始化
        {
            a = 3;//可以在构造函数中更改
            b = 2;
        }
        public static void Main(string[] args) {
            MainClass mc = new MainClass();
            Console.WriteLine(mc.a);
            Console.WriteLine(mc.b);
        }
    }
}

之后更改就会报错:

2.2.3 两者区别

1.初始化
const:在声明时必须初始化值

readonly:可以不初始化值,且可以延迟到构造函数
2.解析:
const:在编译期间会被解析,并将常量的值替换成初始化的值

readonly:延迟到运行的时候
3.效率:
const:注重的是效率

readonly:注重灵活
4.内存:
const:没有内存消耗

readonly:因为需要保存常量,所以有内存消耗
初学者只需要了解常量的概念,知道 const 和 readonly 的区别即可。在后续学习的过程中会慢慢加深理解,实际用过几次后就能完全掌握了。

三、数据类型转换

C# 的类型转换有显式转换 和 隐式转换 两种方式。

  • 显式转换:有可能引发异常、精确度丢失及其他问题的转换方式。需要使用手段进行转换操作。
  • 隐式转换:不会改变原有数据精确度、引发异常,不会发生任何问题的转换方式。由系统自动转换。

不同类型的数据进行操作(加减乘除赋值等等),是需要进行 类型转换 后,才能继续操作。所以需要“类型转换”。

3.1 隐式转换

隐式转换容易理解,当多种数据类型进行某种操作时,不需要干预,系统自动完成类型转换

int i = 66666;
long b = i;    //转为 long 类型后为 b 赋值

通常情况下,多种值类型进行计算时,系统会自动进行隐式转换,并且是向上转换,既转为范围更大的数据类型,并且不会发生精确度变化、数字大小变化等等。

3.2 显示转换

当你需要把一个 long 类型的数据转成 int 时,又或者让 string 与 int 互转,当数据小数点太多时,这时候就必须使用显式转型。

char 是整型!

虽然char存储的是字符而不是数字,但它的确是整型,可以看看上一章,可以发现Char 对象的值是 16 位数字 (序号值)。

也就是说,char是可以参与算术运算的。但并不是直接参与,而是char的基础值。c# 中的char值是基于Unicode的。通过Unicode,任意字符都可以解释成数字。

3.2.1 使用([type])转型操作符

此方法适用与值类型转换( string属于引用类型)

在需要转换的变量前加上( [类型] )即可

请仔细观察下面两图的差异

第二张图中的代码中,第二行,为 int b = (int)a;

在需要转换的变量前使用 ([type]) 这种格式进行转换,如(int)、(float)、(long)

注意:

此种方法只能对值类型数据进行转换。

不应将范围大的类型 往 小 转换 或 将浮点型转为整形,不能将超范围的往小了转。

例如 float 转为 int,精确度会被自动丢失

将大于其类型范围的数给它时,会发生内存溢出。

char 可以直接跟 int 或 long 使用。

int a ='1' + '3';  //小转大
char b = (char)a;  //大转小
int c = 'a' + '5';  //char可以直接转为 int

注意:int 直接转为char,会报错

3.2.2 [Type].Parse()

([type]) 方法是无法在值类型、引用类型( string 类型)间转换的。

但每种数据类型都提供一个Parse()方法,它允许把字符串转成对应的 数值类型。

string str = "666";
long i = int.Parse(str);
Console.WriteLine($"{i},{i.GetType()}");

Parse() 是专为 string 类型转成 值类型 提供功能的!

Parse() 是为符合数字格式的 string 类型进行转换!

3.2.3 [Type].TryParse()

TryParse()与.Parse()相似,但是使用形式不太一样

[类型].TryParse(要更改的字符串,out 存储到哪个变量); 

最重要的不同点在于,.TryParse() 在转换失败时,不会引发异常,而是返回 flase

string str = "666";
int i;
bool b = int.TryParse(str, out i);    //接收转换结果

Console.WriteLine(b);
Console.WriteLine(i);

3.2.4 System.Convert

System.Convert.ToSingle();

System.Convert.ToInt32();

System.Convert.ToDouble();

不知道数据类型的方法,可以使用 变量.GetType()来确认。

常见 类型列表: char、sbyte、short、int、long、uint、ulong、float、double、decimal、string、bool ... ...

但是,同样需要格式支持!

string str = "666";
int a= System.Convert.ToInt32(str);        //正确
 
string str = "666.66";
int a= System.Convert.ToInt32(str);        //报错
 
int a = 66666;
bool c = System.Convert.ToBoolean(a);        //正确
 
string str = "666.66";
bool c = System.Convert.ToBoolean(str);        //报错

System.Convert 在转换是也需要注意 格式 才能转换成功。

同样,此方式也会发生精确度、数字大小改变

3.2.5 System.Convert

每种数据类型都提供了转为字符串类型的方法 ToString()

无论是值类型还是DateTime 等各种引用类型。

ToString()使用方法最为简单

        int a = 666;
        string aa = a.ToString();
        Console.WriteLine($"{aa}");
 
        float b = 666.666F;
        string bb = b.ToString();
        Console.WriteLine($"{bb}");
 
        DateTime c = DateTime.Now;
        string cc = c.ToString();
        Console.WriteLine($"{cc}");
 
        FileInfo d = new FileInfo("E:\\test.txt");
        string dd = d.ToString();
        Console.WriteLine($"{dd}");
 
        string ee;
        try
        {
            int x = 1;
            int y = 0;
            int e = x / y;
        }
        catch (Exception ex)
        {
            ee = ex.ToString();
            Console.WriteLine($"{ee}");
        }

无论什么类型,只需在后面加上 ToString() , 都能 输出 string 类型的内容。(不是转为 string 类型!)

当然,ToString() 是一个方法,并提供了 一下传入参数,每种类型都有几个重载的 TOString() 方法,例如DateTime的

public string ToString(string format, IFormatProvider provider);
public string ToString(string format);
public string ToString(IFormatProvider provider);
public override string ToString();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值