C#学习 - 类型、变量、方法

类型(Type)

又称为数据类型(Data Type)
数据类型是数据在内存中存储时的“型号”
小内存容纳大尺寸数据会丢失精确度、发生错误
大内存容纳小尺寸数据会导致浪费
编程语言的数据类型与数学中的数据类型不完全相同
编程时数据受到数据类型的约束 - 强类型编程语言
编程时数据受到的数据类型的约束并不严格或数据不受数据类型的约束 - 弱类型编程语言
强类型(C#):

int x;//一个32bit位变量
x = 100L;//存放64bit位的数据时出错
bool y;
y = 100;//bool类型的变量无法存放整型数据
if (x = 200)
{	//C#语言规定if后是一个bool运算,不能是赋值,这里会报错Console.WriteLine(x);
}

弱类型(C):

int x = 100;
if (x = 200)
{	//C语言中的bool只有0和非0,所以if后可以接赋值printf(x);
}

C#模仿弱类型:

dynamic x = 100;
Console.WriteLine(x);
x = "Hello,world!";
Console.WriteLine(x);
//dynamic是动态类型

类型所包含的信息

存储此类型变量所需要的内存空间大小
此类型的值所能表示的值的范围
此类型所包含的成员(如属性、方法、事件等)
此类型由何基类派生而来
程序运行时,此类型的变量分配在内存中的位置(会把内存分为栈区和堆区)
此类型所允许的操作(运算)

栈(Stack)

用于方法调用
栈区比较小,速度比较快
程序代码出错时,在栈上使用了过多的内存时,就会造成栈溢出(Stack overflow)

namespace ConsoleApp1
{internal class Program{static void Main(string[] args){StackOverflow so = new StackOverflow();so.Method();}}class StackOverflow{public void Method(){this.Method();//一直在递归调用方法消耗栈区内存}}
}

上段代码会出现“Process is terminated due to StackOverflowException.”,就是StackOverflow错误

堆(Heap)

用来存储对象
堆区比较大
在堆区各处上分配对象内存后,之后没有回收内存时,就是造成了内存泄漏
C#中有垃圾收集器,发现内存没有使用时会自动回收

using System.Collections.Generic;
using System.Windows;namespace WpfApp
{public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}List<Window> winList;private void Button1_Click(object sender, RoutedEventArgs e){ //第一个按钮点击后增加堆区内存占用winList = new List<Window>();for (int i = 0; i < 10000; i++){Window w = new Window();winList.Add(w);}}private void Button2_Click(object sender, RoutedEventArgs e){ //第二个按钮点击后将 Window 实例变成“垃圾”//C# 中的垃圾收集器会在一个合适的时机将这些内存回收winList.Clear();}}
}

进程(Process)

一个程序从硬盘加载到内存中开始运行时就会有一个进程
Win + R 调出运行窗口,输入 perfmon 就能打开性能监视器,可以进行监视软件占用内存
上段代码中程序名为WpfApp,运行时进程名字也叫WpfApp
在性能监视器中选择监视工具 - 性能监视器 - Ctrl+N添加
上面选择Process - Private Bytes
下面选择WpfApp(进程名)
添加后在最下方选择只显示WpfApp,双击WpfApp,选择图表,更改垂直比例可以观察更多
点击第一个按钮就能消耗内存,红线上升;点第二个按钮,在一个合适的时候垃圾收集器就能回收内存呢,红线下降

类型系统

C#五大数据类型:类(Classes)、结构体(Structures)、枚举(Enumerations)、接口(Interfaces)、委托(Delegates)
其中类、接口、委托是引用类型(Reference Type);结构体和枚举是值类型(Value Type)
鼠标对准数据类型右键 - 转到定义,在数据类型前就写有其自身的类型
注:class、struc、enum、interface、delegate不是具体的数据类型,而是用来定义自己的数据类型

变量

变量是以变量名所对应的内存地址为起点、以其数据类型所要求的存储空间为长度的一块内存区域
变量名表示变量的值在内存中的存储位置,并且每个变量都有一个类型,用来决定存入变量的值的类型
变量分为静态变量、实例变量(成员变量、字段)、数组元素、值参数、引用参数、输出形参、局部变量
一般来说,变量只指局部变量
局部变量就是方法体里声明的变量

internal class Program{static void Main(string[] args){Tool.Wrench = "Wrench";//静态变量Tool tool = new Tool();tool.ID = 1;//字段int[] arr = new int[10];//arr就是数组,类型后接[]就是声明数组,arr[0]是第一个元素int x = 10;//局部变量,在 Main(方法体)中声明的}}class Tool{public static string Wrench;public int ID;public double Add(double a,double b)//这里 a 和 b 就是值参数变量{   //在参数前用 ref 修饰就是引用参数变量;用 out 修饰就是输出参数变量return a + b;}}

变量的声明

int a;//这就是声明变量
//此处声明了一个整型变量

需要先声明变量才能使用
格式:有效的修饰符组合(可省略) + 变量类型 + 变量名 + 初始化器(可省略)

public static/*有效的修饰符组合*/ string/*变量类型*/ Wrench/*变量名*/ = "Wrench"/*初始化器*/;

值类型的变量存储

byte a = 100;
//byte类型占用8bit,就是占用一个字节
//100的二进制是 110 0100,只有7位,少的一位用0补齐,就是 0110 0100
sbyte b = 100;
//sbyte占用8个bit,但最高位为符号位(0为正数,1为负数),就只有7位进行存储
//所以存储后是 0110 0100
//如果是 -100,就先以100按位取反再+1,0110 0100 -> 1001 1011 +1 = 1001 1100

其余都类似
值类型没有实例,所谓的“实例”与变量合而为一

引用类型的变量与实例的关系

internal class Program{static void Main(string[] args){Human human;human = new Human();//创建一个Human的实例,再将地址保存在变量human中Human human2;human2 = human}}class Human{uint ID;byte Age;}

上段代码中Human的实例 一共有 32+8bit空间,就是一个 ulong 和一个 byte 的空间,然后将存入内存中的第一个字节的地址转换为二进制,这个二进制存入变量human中,比如:
实例存入内存中的3000 0001到3000 0005(此处为十进制,为了方便计算),第一个地址是3000 0001,转换为二进制就是1 1100 1001 1100 0011 1000 0001,分为4个字节,如果不足用0补齐(0补在最高位),这些数据存入变量human中就是:0000 0001 | 1100 1001 | 1100 0011 | 1000 0001,地址中存放顺序是从后到前。而因为human2 = human,所以变量human2存放的也是Human的实例的地址

注意

  • 局部变量实在Stack(栈区)上分配内存
  • 成员变量在声明后会有一个默认值,变量分配在内存中时,默认内存中全部存放 0。本地变量没有默认值,不赋值无法编译,如:
int x;
Console.WriteLine(x);
//此段代码会报错
  • 常量无法更改数值,声明常量时还必须带有初始化器
 const int x = 100;x = 200;//x因为是常量,代码报错
  • 装箱与拆箱(Boxing & Unboxing),如:
int x = 100;
object obj = x;//装箱
//装箱将值类型转换为引用类型
//变量 x 存放100的二进制形式
//如果发现变量 obj 不是堆区上的实例,而是栈区上的值类型的值时
//会先将变量 x 存放的数据复制一份到堆区上
//再将复制的数据占用的第一个地址转换为二进制存放在变量 obj 中int y = (int)obj;//拆箱
//现在栈区中找一块内存作为变量 y
//再将 obj 存放的地址所指向的堆区上的数据复制到变量 y 中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/76370.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nuxt3项目使用pdfjs-dist预览pdf

使用的包的源代码是 pdfjs - npm 但是我们实际上项目中使用的是pdfjs打包后的dist文件&#xff0c;也就是pdfjs-dist - npm 所以我们需要使用这个命令 npm i pdfjs-dist 我们可以克隆pdfjs这个包来看源代码&#xff0c;里面有使用的例子&#xff0c;也可以根据源代码自己打…

康冠2024届秋招校招面试软件开发岗问的问题

1.自我介绍 2.谈谈你的技术栈 3.我主要使用C#因此面试官问我了解Java怎么样 4.聊项目&#xff0c;例如开发过程中的问题 5.制作完项目的感受 6.为什么你会使用这些技术栈做项目 7.是否会把老项目翻盘重做 8.考公还是考研 9.期待的工作地点

bert ranking pairwise demo

下面是用bert 训练pairwise rank 的 demo import torch from torch.utils.data import DataLoader, Dataset from transformers import BertModel, BertTokenizer from sklearn.metrics import pairwise_distances_argmin_minclass PairwiseRankingDataset(Dataset):def __ini…

ClickHouse进阶(十三):Clickhouse数据字典-3-文件数据源及Mysql数据源

进入正文前&#xff0c;感谢宝子们订阅专题、点赞、评论、收藏&#xff01;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; &#x1f3e1;个人主页&#xff1a;含各种IT体系技术,IT贫道_大数据OLAP体系技术栈,Apache Doris,Kerberos安全认证-CSDN博客 &#x1f4cc;订阅…

鸿蒙应用程序入口UIAbility详解

一、UIAbility概述 UIAbility是一种包含用户界面的应用组件&#xff0c;主要用于和用户进行交互。UIAbility也是系统调度的单元&#xff0c;为应用提供窗口在其中绘制界面。每一个UIAbility实例&#xff0c;都对应于一个最近任务列表中的任务。一个应用可以有一个UIAbility&am…

LVS + Keepalived群集

文章目录 1. Keepalived工具概述1.1 什么是Keepalived1.2 工作原理1.3 Keepailved实现原理1.4 Keepalived体系主要模块及其作用1.5 keepalived的抢占与非抢占模式 2. 脑裂现象 &#xff08;拓展&#xff09;2.1 什么是脑裂2.2 脑裂的产生原因2.3 如何解决脑裂2.4 如何预防脑裂 …

介绍PHP

PHP是一种流行的服务器端编程语言&#xff0c;用于开发Web应用程序。它是一种开源的编程语言&#xff0c;具有易学易用的语法和强大的功能。PHP支持在服务器上运行的动态网页和Web应用程序的快速开发。 PHP可以与HTML标记语言结合使用&#xff0c;从而能够生成动态的Web页面&a…

关于前端就业前景的一点看法

一、前言 最近&#xff0c;很多人在知乎上鼓吹前端未来会没掉的概念。在此我想说这个说法并不真实&#xff0c;而是一种极端的观点。 事实上&#xff0c;前端开发在当今的互联网行业中扮演着至关重要的角色&#xff0c;它是构建 Web 应用程序所必需的一部分&#xff0c;能够实现…

项目中应该使用nginx还是拦截器来封禁IP

项目中应该使用nginx还是拦截器来封禁IP 在项目中&#xff0c;使用 Nginx 或拦截器&#xff08;例如 Spring Interceptor&#xff09;来封禁 IP 地址都是可行的方法&#xff0c;具体选择取决于你的需求和项目架构。 Nginx 是一种高性能的 Web 服务器和反向代理服务器&#xf…

小白学go基础04-命名惯例对标识符进行命名

计算机科学中只有两件难事&#xff1a;缓存失效和命名。 命名是编程语言的要求&#xff0c;但是好的命名却是为了提高程序的可读性和可维护性。好的命名是什么样子的呢&#xff1f;Go语言的贡献者和布道师Dave Cheney给出了一个说法&#xff1a;“一个好笑话&#xff0c;如果你…

如何使用命令行参数?

使用命令行参数是C语言编程中非常常见和有用的技巧。命令行参数允许您在运行程序时向程序传递信息&#xff0c;这样程序可以根据不同的输入执行不同的操作。在本文中&#xff0c;我们将详细讨论如何在C语言中使用命令行参数&#xff0c;包括如何访问和解析命令行参数、处理不同…

TSINGSEE青犀AI视频分析/边缘计算/AI算法·人脸识别功能——多场景高效运用

旭帆科技AI智能分析网关可提供海量算法供应&#xff0c;涵盖目标监测、分析、抓拍、动作分析、AI识别等&#xff0c;可应用于各行各业的视觉场景中。同时针对小众化场景可快速定制AI算法&#xff0c;主动适配大厂近百款芯片&#xff0c;打通云/边/端灵活部署&#xff0c;算法一…

前端中的事件委托

前端小知识 事 件 委 托 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/132819265 【介绍】&#xff1…

目标检测YOLO实战应用案例100讲-森林野火预警的小目标检测(续)

目录 3.2 实验数据评价指标 3.3 YOLO算法 3.3.1 YOLO算法原理 3.3.2 YOLO v5 网络模型

VM安装RedHat7虚机ens33网络不显示IP问题解决

1、今天在VMware中安装RedHat7.4虚拟机&#xff0c;网络连接使用的是 NAT 连接方式&#xff0c;刚开始安装成功之后输入ifconfig 还能看到ens33自动分配的IP地址&#xff0c;但是当虚机关机重启后&#xff0c;再查看IP发现原来的ens33网络已经没有了&#xff0c;只变成了这两个…

XML格式转JSON格式

前言&#xff1a; XML和JSON是两种常见的数据交换格式&#xff0c;它们在现代软件开发中扮演着重要的角色。本文将介绍这两种格式的基本概念、特点以及它们的使用场景&#xff0c;以帮助更好地理解和应用它们。 XML&#xff08;可扩展标记语言&#xff09;和JSON&#xff08;Ja…

Mybatis -- 读取 DATE 类型字段时可能遇到的问题(夏令时问题)

在使用 MYBATIS 读取数据库字段的时候&#xff0c;我们一般需要为查询字段指定数据类型。特别是当我们使用 mybatis generator 去生成对应的接口代码时&#xff0c;会自动按照数据库字段类型生成响应映射规则的代码。   如下&#xff0c;左侧是 date 类型生成的字段映射规则&…

MySQL数据库——存储引擎(2)-存储引擎特点(InnoDB、MyISAM、Memory)、存储引擎选择

目录 存储引擎特点 InnoDB 介绍 特点 文件 逻辑存储结构 MyISAM 介绍 特点 文件 Memory 介绍 特点 文件 区别及特点 存储引擎选择 存储引擎特点 上面我们介绍了什么是存储引擎&#xff0c;以及如何在建表时如何指定存储引擎&#xff0c;接下来我们就来介绍比较…

JS中 bind()的用法,call(),apply(),bind()异同点及使用,如何手写一个bind()

✨什么是bind() bind()的MDN地址 bind() 方法创建一个新函数&#xff0c;当调用该新函数时&#xff0c;它会调用原始函数并将其 this 关键字设置为给定的值&#xff0c;同时&#xff0c;还可以传入一系列指定的参数&#xff0c;这些参数会插入到调用新函数时传入的参数的前面。…

Map集合

Map中常见的API Map<键值对类型&#xff0c; 键值对对象类型> put&#xff08;K key , V value&#xff09;【可以有返回值】 添加/覆盖元素 在添加数据的时候&#xff0c;如果键不存在&#xff0c;那么直接将键对对象添加到map集合当中 在添加数据的时候&#xff0c…