C#详解类型,变量与对象
本节内容:
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#详解类型,变量与对象的更多相关文章
- C# 数据类型详解以及变量、对象与内存
学习刘铁猛老师<C#语言入门详解>视频,针对其中重点知识点进行总结. 1.什么是类型? 类型又称为数据类型(Data Type),数据类型在数据结构中的定义是一个值的集合以及定义在这个值集 ...
- 详解js变量、作用域及内存
详解js变量.作用域及内存 来源:伯乐在线 作者:trigkit4 原文出处: trigkit4 基本类型值有:undefined,NUll,Boolean,Number和Strin ...
- LESS详解之变量(@)
变量基本上是每个语言脚本上都会涉及的一个小小知识点,是学好语言脚本的必经之路.LESS中也可以设置变量,然后通过变量可以改变整个网站的设计风格.良好的掌握LESS中变量的用法,是LESS的基础. 变量 ...
- Java多态性详解——父类引用子类对象
来源:http://blog.csdn.net/hikvision_java_gyh/article/details/8957456 面向对象编程有三个特征,即封装.继承和多态. 封装隐藏了类的内部实 ...
- 详解Python变量在内存中的存储
这篇文章主要是对python中的数据进行认识,对于很多初学者来讲,其实数据的认识是最重要的,也是最容易出错的.本文结合数据与内存形态讲解python中的数据,内容包括: 引用与对象 可变数据类型与不可 ...
- foreach-- for循环的增强型:for(类型 变量 : 数组对象) { 使用变量 }
/* * foreach:增强for循环,一般用于遍历集合或者数组 * 格式: * for(元素的类型 变量 : 集合或者数组对象) { * 可以直接使用变量; * } 注意:在增强for循环中不能修 ...
- 详解Go变量类型的内存布局
定义 每当我们编写任何程序时,我们都需要在内存中存储一些数据/信息.数据存储在特定地址的存储器中.内存地址看起来像0xAFFFF(这是内存地址的十六进制表示). 现在,要访问数据,我们需要知道存储它的 ...
- 详解AJAX核心 —— XMLHttpRequest 对象 (下)
继续上一篇的内容上一篇关于XMLHttpRequest 对象发送对服务器的请求只说到了用Get方式,没有说Post方式的.那是因为要说Post方式就需要先说另外一个东西,那就是DOM(Document ...
- Java多态性详解 (父类引用子类对象)
面向对象编程有三个特征,即封装.继承和多态. 封装隐藏了类的内部实现机制,从而可以在不影响使用者的前提下改变类的内部结构,同时保护了数据. 继承是为了重用父类代码,同时为实现多态性作准备.那么什么是多 ...
随机推荐
- Basler acA2500-14gm 连接采图报错处理
新购 Basler acA2500-14gm 相机,使用从官方网站下载的 pylon v6 版本连接测试,报错: Type Time Source MessageError 2 ...
- FPGA、GPU、CPU三者各自的优缺点是什么呢?
CPU: 英文全称:Central Processing Unit. 中文全称:中央处理器. 厂商:英特尔Intel. 功能:是一台计算机的运算核心和控制核心. 缺点:运算能力(最弱),核处理数(最少 ...
- .Net Core 添加 Swagger 支持
1. NuGet 中添加 Swashbuckle.AspNetCore 2.添加 Startup 信息 将 Swagger 生成器添加到 Startup.ConfigureServices 方法中的 ...
- Android Studio [跑马灯]
MainActivity package com.xdw.secondapp; import android.graphics.Paint; import android.support.v7.app ...
- Flume系列二之案例实战
Flume案例实战 写在前面 通过前面一篇文章http://blog.csdn.net/liuge36/article/details/78589505的介绍我们已经知道flume到底是什么?flum ...
- 检查图片是否损坏、图片后缀是否与实际图片类型对应 - Python
图片工具 检查图片是否损坏 日常工作中,时常会需要用到图片,有时候图片在下载.解压过程中会损坏,而如果一张一张点击来检查就太不Cool了,因此我想大家都需要一个检查脚本: 测试图片,0.jpg是正常的 ...
- 解决AndroidKiller APK 反编译失败,无法继续下一步源码反编译!
报错背景 今天使用AndroidKiller V1.3.1,反编译一个APK,遇到如下报错: 当前 Apktool 使用版本:Android Killer Default APKTOOL 正在反编译 ...
- 将CDH中的hive和hbase相互整合使用
一..hbase与hive的兼容版本: hive0.90与hbase0.92是兼容的,早期的hive版本与hbase0.89/0.90兼容,不需要自己编译. hive1.x与hbase0.98.x或则 ...
- 两种读取.xml文件的方法
这里介绍两种读取配置文件(.xml)的方法:XmlDocument及Linq to xml 首先简单创建一个配置文件: <?xml version="1.0" encodin ...
- 快学Scala 第二十一课 (初始化trait的抽象字段)
初始化trait的抽象字段: trait Logged { println("Logged constructor") def log(msg: String){ println( ...