一、C#中的类型
二、类型所能表示的数的范围
其中S开头代表带符号(用一位来存储符号),U开头代表无符号
8位 = 1字节byte
三、程序的静态与动态:
静态-尚未运行,在编译器中编译
动态-正在运行、调试
程序不运行时在硬盘(外存)里,称作静态的
运行时装载到内存里,称作动态的
四、程序对内存的利用,分为两个区域,栈和堆
栈Stack:用于方法调用,比较小,比较快
堆Heap:用于储存对象,比较大,比较慢
调用函数错误(例如不恰当的递归)会产生爆栈的问题
堆不会爆,但忘记回收对象(free)会产生内存泄露问题
C#有垃圾收集机制,不用手动示范内存
五、C#内存系统
包括两大类:引用类型和值类型
所以类型都一object(对象)为基类型,C#的类型系统是由object类型派生出的树状结构
枚举的定义方法
暂时无法在飞书文档外展示此内容
关键字
第一组:引用类型
object、string对应以其命名的类,因为非常常用,被C#语言吸收为关键字
class、interface、delegate不是对应的类,而是-用来-自定义类-的-关键字
第二组:值类型
bool、byte、char
··
··········关键字对应相应的结构体或枚举类型struct、enum是用来定义类型的关键字
第三组:其他重要关键字
true、false是bool类型的值
void是无返回值的函数的类型,NULL是引用变量不引用任何变量时的值
var(可变匿名变量?)、dynamic是用于声明变量的关键字
var常用与构造函数(CreatXXXX())中,不可滥用,会大幅降低代码可读性
以上表中蓝色为基本数据类型(C#内建数据类型)
其他数据类型由他们组成,他们是构成其他数据类型的基本单元
六、变量
变量名对应变量在内存中的存储位置,可以看做一个内存中储存地址的标签
变量一共有7种
1、静态变量(静态成员变量,隶属与类,常称作静态字段)
2、实例变量(非静态成员变量,隶属与类的实例,称作为成员变量或字段)
3、数组元素
4、值参数
5、引用参数
6、输出形参
7、局部变量:声明在方法体中的变量
字段是属性的雏形,但和属性相比,字段可以被赋任何值(包括不合理的值)
而属性有保护功能
C#数组(array)声明
与C语言不同,C#的数组中括号写在类型后而不是变量名后,且中括号内为空
暂时无法在飞书文档外展示此内容
值参数变量
作为函数的参数(值传递)
暂时无法在飞书文档外展示此内容
引用参数变量
作为方法的参数,但是前面有关键字ref修饰,用于引用传递
输出参数变量
作为方法的参数,但是前面有关键字out修饰
变量名取名时应选名词+小驼峰命名
总结:变量 = 以变量名所对应的内存地址为起点、以其数据类型所要求的存储空间为长度的一块内存区域
含符号类型中第一位0表示正号,1表示负号
在含符号类型中,将内存中二进制表示的正数取负的方法:
每一位按位取反(1变0,0变1),再整个数加上1
存储负数时存的是负数的补码
知识补充:原码、补码
问题由来:如何使用二进制表示带负号的十进制数?
方案1:原码
用一个字节的最高位表示数的正负,0表示正,1表示负
例:+2表示为00000010 (第一位0表示+)
-2表示为10000010 (第一位1表示-)
称作十进制负数的原 1(十进制)+ -1(十进制)= 0
即 1 00000001
+ -1 ???????? 计算得??????? = 11111111
= 0 00000000
具体变换方法:将要变换进制的负数的 绝对值 按位取反 再加 1
称作十进制负数的补码表示法
-1的二进制补码表示为 11111111
00000001(+1的二进制原码)+ 11111111(-1的二进制补码)= 00000000
补码可以保留变换进制前的加法运算性质
意义:使用补码,可以将减法转换为加一个负数的形式,在设计电路时就只需设计加法器电路
所以一个字节表示的书最大为127,最小为-128
比127更大,就变成了负数的补码,比-128更小,就变成了正数的原码
在存储的数比较小,填不满申请的存储空间时,会在数前面补零
存储空间是从地址数值高的字节开始存,8位8位的存
高8位对应高8位,低8位对应低8位
对于值类型,变量和实例是合二为一的
对于引用类型,变量和类型的关系是“小朋友牵气球”
系统看到引用类型的变量,就会分配一个4个字节大小的空间
并将空间内所有位的值都变为零,以此表示该对象没有引用任何实例
分配实例之后,实例的地址会被保存在刚才申请的引用变量存储空间中
引用变量存的是实例的地址!
new创建实例时,也会寻找空闲的内存空间,按实例的类型安排内存空间
局部变量、形参是在栈(stack)上分配内存
全局变量、静态变量是在静态区
实例变量是随着实例在堆上分配内存(动态内存分配是在堆上开辟)
变量的默认值
一旦变量在内存中分配好后,它的内存块就被统统刷成 0,这就是它的默认值。
局部变量没有默认值,因为 C# 为了避免不安全代码,要求局部变量必需有显式赋值。
七、常量
在定义变量时前加Const修饰符,表示这个值是不能变的,成为常量
1、常量不能被再次赋值
2、常量的初始化器不能省略
暂时无法在飞书文档外展示此内容
八、装箱与拆箱
暂时无法在飞书文档外展示此内容
object是所有类型的基类型,是一个引用类型
装箱
暂时无法在飞书文档外展示此内容
x的值为100,但内存地址为100的存储空间是操作系统使用的,将引用变量指向操作系统使用的空间,系统可能会出问题
当计算机发现赋给引用变量的不是一个堆上的实例,而是一个栈上的值类型的值
计算机会先把值类型的值复制,然后在堆上开辟一块空间,建立一个新实例对象,将值类型的值封装入其中,然后将这个对象地址存入obj变量,
装箱:将栈上的值类型的值,封装成对象放在堆上
拆箱
暂时无法在飞书文档外展示此内容
将obj指向的堆上的对象的值复制出来,然后按整数类型存储到栈上的变量上
拆箱:将堆上的实例按要求的数据类型拆出,然后存储到栈上
装箱和拆箱会损失程序的性能
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示