3.变量与常量

变量与常量

  • 1 变量的基本概念
  • 2 变量的声明及赋值
  • 3 变量的作用域
    • 3.1 成员变量
    • 3.2 局部变量
  • 4 数据类型
    • 4.1 值类型
      • 4.1.1 整数类型
      • 4.1.2 浮点类型
      • 4.1.3 浮点类型
    • 4.2 引用类型
  • 5 值类型与引用类型的区别
  • 6 枚举类型
  • 7 类型转换
    • 7.1 隐式转换
    • 7.2 显式转换
    • 7.3 装箱和拆箱
  • 8 常量

1 变量的基本概念

变量本身被用来存储特定类型的数据,可以根据需要随时改动变量中所储存的数据值。变量具有名称、类型、值。变量名是变量在程序源代码中的标识。变量类型确定它所代表的的内存大小和类型,变量值是指它所代表的内存块中的数据。在程序的执行过程中,变量的值可以发生变化。使用变量之前必须声明变量,即指定变量的类型和名称。

2 变量的声明及赋值

变量的使用是程序设计中一个十分重要的环节。为什么要定义变量呢?就是要告诉编译器(Compiler)这个变量是属于哪一种数据类型,这样编译器才知道需要配置多少空间给它,以及它能存放什么样的数据。在程序运行的过程中,空间内的值是变化的,这个内存空间就称为变量。声明变量就是指定变量的名称和类型。声明变量可以一个类型后面跟多个变量,也可以在声明变量的同时给变量赋值。

string str1,str2;
int a=1,b=2,c=3;

3 变量的作用域

由于变量被定义出来后只是暂存在内存中,等到程序执行到某一个点后,该变量会被释放掉,也就是说变量有他的声明周期。变量的作用域是指程序代码能够访问该变量的区域,若超出该区域,则在编译时
会出现错误。

3.1 成员变量

在类体中定义的变量称为成员变量,成员变量在整个类中都有效。类的成员变量又可分为静态变量实例变量俩种。

class Test
{
	int x = 45;	   //实例变量
	static int y = 90;  //静态变量,也称类变量
}

如果在成员变量的前面加上关键字static,这样的成员变量称为静态变量。静态变量的有效范围可以跨类,甚至可以达到整个应用程序之内。对于静态变量,除了能在定义它的类内存取,还能直接以“类名.静态变量”的方式在其他类内使用。

3.2 局部变量

局部变量只在当前的代码块中有效。在类的方法中声明变量,包括方法的参数都属于局部变量。局部变量只有在当前方法中有效,不能用于类的其他方法。局部变量的生命周期取决于方法,当方法被调用时,C#编译器为方法中的局部变量分配内存空间,当该方法的调用结束后,则会释放方法中局部变量占用的内存空间,局部变量也会被销毁。

4 数据类型

C#中的变量类型根据其定义可以分为俩种:值类型和引用类型。这俩种类型的差异在于数据的储存方式,值类型的变量本身直接存储数据,而引用类型则存储实际数据的引用。

4.1 值类型

值类型变量直接存储其数据值,主要包含整数类型、浮点类型、布尔类型等。值类型变量在栈中进行分配,因此效率很高,使用值类型主要是为了提高性能。值类型具有如下特点:

  1. 值类型变量都存储在栈中。
  2. 访问值类型变量时,一般都是直接访问其实例。
  3. 每个值类型数据都有自己的数据副本,因此对一个值类型变量的操作不会影响其他变量。
  4. 复制值类型变量时,复制的是变量的值,而不是变量的地址。
  5. 值类型变量不能为null,必须具有一个确定的值。
    值类型是从System.ValueType继承而来的类型。

4.1.1 整数类型

整数类型用来存储整数数值,即没有小数部分的值。可以使整数,也可以是负数。整形数据在C#中有三种表示形式:十进制、八进制、十六进制
十进制:不能以 0 作为数的开头。
八进制:必须以 0 作为数的开头。
十八进制:必须以 0X0x 作为数的开头。

C#内置证书类型如下表:

类型说明( 8 位等于 1 字节)范围
sbyte8位有符号整数-28-1 ~ 28-1-1
short16位有符号整数-216-1 ~ 216-1-1
int32位有符号整数-232-1 ~ 2321-1
long64位有符号整数- 264-1 ~ 264-1-1
byte8位无符号整数0 ~ 28-1
ushort16位无符号整数0 ~ 216-1
unit32位无符号整数0 ~ 232-1
ulong64位无符号整数0 ~ 264-1

字节中存放的为二进制数字,所以范围是有计算公式的,就是通过二进制位数判断十进制的取值范围,有符号位数的第一个字节存放正负,其余存放二进制数字。

4.1.2 浮点类型

浮点类型变量主要用于处理含有小数的数值数据,浮点类型主要包含floatdouble俩种数值类型。

类型说明
float精确到7位数
double精确到15~16位数

如果不做任何设置,包含小数点的数值都别认为是double类型,如果要将数值以float类型来处理,需要通过强制使用 Ff 将其强制指定*float类型。如果要将float数值强制指定为double类型,可以使用dD来记性转换,也可以不加。
如果需要时用float类型变量时,必须在数值的后边跟随f或F,否则编译器会直接将其作为double类型处理。

float a = 1.1f;
float b = 1.1F;
double c = 1.1d;
double d = 1.1D;
double e = 1.1;

4.1.3 浮点类型

布尔类型的值只能是 truefalse。布尔类型变量不能与其他类型之间进行转化。
在定义全局变量时,整数类型和浮点类型的默认值为 0 ,布尔类型的默认值为 false

4.2 引用类型

引用类型是构建C#应用程序的主要对象数据类型。在应用程序执行的过程中,预先定义的对象类型以new创建对象实例,并且储存在堆中。堆是一种系统以弹性配置的内存空间,没有特定大大小及存活时间,因此可以被弹性的运用于对象的访问。
引用类型就类似于生活中的代理商,代理商没有自己的产品,而是代理厂家的产品,使其就好像是自己的产品一样。
引用类型具有如下特征:

  1. 必须在托管堆中为引用类型变量分配内存。
  2. 使用new关键字来创建引用类型变量。
  3. 在托管堆中分配的每个对象都有与之相关联的附加成员,这些成员必须被初始化。
  4. 引用类型变量是由垃圾回收机制来管理的。
  5. 多个引用类型变量可以同时引用同一对象, 这种情况下对一个变量的操作会影响另一个变量所引用的同一对象。
  6. 引用类型被赋值前的值都是null。

所有被称为“类”的都是引用类型,主要包括类、接口、数组、委托

例:

using System;
namespace ConsoleApp1
{
    class Program
    {
        class C     
        {
            public int Value = 0;  
        }
        static void Main(string[] args)
        {
            int v1 = 0;
            int v2 = v1;
            v2 = 927;
            C c1 = new C();
            C c2 = c1;
            c2.Value = 112;
            Console.WriteLine("Values:{0},{1}", v1, v2);  			// 0 ,927
            Console.WriteLine("Refs:{0},{1}", c1.Value, c2.Value);  // 112  ,112
            Console.ReadLine();
        }
        
    }
}

5 值类型与引用类型的区别

从概念上看,值类型直接存储其值,而引用类型储存对其值得引用。这俩种类型储存在内存的不同地方。在C#中,必须在设计类型时就决定类型实例的行为。如果在编写代码时不能理解引用类型和值类型的区别,那么将会给代码带来不必要的异常。
从内存空间上看,值类型是在栈中操作,而引用类型则在堆中分配存储单元。栈在编译是就分配好空间,在代码中有栈的明确定义,而堆是程序运行中动态分配的内存空间,可以根据程序的运行情况动态的分配内存的大小。因此值类型总是在内存中占用一个预定义的字节数。而引用类型的变量则在堆中分配一个内存空间,这个内存空间包含的是对另一个内存位置的引用,这个位置是托管堆中的一个地址,即存放此变量实际值的地方。
也就是说值类型相当于现金,要用就直接用。而引用类型相当于存着,要用得先去银行取。
C#的所有值类型均隐式派生自System.ValueType,而System.ValueType直接派生于System.Object。即System.ValueType本身是一个类类型,而不是值类型。其关键在于ValueType重写了Equals()方法,而对值类型按照实际的值来比较,而不是引用地址来比较。
下面以一段代码来展示值类型与引用类型的区别:

using System;
namespace ConsoleApp1
{
    class Program
    {
       
        static void Main(string[] args)
        {
            ReferenceAndValue.Demonstration();
            Console.ReadKey();
        }
    }
    public class stamp
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
    public static class ReferenceAndValue
    {
        public static void Demonstration()
        {
            stamp st1 = new stamp { Name = "张三", Age = 25 };
            stamp st2 = new stamp { Name = "李四", Age = 18 };
            int age = st1.Age;
            st1.Age = 22;
            stamp st3 = st2;
            st2.Name = "王五";
            Console.WriteLine("st1的年龄{0}",st1.Age);  // 22
            Console.WriteLine("年龄的值{0}",age);       // 25
            Console.WriteLine("st2的名字{0}",st2.Name); // 王五
            Console.WriteLine("st3的名字{0}",st3.Name); // 王五

        }
    }
}

6 枚举类型

枚举类型是一种独特的值类型,,它用于声明一种具有相同性质的常量。编写与日期相关的应用程序时,经常需要用到年、月、日、星期等日期数据,可以将这些数据组织成多个不同名称的枚举类型。使用枚举可以增加程序的可读性、可维护性。同时枚举类型可以避免类型错误。
在定义枚举类型时,如果不对其进行赋值,默认情况下,第一个枚举类型的值位0,后面每个枚举数的值依次递增1。
在C#中使用关键则enum类声明枚举,其形式如下:

enum 枚举名
{
	//枚举值名称 = 枚举值
	list1 = value1,
	list2 = value2,
	list3 = value3,
	...
	listN = valueN
}

例:

using System;
namespace ConsoleApp1
{
    class Program
    {
        enum MyDate
        {
            Sun = 0,
            Mon = 1,
            Tue = 2,
            Wed = 3,
            Thi = 4,
            Fri = 5,
            Sta = 6
        }
        static void Main(string[] args)
        {
            int k = (int)DateTime.Now.DayOfWeek;
            switch (k)
            {
                case (int)MyDate.Sun:
                    Console.WriteLine("今天是星期日");
                    break;
                case (int)MyDate.Mon:
                    Console.WriteLine("今天是星期一");
                    break;
                case (int)MyDate.Tue:
                    Console.WriteLine("今天是星期二");
                    break;
                case (int)MyDate.Wed:
                    Console.WriteLine("今天是星期三");
                    break;
                case (int)MyDate.Thi:
                    Console.WriteLine("今天是星期四");
                    break;
                case (int)MyDate.Fri:
                    Console.WriteLine("今天是星期五");
                    break;
                case (int)MyDate.Sta:
                    Console.WriteLine("今天是星期六");
                    break;

                default:
                    break;
            }
            Console.ReadKey();
        }
    }
}

7 类型转换

对于类型转换,就是用目标内存块去套取源内存中的数据,能套多少算多少。

7.1 隐式转换

所谓隐式转换就是不需要声明就能进行的转换。进行隐式转换,编译器不需要进行检查就能自动进行转换。下表列出了可以进行隐式转换的数据类型

源类型目标类型
sbyteshort、int、long、float、double、decimal
byteshort、ushort、int、uint、long、ulong、float、double、decimal
shortint、long、float、double、decimal
ushortint、uint、long、ulong、float、double、decimal
intlong、float、double、decimal
uintlong、ulong、float、double、decimal
charushort、int、uint、long、ulong、float、double、decimal
floatdouble
ulongfloat、double、decimal
longfloat、double、decimal

当一种类型的值转换为大小相等或更大的另一类型时,发生扩大转换。当一种类型的值转换为比较小的另一种类型时,则发生收缩转化。

7.2 显式转换

显式转换也可以称为强制转换,需要在代码中明确地声明要转换的类型。如果要把高精度的变量值赋值给低精度的变量,就需要使用显式转换。
下表列出了需要进行显式转换的数据类型:

源类型目标类型
sbytebyte、ushort、unit、ulong、char
bytesbyte 、char
shortsbyte、byte、ushort、unit、ulong、char
ushortsbyte、byte、short、char
intsbyte、byte、short、ushort、unit、ulong、char
uintsbyte、byte、short、ushort、int、char
charsbyte、byte、short
floatsbyte、byte、short、ushort、int、uint、long、ulong、char、decimal
ulongsbyte、byte、short、ushort、int、uint、long、char
longsbyte、byte、short、ushort、int、uint、ulong、char
doublesbyte、byte、short、ushort、int、uint、ulong、long、char、decimal
decimalsbyte、byte、short、ushort、int、uint、ulong、long、char、decimal

7.3 装箱和拆箱

将值类型转换为引用类型的过程叫做装箱,相反,将引用类型转换为值类型的过程叫做拆箱。在执行拆箱操作时,要符合类型一致的原则,否则会出现异常。
装箱是将一个值类型转换为一个对象类型(Object),而拆箱是将一个对象类型显式转换为一个值类型。对于装箱而言,它是将被装箱的值类型复制一个副本来转换。而对于拆箱而言,需要注意类型的兼容性,不能将一个值为string的object类型转换为int类型。
例:

using System;
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 1;
            Object ob1 = new Object();  
            ob1 = a;        //装箱 将值类型转化引用类型

            string st1 = "张三";
            string st2 = "";
            Object ob2 = st1;
            st2 = (string)ob2;  //拆箱 将引用类型转换为值类型

            Console.WriteLine("ob1:{0}",ob1);   // 1
            Console.WriteLine("st2:{0}", st2);  //张三
            Console.ReadKey();
        }
    }
}

8 常量

常量就是值固定不变的量,而且常量的值在被编译时就已经确定。C#中用关键字const定义差常量,并且创建常量时必须设置初始值。常量就相当于每个公民的身份证号码,一点设置就不允许再修改。

热门文章

暂无图片
编程学习 ·

Java输出数组的内容

Java输出数组的内容_一万个小时-CSDN博客_java打印数组内容1. 输出内容最常见的方式// List<String>类型的列表List<String> list new ArrayList<String>();list.add("First");list.add("Second");list.add("Third");list.ad…
暂无图片
编程学习 ·

母螳螂的“魅惑之术”

在它们对大蝗虫发起进攻的时候&#xff0c;我认认真真地观察了一次&#xff0c;因为它们突然像触电一样浑身痉挛起来&#xff0c;警觉地面对限前这个大家伙&#xff0c;然后放下自己优雅的身段和祈祷的双手&#xff0c;摆出了一个可怕的姿势。我被眼前的一幕吓到了&#xff0c;…
暂无图片
编程学习 ·

疯狂填词 mad_libs 第9章9.9.2

#win7 python3.7.0 import os,reos.chdir(d:\documents\program_language) file1open(.\疯狂填词_d9z9d2_r.txt) file2open(.\疯狂填词_d9z9d2_w.txt,w) words[ADJECTIVE,NOUN,VERB,NOUN] str1file1.read()#方法1 for word in words :word_replaceinput(fEnter a {word} :)str1…
暂无图片
编程学习 ·

HBASE 高可用

为了保证HBASE是高可用的,所依赖的HDFS和zookeeper也要是高可用的. 通过参数hbase.rootdir指定了连接到Hadoop的地址,mycluster表示为Hadoop的集群. HBASE本身的高可用很简单,只要在一个健康的集群其他节点通过命令 hbase-daemon.sh start master启动一个Hmaster进程,这个Hmast…
暂无图片
编程学习 ·

js事件操作语法

一、事件的绑定语法 语法形式1 事件监听 标签对象.addEventListener(click,function(){}); 语法形式2 on语法绑定 标签对象.onclick function(){} on语法是通过 等于赋值绑定的事件处理函数 , 等于赋值本质上执行的是覆盖赋值,后赋值的数据会覆盖之前存储的数据,也就是on…
暂无图片
编程学习 ·

Photoshop插件--晕影动态--选区--脚本开发--PS插件

文章目录1.插件界面2.关键代码2.1 选区2.2 动态晕影3.作者寄语PS是一款栅格图像编辑软件&#xff0c;具有许多强大的功能&#xff0c;本文演示如何通过脚本实现晕影动态和选区相关功能&#xff0c;展示从互联网收集而来的一个小插件&#xff0c;供大家学习交流&#xff0c;请勿…
暂无图片
编程学习 ·

vs LNK1104 无法打开文件“xxx.obj”

写在前面&#xff1a; 向大家推荐两本新书&#xff0c;《深度学习计算机视觉实战》和《学习OpenCV4&#xff1a;基于Python的算法实战》。 《深度学习计算机视觉实战》讲了计算机视觉理论基础&#xff0c;讲了案例项目&#xff0c;讲了模型部署&#xff0c;这些项目学会之后可以…
暂无图片
编程学习 ·

工业元宇宙的定义与实施路线图

工业元宇宙的定义与实施路线图 李正海 1 工业元宇宙 给大家做一个关于工业元宇宙的定义。对于工业&#xff0c;从设计的角度来讲&#xff0c;现在的设计人员已经做到了普遍的三维设计&#xff0c;但是进入元宇宙时代&#xff0c;就不仅仅只是三维设计了&#xff0c;我们的目…
暂无图片
编程学习 ·

【leectode 2022.1.15】完成一半题目

有 N 位扣友参加了微软与力扣举办了「以扣会友」线下活动。主办方提供了 2*N 道题目&#xff0c;整型数组 questions 中每个数字对应了每道题目所涉及的知识点类型。 若每位扣友选择不同的一题&#xff0c;请返回被选的 N 道题目至少包含多少种知识点类型。 示例 1&#xff1a…
暂无图片
编程学习 ·

js 面试题总结

一、js原型与原型链 1. prototype 每个函数都有一个prototype属性&#xff0c;被称为显示原型 2._ _proto_ _ 每个实例对象都会有_ _proto_ _属性,其被称为隐式原型 每一个实例对象的隐式原型_ _proto_ _属性指向自身构造函数的显式原型prototype 3. constructor 每个prot…
暂无图片
编程学习 ·

java练习代码

打印自定义行数的空心菱形练习代码如下 import java.util.Scanner; public class daYinLengXing{public static void main(String[] args) {System.out.println("请输入行数");Scanner myScanner new Scanner(System.in);int g myScanner.nextInt();int num g%2;//…
暂无图片
编程学习 ·

RocketMQ-什么是死信队列?怎么解决

目录 什么是死信队列 死信队列的特征 死信消息的处理 什么是死信队列 当一条消息初次消费失败&#xff0c;消息队列会自动进行消费重试&#xff1b;达到最大重试次数后&#xff0c;若消费依然失败&#xff0c;则表明消费者在正常情况下无法正确地消费该消息&#xff0c;此时…
暂无图片
编程学习 ·

项目 cg day04

第4章 lua、Canal实现广告缓存 学习目标 Lua介绍 Lua语法 输出、变量定义、数据类型、流程控制(if..)、循环操作、函数、表(数组)、模块OpenResty介绍(理解配置) 封装了Nginx&#xff0c;并且提供了Lua扩展&#xff0c;大大提升了Nginx对并发处理的能&#xff0c;10K-1000K Lu…
暂无图片
编程学习 ·

输出三角形

#include <stdio.h> int main() { int i,j; for(i0;i<5;i) { for(j0;j<i;j) { printf("*"); } printf("\n"); } }
暂无图片
编程学习 ·

stm32的BOOTLOADER学习1

序言 最近计划学习stm32的BOOTLOADER学习,把学习过程记录下来 因为现在网上STM32C8T6还是比较贵的,根据我的需求flash空间小一些也可以,所以我决定使用stm32c6t6.这个芯片的空间是32kb的。 #熟悉芯片内部的空间地址 1、flash ROM&#xff1a; 大小32KB&#xff0c;范围&#xf…
暂无图片
编程学习 ·

通过awk和shell来限制IP多次访问之学不会你打死我

学不会你打死我 今天我们用shell脚本&#xff0c;awk工具来分析日志来判断是否存在扫描器来进行破解网站密码——限制访问次数过多的IP地址&#xff0c;通过Iptables来进行限制。代码在末尾 首先我们要先查看日志的格式&#xff0c;分析出我们需要筛选的内容&#xff0c;日志…
暂无图片
编程学习 ·

Python - 如何像程序员一样思考

在为计算机编写程序之前&#xff0c;您必须学会如何像程序员一样思考。学习像程序员一样思考对任何学生都很有价值。以下步骤可帮助任何人学习编码并了解计算机科学的价值——即使他们不打算成为计算机科学家。 顾名思义&#xff0c;Python经常被想要学习编程的人用作第一语言…
暂无图片
编程学习 ·

蓝桥杯python-数字三角形

问题描述 虽然我前后用了三种做法&#xff0c;但是我发现只有“优化思路_1”可以通过蓝桥杯官网中的测评&#xff0c;但是如果用c/c的话&#xff0c;每个都通得过&#xff0c;足以可见python的效率之低&#xff08;但耐不住人家好用啊&#xff08;哭笑&#xff09;&#xff09…