本节内容:

1.什么是类型(Type)

2.类型在C#语言中的作用

3.C#语言的类型系统

4.变量、对象与内存

1.什么是类型(type)

类型又名数据类型(Date Type),是数据在内存中存储时的“型号”,小内存容纳大数据会丢失精确度、发生错误大内存存纳小尺寸数据会导致浪费,编程语言的数据类型与数据的数据类型不完全相同

1.2.强类型语言(保证了数据的完整性)(数据受到数据类型的约束严格)与弱类型语言(灵活性与危险性并存)(保证数据的正确性)的比较

*C语言中这里的if里面得的值不为0其他都为真,即使不是bool类型也可通过编译,故为弱类型;

*相对的C#中if条件里面必须为bool类型的值,否则编译不过去。

C语言举例-if条件;JavaScript示例:动态类型(极弱类型语言);C#语言对弱类型?/动态类型的模拟

2.类型在C#语言中的作用

2.1.一个C#类型中所包含的信息有:

①存储此类型变量所需的内存空间大小;

②此类型值可表示的最大、最小值范围;

③此类型所包含的成员(如方法、属性、事件等);

④程序运行的时候,此类型的变量在分配内存的什么位置;

Stack简介:比较小,比较快,用于方法(函数)调用,(装多了会爆);

第一种情况为:算法没写好,函数调用过多,栈就爆了;

第二种情况:程序有错误,不小心在栈上分配了太多的内存,栈就爆了;

称为:Stack overflow。

Heap简介:即堆,比较大,用于存储对象(实例就放在堆里面),如果忘记回收对象会造成内存浪费,这种浪费学名叫做:内存泄漏。

使用Performance Monitor查看进程的堆(Heap)内存使用量;

关于内存泄漏:C#中存在垃圾回收机制,对象没人用了,有垃圾回收机制自动回收对象的内存。不用像java一样需要手动释放内存,换句话说C#较安全比C++安全得多。

⑤此类型所允许的操作符(运算)如: double result = 3 / 4;结果为0

而double result = 3.0 / 4.0;结果为0.75;

⑥静态的程序指的是没有在运行的程序。

程序的静态期(编辑器和编译器),动态期(运行期):静态的分析代码,动态的调试程序 。

可以这么说静态的程序是装在硬盘里的,动态的程序是装在内存里的。

双击一个应用程序(exe)就是一个把存储在硬盘里的静态程序动态加载到内存的过程。

Process(进程)概念介绍:一个程序从硬盘加载到内存开始执行之后,就形成一个进程,换句话说就是这个程序正在运行的实例。进程名与(exe)程序文件名字相同,且每个进程都有一个pid(Process ID)

Windows+R键可以打开运行窗口,输入perfmon(Performance Monitor)进入性能监视器,打开性能监视器窗口,该窗口默认监视总的进程,可以点“x”在“+”号中添加具体的进程,监视某一程序的内存占比变化。

3.C#语言的类型系统

①C#五大数据类型

类(Class):如Windows、Form、Console等

结构体(Structures):如Int32、Int64、Single、Double

如:在int中f12查看定义:public struct Int32 : IComparable

枚举(Enumerations):如HorizontalAlignment、Visbility

例如:public enum FormWindowState

{

//默认大小的窗口。

Normal = 0,

//最小化的窗口。

Minimized = 1,

//最大化的窗口。

Maximized = 2,

}

接口(Interfaces)

委托(Delegates)

②C#类型的派生谱系:

Object:引用类型(Reference Type)和值类型(Value Type)

引用类型:类、接口、委托

值类型:结构体、枚举

最右边的分类上下来看可以分为三组:第一组(与引用类型相关):object、string(这两个关键词基类(class)为本身)与class 、interface、delegate(这三个关键字不是具体的数据类型f12找不到定义的,而是运用这三个关键词去创建他们的数据类型);

第二组(与值类型相关):横线以上:对应的是真正数据类型;横线以下与第一组的横线以下的三个一样,都是去定义各自的类型,没有基类型。

第三组:true和false为bool类型的返回值;void表示不需要返回值,null表示一个引用变量里面的值是空的不属于任何数据类型;var与dynamic是用来声明变量的(以后会用到)。

(蓝色的字体表示为现成的数据类型,而且十分常用,甚至被归为关键字了;其次这些数据类型都是基本数据类型(即别的类型都是拿这些数据类型去构成的))

4.变量、对象与内存

*值类型与引用类型的内存存储方式是不同的,不分清将会造成很大错误!

①什么是变量

表面上来看(从C#代码的上下文行文来看),变量的用途是存储数据。

实际上,就存储在这个地址里面),并且每一个变量都有一个存储类型,以决定什么类型的值能够存入变量。*即变量名称表示(对应着)变量的值在内存中的存储位置

*认识一个事物是由浅入深,由表及里,由现象到本质的过程。

变量一共有7种:

静态变量(static),实例变量(也叫非静态变量)(成员变量、字段),数组元素、值参数、引用参数、输出形参、局部变量。

狭义的变量指的是局部变量,因为其它种类的变量都有自己的约定名称。

  简单地讲,局部变量就是方法体(函数体)里面声明的变量。

变量的声明:

有效的修饰符组合(可无) 类型 变量名 初始化器(可无)如:int x;

*总结:变量=以变量名所对应的内存地址为起点,以其数据类型所要求的存储空间为长度的一块内存区域

②值类型的变量:

以byte/sbyte/short/ushort为例:

值类型没有实例,所谓“实例”与变量合二为一(因为是结构体struct)。

值类型变量的存储如:byte b;b=100;这两条语句作用为:首先确定byte数据类型需要的存储空间大小,然后去栈内存中找可以使用的(空的)内存地址,找到内存地址后,就把变量名与该内存地址对应起来,再把100转化为2进制数据写进该地址内存中。

③引用类型的变量与实例:

引用类型变量与实例的关系:引用类型变量里存储的数据是对象(实例)的内存地址解释如下:存储引用类型变量与实例时如:

*创建Student类的引用类型变量:Student stu;创建后便去栈内存(因为其为局部变量故由栈分配内存)中寻找空闲的内存并分得4个字节的内存空间(凡是引用类型固定分配4字节)。

*然后创建Student类的实例:new Student();这个时候要去找空闲的堆内存,找 到之后开始分配内存,这时需要计算需要多大的内存(类中的各种数据占内存的总 和),分完之后还要在该内存块内部进行分组:这块内存是存储哪种数据类型的, 那块属于哪种数据类型...。

*最后将其赋值给引用类型变量(把气球给孩子):stu = new Student();此时在内 存中把创建类的实例时分配到的内存地址(内存地址是一个编号不是二进制数)转化为二进制数,并将该二进制数存储到创建Student类引用类型变量stu时分配到的4个字节的内存空间里面(按高低原则)。完成引用类型变量的存储。

这样就可以解释两个不同的引用类型变量来引用同一个实例的情况(两个小朋友分别用自己的两根绳子牵着同一个气球),如下:

{

Student stu1;

Student stu2;

stu1=new Student();

Stu2=stu1;

}

④变量的默认值(局部变量(main函数外如类里面的变量)一旦创建后在内存块中全部刷为0);注意本地变量不能没有初始值(main函数里的变量),例如:

所谓的本地变量不能没有初始值,指的是不能没有初始值就被其他方法调用,如main函数中的如下语句:

Int x;

Console.WriteLind(x);

由于本地变量x没有初始值就被Console类的WriteLine方法调用了故会报错。

⑤常量(值不可改变的变量)

⑦局部变量是在Stack(栈)上分配内存的(其他一般在堆中分配)

⑥装箱与拆箱(Boxing&Unboxing)

补充说明:object是类可以派生出:数值类型和引用类型,但本身是类而类属于引用类型,所以object属于引用类型:内存空间存储被引用对象的地址。其定义为:

public class Object

{

public Object();

}

可见object一般当做引用类型使用。

*装箱:当引用变量引用栈上的数据的时候就要进行装箱,先把被引用的数据(下面指int x)拷贝一份,封装成一个实例,放在堆上的空闲内存中。

例如 {

int x=100;//注意局部变量是在栈上分配内存的

object obj;

obj=x;

}

为了使“个字节内存存的是地址,如果直接把数值型变量x内存里存的数据复制给obj的内存空间,则obj会把内存空间里的数据当做是地址,然后去引用该地址的数据,显然错误。

正确做法为:先在进制数在复制给在栈上obj的内存,这个过程使“obj=x;语句合法的内存操作”叫做装箱。

*即把栈上的值类型的数据封装成一个object类型的实例放在堆上叫做装箱

*拆箱:例如 {

int x=100;

object obj;

obj=x;

Int y=[int]obj;

}

为了使“ Int y=[int]obj;(在堆内把obj的数据取出来)”成立:先在栈内存中找到空闲的内存开辟一个4字节(因为y为int型)的存储空间存放数值类型变量y,然后将某块堆内存中存放的obj对象数据的按int32格式把数据(转换)复制到y变量的栈内存空间中。

*即把堆中obj实例里面的值按要求拆成目标数据类型存储到栈上y(目标数据类型)的内存空间中。

*装箱装地址,拆箱按要求拆出数据(如:int y=obj;则obj要按int32的格式拆出数据)

*装箱和拆箱会损失程序的性能,慎用。

C#详解类型,变量与对象的更多相关文章

  1. C# 数据类型详解以及变量、对象与内存

    学习刘铁猛老师<C#语言入门详解>视频,针对其中重点知识点进行总结. 1.什么是类型? 类型又称为数据类型(Data Type),数据类型在数据结构中的定义是一个值的集合以及定义在这个值集 ...

  2. 详解js变量、作用域及内存

    详解js变量.作用域及内存 来源:伯乐在线 作者:trigkit4       原文出处: trigkit4    基本类型值有:undefined,NUll,Boolean,Number和Strin ...

  3. LESS详解之变量(@)

    变量基本上是每个语言脚本上都会涉及的一个小小知识点,是学好语言脚本的必经之路.LESS中也可以设置变量,然后通过变量可以改变整个网站的设计风格.良好的掌握LESS中变量的用法,是LESS的基础. 变量 ...

  4. Java多态性详解——父类引用子类对象

    来源:http://blog.csdn.net/hikvision_java_gyh/article/details/8957456 面向对象编程有三个特征,即封装.继承和多态. 封装隐藏了类的内部实 ...

  5. 详解Python变量在内存中的存储

    这篇文章主要是对python中的数据进行认识,对于很多初学者来讲,其实数据的认识是最重要的,也是最容易出错的.本文结合数据与内存形态讲解python中的数据,内容包括: 引用与对象 可变数据类型与不可 ...

  6. foreach-- for循环的增强型:for(类型 变量 : 数组对象) { 使用变量 }

    /* * foreach:增强for循环,一般用于遍历集合或者数组 * 格式: * for(元素的类型 变量 : 集合或者数组对象) { * 可以直接使用变量; * } 注意:在增强for循环中不能修 ...

  7. 详解Go变量类型的内存布局

    定义 每当我们编写任何程序时,我们都需要在内存中存储一些数据/信息.数据存储在特定地址的存储器中.内存地址看起来像0xAFFFF(这是内存地址的十六进制表示). 现在,要访问数据,我们需要知道存储它的 ...

  8. 详解AJAX核心 —— XMLHttpRequest 对象 (下)

    继续上一篇的内容上一篇关于XMLHttpRequest 对象发送对服务器的请求只说到了用Get方式,没有说Post方式的.那是因为要说Post方式就需要先说另外一个东西,那就是DOM(Document ...

  9. Java多态性详解 (父类引用子类对象)

    面向对象编程有三个特征,即封装.继承和多态. 封装隐藏了类的内部实现机制,从而可以在不影响使用者的前提下改变类的内部结构,同时保护了数据. 继承是为了重用父类代码,同时为实现多态性作准备.那么什么是多 ...

随机推荐

  1. Basler acA2500-14gm 连接采图报错处理

    新购 Basler acA2500-14gm 相机,使用从官方网站下载的 pylon v6 版本连接测试,报错: Type    Time    Source    MessageError    2 ...

  2. FPGA、GPU、CPU三者各自的优缺点是什么呢?

    CPU: 英文全称:Central Processing Unit. 中文全称:中央处理器. 厂商:英特尔Intel. 功能:是一台计算机的运算核心和控制核心. 缺点:运算能力(最弱),核处理数(最少 ...

  3. .Net Core 添加 Swagger 支持

    1. NuGet  中添加 Swashbuckle.AspNetCore 2.添加 Startup 信息 将 Swagger 生成器添加到 Startup.ConfigureServices 方法中的 ...

  4. Android Studio [跑马灯]

    MainActivity package com.xdw.secondapp; import android.graphics.Paint; import android.support.v7.app ...

  5. Flume系列二之案例实战

    Flume案例实战 写在前面 通过前面一篇文章http://blog.csdn.net/liuge36/article/details/78589505的介绍我们已经知道flume到底是什么?flum ...

  6. 检查图片是否损坏、图片后缀是否与实际图片类型对应 - Python

    图片工具 检查图片是否损坏 日常工作中,时常会需要用到图片,有时候图片在下载.解压过程中会损坏,而如果一张一张点击来检查就太不Cool了,因此我想大家都需要一个检查脚本: 测试图片,0.jpg是正常的 ...

  7. 解决AndroidKiller APK 反编译失败,无法继续下一步源码反编译!

    报错背景 今天使用AndroidKiller V1.3.1,反编译一个APK,遇到如下报错: 当前 Apktool 使用版本:Android Killer Default APKTOOL 正在反编译 ...

  8. 将CDH中的hive和hbase相互整合使用

    一..hbase与hive的兼容版本: hive0.90与hbase0.92是兼容的,早期的hive版本与hbase0.89/0.90兼容,不需要自己编译. hive1.x与hbase0.98.x或则 ...

  9. 两种读取.xml文件的方法

    这里介绍两种读取配置文件(.xml)的方法:XmlDocument及Linq to xml 首先简单创建一个配置文件: <?xml version="1.0" encodin ...

  10. 快学Scala 第二十一课 (初始化trait的抽象字段)

    初始化trait的抽象字段: trait Logged { println("Logged constructor") def log(msg: String){ println( ...