C#学习笔记

C#基础入门

c#是什么?

c#是由微软公司在2006年发布的一种全新的简单的安全的面向对象高级编程语言

问题:c#能做什么?

c#可以做桌面应用开发服务器开发移动应用开发游戏开发人工智能开发各类工具开发; 目前应用最广泛的就是互联网系统和游戏。

初识

操作系统

操作系统(Operation System,OS)是指控制和管理整个计算机系统的硬件和软件资源 ,并合理的组织和调度及调度计算机的工作和资源分配,以提供给用户和其它软件方便的接口和环境。

常见的操作系统:windows、Linux、Mac OS X、android、ios

计算机的机器语言构成

0、1的指令集合

c#执行在计算机上的原理是什么

由高级语言,经过编译的过程翻译成计算机底层可以识别的0、1指令

程序如何与硬件交互

运行在操作系统之上,通过系统统一管理硬件资源

编程语言分类

  • 编译型语言:C++ / C

  • 解释型语言:JavaScript / Phthon / PHP

  • 半编译半解释型语言:Java / C#

CLR介绍

通用语言运行平台(Commom Language Runtime,简称CLR)是微软为他们的 .Net虚拟机 所选用的名称。这是通用语言架构 (简称CLI)的微软实现版本,它定义了一个代码运行环境

JIT -即时编译系统

  • 预先编译:提前把代码编译成机器码
  • 动态编译:对源代码一句一句,边翻译边运行

即时编译:运行时,一句一句边翻译边运行,如果翻译的代码属于*热点(HotPot)*那么就会进行缓存,本次运行过程中,如果再遇到本代码段,可以直接使用;直到程序退出。

所以兼容了二者的优点

.Net介绍

什么是.Net平台

.Net读作"dot net"

.Net平台是C#语言从编写到运行所依赖的环境 ,其上也构建多种多样的应用开发工具及类库 ;包括了一个虚拟运行时的CLR ,以及一系列的类库

C#基础语法

语句注释

语句:C#程序由一系列语句组成,一个语句就是一条指令,分好结尾;

  • 语句顺序执行
  • 语句每一条都会区分大小写

注释:注释(Comments)并不是一种C#代码,而是对代码的说明文字,方便自己或他人查看从而理解程序的含义

  • 单行注释://注释内容,只可写一行
  • 多行注释:/* */

字面量

字面量就是计算机程序用来处理数据,字面量规定了:数据在程序中的书写格式。

变量

变量是用来存储一个数据的内存区域 ,里面存储的数据可以变化

内存可以理解为一系列的空着的房间。

变量为什么需要类型

  • 任何一个程序中的变量,程序员都需要声明其变量的数据类型
  • 不同应用场景下,需要存储的空间大小不同,比如存储成绩(0-100)跟存储银行款(上万亿)。

变量定义格式

数据类型 变量名称 = 初始值;

c# 复制代码
    int score = 10;

变量的读和写

  • 从变量代表内存中,把数据取出来使用,叫做读取;
  • 把数值放进变量所代表的内存中,叫做写入;即改变了变量的值;

关键字、标识符

C#中,会保留一些单词作为特殊含义,拥有特殊功能,例如:int、double、float、public、class...

关键字不可作为变量的名称来使用;

什么是标识符

C#中,用于给变量、类、方法等用户自定义元素起名的符号串,即标识符;

变量命名规则

  • 变量名第一个字符必须是字母、下划线(_)或者@符号
  • 后续字符可以是字母/数字/下划线
  • 不可以使用C#内的关键字,比如int

变量命名指导规范

  • 尽量使用明确的单词或者单词缩写,建议全英文
  • 使用驼峰命名法

变量使用细节

  • 变量必须先声明再使用
  • 变量必须存储跟类型匹配的数据
  • 变量定义可以没有初始值,使用必须有初始值
  • 一条语句可以定义多个变量
  • 变量有效范围是从定义开始,一直到遇到一个"}"截止,同一个范围内变量名不可重复

进制与转换

什么是二进制

二进制数(binaries)是逢2进位的进位制,0、1是基本算符;

十进制:0 1 2 3 4 5 6 7 8 9(进位)10 11 ......

十进制转二进制算法

除二取余法

二进制转十进制算法

按位求幂相加

八进制

八进制数是逢8进位的进位制0-7是基本算符;

十六进制

C#中也可以使用十六进制对数据进行表达,逢16进位,所以需要16个 个位数字 表达方法。

0 1 2 3 4 5 6 7 8 9 A(10) B(11) C(12) D(13) E(14) F(15) 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F

C#中的进制表示

二进制:

c# 复制代码
int n1 = 0B101;

十六进制

c# 复制代码
int n2 = 0x1A;

八进制在c#中没有明确的表达方法

变量的基础原理

内存单位

  • 内存中可见的最小单位是bit(比特),表示0和1
  • 内存中用于存储数据的最小单位是8个bit,即1byte(字节)

变量内存分配案列

变量生成的时候,系统会分配给其一块大小合适的内存;

字符的表示

一个字符可以是普通的英文字母,一个汉字、一个符号,占有2byte的内存大小

字符的本质

自然语言可以理解'A',计算机只能看到2byte的数字

对于任何一个2byte的数字,如果是char则理解为字符,否则理解为数字;

建立某一个数字某一个字符 之间联系的方法,即为编码

UTF-16码表举例(十六进制)

数据类型

C#中将数据类型分为两类

  • 值类型
  • 引用类型

基础值类型

  • 整数
    • byte
    • short
    • int
    • long
  • 浮点数
    • float
    • double
  • 字符
    • chart
  • 布尔
    • bool

变量数值类型(整数)

数值类型选择,一般选int,int装不下选long。默认为int

s表示signed,即有符号;u表示unsigned,即无符号;

大空间变量,可以接受小空间变量的赋值,反之则不可

变量数值类型(浮点数)

变量数值类型(字符与布尔)

常量

什么是左值/右值

  • 左值:可放在等号左边 的存储单元,即用户可以读取 并可以改变其存储的值;
  • 右值:可以放在等号右边 的存储单元、字面量,即用户可以读取的存储的单元或者值

什么是常量

  • 常量包括字面量 以及常变量 ,程序执行期间不会改变,常量在语句中只能作为右值的存在,不能作为左值。
  • 常变量也是一种变量
    • 定义期间必须给定初始值,否则vs会报编译的语法错误
    • 定义后,只能读取访问,不能改变其值
  • 常变量定义使用关键字const,格式如下
    • const 变量类型 变量名 = 初始值;
常变量的作用
  • 可以作为字面量的载体,一次性修改多处数值
  • 防止定义初始值后,被其他程序员修改

整数二进制的存储原理

研究Byte类型

为什么一个byte类型的整数取值范围是0-255?

因为当8个bit都是1的时候,对应的是进制就是255;

那么,为什么一个sbyte类型的整数取值范围是-128-127呢?

此时就需要探究下整数在内存中导读如何存储为二进制!

二进制内存最高位1bit便是符号,其它位表示数值绝对值;

缺点:无法正确处理数据运算

方案三 补码

补码的优势

回顾问题:

sbyte的取值范围

检测Overflow

c# 复制代码
sbyte b  = 127
checked{
    b++;
}
//如果溢出,则vs会编译报错

浮点数二进制存储方法

浮点数

常用浮点数分为floatdouble ,二者都可以表达带有小数点的数字,分别占4字节8字节

问题:

  • 带小数的量为什么称为浮点数
  • 浮点数在内存中的二进制是如何存储的

小数二进制表达:乘二取整法

十进制消暑转二进制表示,采用乘二取整法

二进制小数转化为十进制

二进制小数转化为十进制表示,采用按位符术次幂,相乘再相加

浮点数十进制转二进制

  • 一个完整的浮点数:整数.小数,转化为二进制
    • 整数部分除二取余法得到二进制
    • 小数部分乘二取整法得到二进制
    • 整数在前,小数在后,用小数点相连

科学计数法(十进制)

科学记数法是一种数字的表示方法。把一个数表示成 x10的n次幂相乘的形式

二进制的科学计数法

二进制科学计数法是一种数字表示的方法。把一个数表示成 x(二进制)2的n次幂相乘的形式

浮点数的存储(float)

尾数规则

尾数必须以 1.xxx 的形式进行表示,即整数部分必须是1

指数规则

指数必须加上127 的偏移量(Bias),得到的数据转化为二进制,存储在指数区域;这种方式称为移码存储

为什么不用补码呢?主要是便于大小比较以及电路设计。

移码存储细节与对阶

对阶操作:对操作两个浮点数相加的时候,需要把二者的指数调节一致才能计算

对阶操作举例

注意

c#面向过程

运算符和表达式

  • 运算符:对字面量或者变量进行操作的符号
  • 表达式:用运算符把一个或者多个字面量或者变量 连接起来符合语法的式字即表达式
c# 复制代码
int a  =  10;

int b  = 20;

int c = a + b;
  • +:运算符
  • a+b:是表达式,且由于+表示的为算术运算符,所以称为算术表达式

运算符种类

  • 算术运算符
  • 位运算符
  • 赋值运算符
  • 逻辑运算符
  • 关系运算符

算术运算符

注意

  • 整数与整数操作,结果是整数
  • 整数与浮点数操作,结果是浮点数
  • 浮点数与浮点数操作,结果是浮点数

自增自减运算符

隐式类型转换

把一个取值范围小 的数值或者变量,赋值给另一个取值范围大的变量

隐式转化规则

  • 无符号 不能接纳有符号的数据
c# 复制代码
    sbyte b = 10;
    uint num = b; //报错
  • 数据之间的隐式转化关系如下

运算过程中隐式转换

  • 取值范围小的数据,与取值范围大的数据进行运算,小数据数据提升为大类型后,在进行运算;
  • byte short chart 三种数据在运算的时候,都会首先转化为int类型

显式类型转化

  • 把一个取值范围大 的数值或变量,赋值给另一个取值范围小的变量

不可直接赋值,需要强制类型转换

格式:目标数据类型 变量名 = (目标数据类型)需要转换的数据或者变量;

c# 复制代码
// long a = 10;

// int b = a;//报错 

// long a = 10;

// int b = (int)a;

float a = 10.1f;

int b = (int)a;//精度损失

数据截断与歧义

  • 如果大整数类型给到小整数类型,数据有可能被截断 或者歧义

显示类型转换-更灵活的版本

  • Convert 是C#提供的类(类似于console)。里面含有一系列类型转换的功能方法
    • 特点:任意数据类型 的值转换为任意数据类型
    • 数据类型无法转换时,会报错

位运算符

位运算(1bit)

  • 在计算机内部,每个数据都是0、1排列组成,本质存储二进制bit;按bit为进行的运算,称为位运算

  • & 与运算: 两者都为1,结果为1

  • | 或运算: 两者有一个为1,结果为1
  • ^ 异或运算: 二者不同结果为1
  • ~取反运算:0变1,1变0

真值表

位运算(整数)

  • 整数由多个bit组成,也可以进行按位运算

左移或右移位运算

  • 构成整数的bit们,可以集体向左或者向右移动
    • 左移n位,原来的数字需要乘以 2 的 n 次方
    • 右移n位,原来的数字需要乘以 2 的 -n 次方

练习

关系运算符与逻辑运算符

关系运算符

  • 关系运算符:用于判断两个数据之间的大/小/相等关系 的运算符。运算结果为bool类型,即true 或者false
  • c#的逻辑运算符无法赋值给整数,整数也无法复制给bool变量
c# 复制代码
int a = 10,b = 20;
bool flag1  = a > b;//false
bool flag2  = a < b; //true

关系运算符汇总表

三元运算符

语法格式:判断条件?条件1:条件2

  • 作用:

    • 计算判断条件的真假
    • 如果是真,则表达式结果为值1
    • 如果是假,则表达式结果为2

赋值运算符与sizeof

赋值操作用于给一个变量装入数值

其它运算符

运算符的优先级

优先级的概念

  • 在一个表达式中,存在多个运算符的时候,需要规定计算的先后顺序 ,即优先级

举例

c# 复制代码
int a = 1,b=2,c=3,d=4;
int r = a + b * c / d;
  • +-优先级相同
    • /优先级相同,且高于+ -
  • 优先级相同,从左到右
  • 自增自减(++/--),优先级高于四则运算

⚠️ 优先级并不是先运算,而是先结合为整体

关系逻辑运算符优先级

  • !> 算数运算符 > 关系运算符 > && > || > 赋值运算符

括号优先级

  • 在一个表达式中,如果有括号,先运算括号内的表达式

优先级表(部分)

⚠️ 如果害怕顺序出现问题,把需要进行的每一步运算都用括号包裹

变量键盘输入

变量输入输出

输入

c# 复制代码
Console.Read();    //读入一个字符,得到其Unicode值
Console.ReadLine();//读入一个字符串

举例

输出

c# 复制代码
Console.Write(); //输出字符
string a = "我";
string b = "你";
Console.WriteLine("{0}爱{1},a,b);//输出字符串 我爱你

语句 循环

if语句

格式

if(判断条件1){

语句代码;

}else if(判断条件2){

语句代码;

}else if(判断条件3){

语句代码;

}else if(判断条件4){

语句代码;

}

......

else{

语句代码;

}

switth语句

格式

switch(条件表达式){

case 值1: 语句代码; break;

case 值2: 语句代码; break;

case 值3: 语句代码; break;

......

default: 语句代码; break;

}

while 循环语句

格式

while(条件判断语句){

循环体语句;

条件控制语句;

}

概念:条件语句成立,则执行循环体语句

⚠️ 条件判断语句设为ture设置死循环

do while循环

格式

do{

循环体语句;

条件控制语句;

}while(条件判断语句)

概念:执行循环体语句,如果条件判断成立,则继续执行

while、do...while循环区别:

  • while循环不一定执行
  • do ... while循环至少执行一次

for 循环

格式:

for(初始化语句;条件判断语句;条件控制语句){

循环体语句

}

break 和 continue

break

  • break目前用于循环和switch语句中
  • break 只能结束当前所属语句范围(最内层循环,所在的swith)

continue

  • 强制结束本次循环,开始下一次循环

面向过程高级

方法的概念与格式

为什么需要方法?

如果逻辑代码变多,关系变复杂,一切都会很糟糕

概念

方法(函数):是一段具有独立功能的代码,可以被调取使用

优势

  • 可以对独立功能的代码进行统一管理,避免代码的臃肿
  • 统一代码不用重写,提高复用性

格式

c# 复制代码
public static void 方法名(){
    功能代码;
}

使用方法

方法名()

内存过程

从内存代码区,到栈内存,然后执行弹出的过程(先入后出)

⚠️ 变量在其定义的内存方法区内有效,运行完毕后内存会回收,变量的有效区称之为变量的作用域

方法的参数与返回值

形参

表示定义方法的时候,声明参数;如果不调用,则没有内存分配;

c# 复制代码
//st就是形参
public static viod Shout(string st){
     Console.WriteLine("老王林会~" + st);
}

实参

表示使用方法的时候,传入的参数

c# 复制代码
string st = "wangwang~"
Shout(st);
//此时的st为实参

返回值

定义方法

c# 复制代码
  public static int summation(int a,int b){
     return a+b
  }

调用方法

c# 复制代码
int sun   = summation(10,20);

方法的设计与使用细则

方法的统一设计格式

public static 数据类型 方法名(类型 变量1,类型 变量2, .....){}

方法的设计步骤

  • 明确方法功能,并起一个合适的名字
  • 明确方法是否需要返回值,返回怎样的结果
  • 明确方法是否需要参数,即用户传入什么
  • 设计方法功能代码

方法使用细则

  • 方法与方法之间为平级,禁止嵌套定义
  • 方法的定义位置顺序与执行顺序无关,按照调用顺序执行
  • void 返回类型的方法,也可用return语句结束当前方法,return后不加任何数据

返回值的其他用处

返回值可以作为函数运行成功与否的标志,比如bool类型,true表示运行成功,false表示运行失败

默认值参数

方法在定义时可以指定默认值,无需调用者提供

c# 复制代码
public static viod Shout(string st = "wangwang"){
     Console.WriteLine("老王林会~" + st);
}

当存在多个参数时,默认值必须从右到左给予

c# 复制代码
public static viod Shout(string st,string nt = " = "wangwang"){
     Console.WriteLine("老王林会~" + nt);
}

方法的重载

有时候我们会接到一些需求,例如:

  • 设计三个方法,分别实现下面需求:
    • 计算两个整数相加,求和返回
    • 计算两个浮点数相加,求和返回
    • 计算三个整数相加,求和返回
c# 复制代码
public static int add1(int a, int b) {
    return a + b;
}
public static double add2(double a, double b) {
    return a + b;
}
public static int add3(int a, int b, int c) {
    return a + b + c;
}

面对这样的需求,只是参数列表与返回值不同,但是需要多个不同的方法,显得特别乱,此时重载应运而生

方法重载(Overload)

  • 在同一个类中,定义多个同名方法 ,每个方法有不同的参数类型参数数量 ,成为方法的重载

  • 归纳总结

    • 同一个类,方法名相同,参数不同
    • 参数:个数、类型、顺序
    • 注意:是否重载跟返回值无关
c# 复制代码
//重写上面的需求,使用重载
public static int add(int a, int b) {
    return a + b;
}
public static double add(double a, double b) {
    return a + b;
}
public static int add(int a, int b, int c) {
    return a + b + c;
}

方法重载与隐式类型转换

  • 传入的参数,如果无法找到完全匹配的重载方法,则会尝试隐式类型转换

方法参数修饰符

需求

  • 希望传给方法的参数在方法的内部更改,并影响到实参

举例

c# 复制代码
int a = 3;
public static void doubleIt(int val){
   return val *= 2;
}

int b = doubleIt(a);//6

此时希望a也改变

未完待续......

相关推荐
指尖流烟1 小时前
C#调用图表的使用方法
开发语言·c#
friklogff3 小时前
【无标题】云端之C#:全面解析6种云服务提供商的SDK
开发语言·flask·c#
c#上位机4 小时前
C#事件的用法
java·javascript·c#
chnyi6_ya4 小时前
一些写leetcode的笔记
笔记·leetcode·c#
IT规划师4 小时前
C#|.net core 基础 - 扩展数组添加删除性能最好的方法
c#·.netcore·数组
时光追逐者5 小时前
分享6个.NET开源的AI和LLM相关项目框架
人工智能·microsoft·ai·c#·.net·.netcore
friklogff5 小时前
【C#生态园】提升C#开发效率:深入了解自然语言处理库与工具
开发语言·c#·区块链
__water14 小时前
『功能项目』回调函数处理死亡【54】
c#·回调函数·unity引擎
__water14 小时前
『功能项目』眩晕图标显示【52】
c#·unity引擎·动画事件
__water15 小时前
『功能项目』第二职业法师的平A【57】
c#·unity引擎·魔法球伤害传递