欢迎来到Cefler的博客
博客主页:那个传说中的man的主页
个人专栏:题目解析
推荐文章:题目大解析2
1.c#无指针操作符
2.c#无需手动释放内存,使用”引用计数“
技术自动释放内存
3.c#只允许单继承,无多继承
4.c#没有宏定义
5.c#完全面向对象
主要有四个部分组成
1.using System:可以理解为c语言中的头文件包含,相当于一个工具包(库),我们一下若使用些相关工具就得先引用它
2.namespace StudyNewLanguage:我们创建的空间,意义和上面的System一样
3.class Program:库中的类,c#中访问静态成员的语法是 类名.静态成员(c++中是类名::静态成员)
4. static void Main(string[] args):主函数,程序运行的入口。
主函数设置形式
值类型变量和引用类型变量区别
1.值类型变量保存的是具体的数据,而引用类型变量保存的数据地址
2.有空引用,无空值的说法
3.值类型变量存储在栈区当中,而引用类型变量存储在堆区当中
一、输入
1.Console.ReadLine():直到键盘读取到回车后停止读取
2.Console.Read():只读取一个
3. Console.ReadKey():当检测到有键盘输入时马上停止读取,即只读取一个按键
二、输出
折叠代码:为了让代码块整洁,区域块清晰
语法
#region
.
.
#endregion
c#中的基本数据类型,都间接或直接的继承Object,实现了c#完全面向对象
一、值类型
二、引用类型
枚举、结构体,类的定义区域:命名空间内
三、结构体引用
为什么有些变量前要加public?
字面意思:Public公用的,给其定义为公用的,该变量就可以在别的类中被使用,就比如我们常使用的类如console中的writeline等功能
比如这里我们就可以在Class1中引用结构体中obj2中的变量
c#中的结构体和c语言略有不同,{}后不用加;而且声明变量时,直接结构体名+变量名即可
四、Class引用
class声明的变量必须new一个才能引用,作法如下
class Obj3
{
public int a;
}
class Class1
{
static void Main()
{
Obj3 cl = new Obj3();//Obj3 cl相当于定义了一个指针
cl.a = 5;
}
}
一、有符号的整型变量
1.sbyte:-128~127
2.int:-21亿~21亿
3.short: -32768~32767
4.long:-900万兆~ 900万兆
二、无符号的整型变量
1.byte:0~255
2.unit:0~42亿
3.ushort:0~65535
4.ulong:0~18百万兆
三、浮点数
1.float:存储7/8位有效数字,声明时,要在后面加f,因为在c#当中,默认是double类型,所以要加f声明为float
2.double:存储15~17位有效数字
3.decimal:存储27~28位有效数字,声明时,要在后面加m
四、特殊类型
1.bool:true和false
2.char:存储单个字符
2.string:存储字符串,无上限
1.单引号:’
2.双引号:\“
3.换行:\n
4.斜杆:\
5.制表符:\t,就是空一个tab键(4个空格)
6.光标退格:\b,就是光标向前退一格
1.高精度转低精度自动转换,而低精度转高精度的则需要强转
2.结构体类型不允许与其它类型进行转换
3.枚举类型可以和int 进行相互转换(但需要强制转换)
使用情况:高精度转低精度
语法:变量类型 变量名 = (变量类型)变量
注意:精度问题,范围问题
作用:主要将字符串转换为对应类型
语法:变量类型.Parse(“字符字符串”)
注意:字符串必须能够转换为对应类型,且范围必须是变量能够存储的
作用:更准确的将各个类型进行转换
语法:Convert.To变量类型(变量/常量)
注意:变量和常量必须正确,必须能被所设置的接收变量所接收
该法比强转法好在精度好,会四舍五入
每个类型使用Convert法
作用:拼接打印
语法:变量.ToString()
语法:
语法:
1.string.Format(“待拼接的内容”,内容1,内容2,……)
2.想要被拼接的内容用占位符替代:数字0~n,依次往后
语法:
Console.WriteLine(“{0},{1},……”,内容1,内容2,……)
一、一维数组
数组命名语法:
1.类型[] 数组名 = {};这里数值自己给,无上限
2.类型[] 数组名 = new 类型[大小]{}; {}可有可无,但若是给了,其中的数据个数必须和数值大小一样
获取数组长度
语法:数组名.Length
二、二维数组
数组命名语法:
1.类型[,] 数组名 = {};
2.类型[,] 数组名 = new 类型[行,列]{};
语法:
1.string 变量名 = ”字符串“
2.string[] 变量名 =”字符串,字符串,字符串,……“ string 数组
Split看分隔符是什么
1.函数声明
语法格式:
Access_Specifier Return_Type FunctionName(Parameter List)
{
Function_Body
Return_Statement
}
其中,Access_Specifier 为访问权限修饰符;Return_Type 为返回值类型;FunctionName 为函数名称;Parameter List 为参数列表;Function_Body 为函数主体;Return_Statement 为返回语句,用来返回数据。另外需要注意的是,访问权限修饰符、参数列表和返回语句是可选的,可以省略。
2.函数调用
想要调用我们定义好的函数,首先需要将函数所在的类实例化为对象,然后通过对象.函数名()
的形式即可调用指定的函数,这里有几点需要注意:
提示:若调用同一个类中静态函数(使用 static 修饰的函数),则可以省略实例化对象的过程,直接使用
函数名()
的形式调用。
而若在其它类定义的函数想调用,所定义函数前得先声明为public即公用的。
如何实例化对象以及调用函数
using System;
namespace c.biancheng.net
{
class Demo
{
static void Main(string[] args){
Demo Obj = new Demo(); //实例化当前类的对象
//调用定义好的 Output 函数,将字符串传递给函数,并使用 msg 接收函数的返回值
string msg = Obj.Output("https://editor.csdn.net/md/?articleId=130901273");
Console.WriteLine(msg);
}
/*
* 定义一个函数,该函数可以接收一个字符串参数,
* 并返回一个字符串
*/
public string Output(string message){
string str = "欢迎访问:" + message;
return str;
}
}
}
类中的static函数(无需实例化为对象)
using System;
namespace c.biancheng.net
{
class Demo
{
static void Main(string[] args){
string msg = Output("https://editor.csdn.net/md/?articleId=130901273"); // 调用类中的静态函数
Console.WriteLine(msg);
}
/*
* 定义一个函数,该函数可以接收一个字符串参数,
* 并返回一个字符串
*/
static string Output(string message){
string str = "欢迎访问:" + message;
return str;
}
}
}
传值无法修改实参,传址可以修改实参
class 的类名是指针(即地址)
namespace StudyNewLanguage
{
class Student
{
public int score;
}
class Fun
{
public static void Swap(int a,int b)//在同一个类中,static可以直接函数名访问,无需实例化对象
{
int tmp = a;
a = b;
b = tmp;
}
public static void ChangeNum(Student stu)
{
stu.score = 80;
}
static void Main()
{
int x = 20, y = 30;
Swap(x, y);//传值操作无法改变实参
Console.WriteLine("x={0},y={1}", x, y);
Student stu = new Student();//class类,创建变量必须实例化对象
stu.score = 90;
ChangeNum(stu);//这里传的是指针
Console.WriteLine(stu.score);
}
}
}
引用类型传递:传递的是数据地址。类、数组、接口、string
那么值类型传递如何修改数据呢?
法一:使用ref关键字
1.定义函数时,使用ref修饰变量,代表引用类型传递
2.调用函数时,使用ref修饰实参
注意!:实参必须初始化
法二:使用out关键字
1.定义函数时,使用out修饰变量,代表引用类型传递
2.调用函数时,使用out修饰实参
注意!:实参可以不初始化,但是函数体必须对实参进行赋值操作 ,即改变
c#完全面向对象,所有的类型,间接或直接继承了Object类
装箱:
将其它类型转化为Object类型
拆箱:
将Object类型转化为其它数据类型
在程序开发中避免拆装箱,防止不必要的损耗
int a = 24;
Object obj = (object)a ;//装
int b = (int)obj;//拆
Console.WriteLine(b);
注意事项:
1.子类转父类(自动转换)
2.父类转子类(强制转换)
准确来说应该是子类赋值给父类无需强转,父类赋值给子类需要强转
进行赋值的前提二者类型得要相同,所以要么提前将类型转换,要么强制类型转换
Son1 s1 = new Son1();//引用类型创建变量先实例化对象
Farther f1 = s1;//这里直接将子类赋值给父类
#endregion
#region 父类转子类-强转
Farther f2 = new Farther();
s1 = (Son1)f2;//此时转换不安全,因为s1为空指针,s1不指向Son1,会转换不成功
用于判断一个类型是否是某个类型
用于引用类型转换,转换成功返回值为非空,失败则为空
Farther f2 = new Farther();
Son1 s3 = new Son1();
if(f2 is Son1)
{
s3 = f2 as Son1;
Console.WriteLine("一步到位");
}
else
{
s3 = f2 as Son1;//转换失败为空,此时f2的类型不为Son1,所以转换肯定失败
Console.WriteLine(s3 == null);
f2 = new Son1();//必须实例化对象后,此时f2类型才为Son1,才能使用as
Console.WriteLine("二步到位");
}
s3 = f2 as Son1;
总结:
1.子类赋值给父类什么都不用担心,因为自动赋值
2.父类赋值给子类,有强制类型转换和as关键字两种方法,但是前提是父类得提前 new 子类类型()实例化对象才行
Farther f2 = new Farther();
Son1 s3 = new Son1();
f2 = new Son1();
s3 = (Son1)f2;//强制类型转换也行
class 子类:父亲
{
}
没有多继承,一个类只能继承一个父亲(单继承)
一个类可以派生出多个类,但只有一个父亲
构造函数
构造函数相关概念可参考:C#中构造函数的定义以及特点和作用(详细解释)
知识点1:派生类构造函数需要调用基类构造函数,当基类有无参构造函数时,可以省略调用否则显示调用
知识点2:静态成员不能访问非静态成员;静态成员函数没有this引用
知识点3:this只引用当前调用者对象,存在于类的非静态成员函数中,只读不改
知识点4:base代表基类,用于调用基类构造或成员函数
如上便是本期的所有内容了,如果喜欢并觉得有帮助的话,希望可以博个点赞+收藏+关注❤️ ,学海无涯苦作舟,愿与君一起共勉成长