C# 数据类型详解以及变量、对象与内存
学习刘铁猛老师《C#语言入门详解》视频,针对其中重点知识点进行总结。
1、什么是类型?
类型又称为数据类型(Data Type),数据类型在数据结构中的定义是一个值的集合以及定义在这个值集上的一组操作。
可以简单理解为数据在内存中存储的“型号”;小内存容纳大尺寸数据会丢失精准度,发生错误;而大内存容纳小尺寸数据会导致浪费。
还应注意编成语言的数据类型与数学中的数据类型不完全相同,例如数学中 3/4=0.75 而在C# 语言中 3 /4 =0。
不同的编程语言对数据类型的约束程度不一样,所以有强类型编程语言和弱类型编程语言的区分。
变量是用来存储值得所在处,它们有名字和数据类型。变量的数据类型决定了如何将代表这些值的位存储到计算机的内存中。
我们都知道,计算机的世界是二进制的,仅仅用0和1就构建了所有的表达,计算机用来存储0或者1的单位就是位(bit),8个位组成一个字节(byte)。
2、数据类型在C#语言中的作用
一个C#类型中所包含的信息有:
- 存储此类型变量所需的内存空间大小 如 int 类型需要4个字节也就是4*8=32位进行存储
- 此类型的值可表示的最大、最小值范围 sbyte占一个字节8位,s前缀表示带符号位,取值范围-128到127,byte占一个字节,不带符号位,取值范围位0-255。
- 此类型所包含的成员(如方法、属性、事件等) 可以用于ide的错误识别和反射时动态调用
- 此类型由何基类派生而来
- 程序运行的时候,此类型的变量在分配在内存的什么位置(栈或堆)
- 此类型所允许的操作(运算)
3、程序的内存使用分析
- Stack简介:函数调用使用,函数调用实际可以理解位栈帧的入栈出栈操作。空间较小,一般1-2M
- Stack overflow 空间较小所以会出现栈空间溢出的情况。例如递归函数未正常结束。
- Heap简介:用来存储对象(实例)使用,空间较大,可以达到数G
- 使用Perfomance Monitor观察内存使用情况
- 关于内存泄漏 未使用的对象未赋值为null导致垃圾收集器未处理,导致空间浪费,这称为内存泄漏。
这里给出观察内存使用情况的一个样例,新增的wpf程序,使用Winform程序也是可行的。
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Documents;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- using System.Windows.Navigation;
- using System.Windows.Shapes;
- namespace HeapSample
- {
- /// <summary>
- /// MainWindow.xaml 的交互逻辑
- /// </summary>
- public partial class MainWindow : Window
- {
- public MainWindow()
- {
- InitializeComponent();
- }
- List<Window> winList;
- private void Btn_Consume_Click(object sender, RoutedEventArgs e)
- {
- winList = new List<Window>();
- for (int i = ; i < ; i++)
- {
- Window wd = new Window();
- winList.Add(wd);
- }
- }
- private void Btn_ClearHeap_Click(object sender, RoutedEventArgs e)
- {
- winList.Clear();
- }
- }
- }
至于Perfomance Monitor观察内存使用情况,可以查看 https:////www.cnblogs.com/FreeLoopPowter/p/12298482.html 。
4、C# 数据类型系统
C#的五大数据类型
- 类(class):如 Form,Window,Console.String
- 结构体(structres):如 Int32,Int64,SIngle,Double
- 枚举(Enumerations):如Visibility,WindoState
- 接口(Interfaces)
- 委托(Delegate)
C#类型的派生谱系
这里顺带提一点,我们经常在编辑器中使用结构体时,例如定义一个32位的整型变量时,我们基本使用 int a=5; 这样的形式,这并不是前面说的结构体类型包含的内容,为啥没有报错呢?
这是由于某些数据类型如此常用,以至于许多编辑器允许代码以简化语法来操纵它们(也叫关键字)。这种语法不仅增强了代码的可读性和书写的方便性,生成的IL代码还与使用对应的FCL类库中的类型一致。
这类编译器能直接支持的类型称为 基元类型。基元类型直接映射到Framework类库(FCL)中存在的类型,可以通过按 F12 查看定义,就可以看到映射的FCL类型。
查看CLR Via C#一书,发现其对值类型和引用类型的阐述非常明了,还包括了对值类型和引用类型内存分配的讲解。这里选取重要内容进行记录,方便自己后续温习。对数据类型的内存分配情况的分析有利于后续理解方法的传值参数、引用参数、输出参数的理解。
CLR支持两种类型:引用类型和值类型。虽然FCL的大多数类型都是引用类型,但程序员使用最多的还是值类型。引用类型总是从托管堆中分配,C#的new 操作符返回对象内存地址——即指向对象数据的内存地址。使用引用类型必须留意性能问题,首先认清楚以下四个事实。
- 内存必须从托管堆分配。
- 堆上分配的每个对象都有一些额外成员。
- 对象中的其他字段(为字段而设)总是设为零。
- 从托管堆分配对象时,可能强制执行一次垃圾回收。(当垃圾回收器发现内存不够时会强制执行一次垃圾回收)
如果所有类型都是引用类型,应用程序的性能将显著下降。设想每次使用 Int32 时都进行一次内存分配,性能会收到多么大的影响!为了提升简单和常用的数据类型的性能,CLR提供了名为“值类型”的轻量级类型。值类型的实例一般是在线程栈上分配(虽然也可作为字段嵌入引用类型的对象中),在代表值类型实例的变量中不包含指向实例的指针。变量中包含了实例本身的字段。由于变量已包含了实例的字段,所以操作实例中的字段不需要提取指针。值类型的实例不受垃圾回收器的控制。因此,值类型的使用缓解了托管堆的压力,并减少了应用程序生存期间的垃圾回收次数。
下面给出一个示例,结合图示讲解值类型和引用类型的区别。引用类型变量对对象实例的引用实际上是以在栈中分配的引用类型变量存放堆中实例的起始内存地址来实现的。
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace RefTypeAndValueTypeApp
- {
- class Program
- {
- static void Main(string[] args)
- {
- //在堆上分配空间
- SomeRef r1 = new SomeRef();
- //在栈上分配空间
- SomeValue v1 = new SomeValue();
- r1.x = ;//提取指针,给指针引用的对象赋值
- v1.x = ;//在栈上修改,由0修改为5
- Console.WriteLine(r1.x);//显示 "5"
- Console.WriteLine(v1.x);//同样显示 "5"
- //以上内存分配情况见图左边
- //只复制引用(指针)
- SomeRef r2 = r1;
- //在栈上分配并复制成员
- SomeValue v2 = v1;
- r1.x = ;//r1.x 和 r2.x 都会改变
- v1.x = ;//v2.x会改变 v1.x不会改变
- Console.WriteLine(r1.x);//显示 "8"
- Console.WriteLine(r2.x);//同样显示 "8"
- Console.WriteLine(v1.x);//显示 "9"
- Console.WriteLine(v2.x);//显示 "5"
- //以上部分程序执行的内存分配情况见图右侧
- //让控制台等待输入,有输入后才终止
- Console.ReadKey();
- }
- }
- /// <summary>
- /// 引用类型
- /// </summary>
- class SomeRef
- {
- public Int32 x;
- }
- /// <summary>
- /// 值类型
- /// </summary>
- struct SomeValue
- {
- public Int32 x;
- }
- }
书写这篇随笔的主要目的是自己温习和防遗忘,本着分享的心态公开,如有不妥之处,还请指出,相互交流。
C# 数据类型详解以及变量、对象与内存的更多相关文章
- Python之路-变量和基本数据类型详解(变量、数据类型、)
一.注释 注释的作用: 增加程序的可读性 作为调试用 提高团队的合作效率 注释的分类 1.单行注释 以井号(#)开头,右边的所有内容当做说明 2.多行注释 以三对单引号(’’’注释内容’’’)将注释包 ...
- 详解Go变量类型的内存布局
定义 每当我们编写任何程序时,我们都需要在内存中存储一些数据/信息.数据存储在特定地址的存储器中.内存地址看起来像0xAFFFF(这是内存地址的十六进制表示). 现在,要访问数据,我们需要知道存储它的 ...
- c# 把一个匿名对象赋值给一个Object类型的变量后,怎么取这个变量? c# dynamic动态类型和匿名类 详解C# 匿名对象(匿名类型)、var、动态类型 dynamic 深入浅析C#中的var和dynamic
比如有一个匿名对象,var result =......Select( a=>new { id=a.id, name=a.name});然后Object obj = result ;我怎 ...
- 2-2和2-3基本数据类型 & 2-4基本数据类型详解 & 3-1和3-2整形字面量值及变量声
2-4基本数据类型详解 3-1和3-2整形字面量值及变量声 023是八进制的 0x1357是十六进制 0X3C也是十六进制 0x1abL:长整型 变量声明 数据类型 空格 变量名 赋值: 变量的定义:
- python 数据类型详解
python数据类型详解 参考网址:http://www.cnblogs.com/linjiqin/p/3608541.html 目录1.字符串2.布尔类型3.整数4.浮点数5.数字6.列表7.元组8 ...
- python数据类型详解(全面)
python数据类型详解 目录1.字符串2.布尔类型3.整数4.浮点数5.数字6.列表7.元组8.字典9.日期 1.字符串1.1.如何在Python中使用字符串a.使用单引号(')用单引号括起来表示字 ...
- 转 python数据类型详解
python数据类型详解 目录 1.字符串 2.布尔类型 3.整数 4.浮点数 5.数字 6.列表 7.元组 8.字典 9.日期 1.字符串 1.1.如何在Python中使用字符串 a.使用单引号(' ...
- 详解js变量、作用域及内存
详解js变量.作用域及内存 来源:伯乐在线 作者:trigkit4 原文出处: trigkit4 基本类型值有:undefined,NUll,Boolean,Number和Strin ...
- python之数据类型详解
python之数据类型详解 二.列表list (可以存储多个值)(列表内数字不需要加引号) sort s1=[','!'] # s1.sort() # print(s1) -->['!', ' ...
随机推荐
- Hibernate定制Tuplizer
Hibernate定制Tuplizer,使用@Tuplizer注解 本文转自http://www.521100.net/hibernate-tuplizer.html 首先,第一步在Hinbernat ...
- git reset --hard HEAD^ 在cmd中执行报错
报错: D:\git-root\test>git reset --hard HEAD^ More? More? fatal: ambiguous argument 'HEAD ': unknow ...
- Kdenlive-简单的操作
版权声明:原创文章,未经博主允许不得转载 前章:https://www.cnblogs.com/weilinfox/p/12246123.html 尽管是简单操作,但内容比较多.可以一边自己尝试编辑一 ...
- JS-04-流程控制和循环
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 设计模式-03工厂方法模式(Factory Method Pattern)
插曲.简单工厂模式(Simple Factory Pattern) 介绍工厂方法模式之前,先来做一个铺垫,了解一下简单工厂模式,它不属于 GoF 的 23 种经典设计模式,它的缺点是增加新产品时会违背 ...
- DOCKER 学习笔记4 认识DockerCompose 多容器编排
前言 通过上一节的学习,学会了如何在Linux 环境下搭建Docker并且部署Springboot 项目,并且成功的跑了起来,当然,在生产环境中,不只是需要一个后端的Web 项目,还需要比如 Ngin ...
- 实验11:EIGRP
实验8-1:EIGRP 基本配置 实验目的通过本实验可以掌握:(1)在路由器上启动EIGRP 路由进程(2)启用参与路由协议的接口,并且通告网络(3)EIGRP 度量值的计算方法(4)可行距离(FD) ...
- JSP&Servlet学习笔记----第3章
Web容器是JSP/Servlet唯一认识的HTTP服务器. HTTP是基于请求/响应的无状态通信协议. 流程: 1.请求来到HTTP服务器 2.HTTP服务器将请求转交给Web容器 3.Web容器创 ...
- Windbg实用手册
Windbg工作中用的不多,所以命令老是记不住,每次使用都要重新查命令,挺烦. 趁这次培训的机会好好测试和总结了一下,下次再用就方便多了. 在这里一起共享一下,如果有错误,请指正. 基本知识和常用命令 ...
- Net Core 中WebAPI有关 Session的设置,及获取
步骤一: 在Startup 文件中做相应的设置 ConfigureServices方法里添加 //ConfigureServices添加: services.AddSession(options =& ...