前两个月主要讲的是C#和算法基础,用的是unity自己开发K12教程。
个人觉得可以配合着我之前看的科技传播坊出的C#入门视频,和一本C#本质论能更深入的学习C#。
https://www.bilibili.com/video/av10011565/?spm_id_from=333.788.b_636f6d6d656e74.12
这里列出了现阶段学习的东西。
数据类型:好像就学了int 类型,float类型,char类型,bool类型和string类型。
int类型为32 位有符号整数,范围-2,147,483,648 到 2,147,483,647。
float类型为32位浮点数,用来保存实数。浮点数精度问题参看之前发的博文里浮点数那一节。
https://editor.csdn.net/md/?articleId=107444359
char类型为16 位 Unicode 字符。Unicode兼容ASCII码。
char类型的加法是Unicode码相加,输出一个int类型的数。
如:Console.WriteLine('a'+'b');//输出是195
string类型为字符串类型,相当于一串的char类型序列。可以通过数组索引的方式提取出字符串中单个字符。
bool类型只有true和false两种,代表真和假。
变量:出自于数学,例如在一个一元二次式中:x^2+bx+c=0,x就是变量。就相当于给某个数据取个名字,方便之后的操作。
变量的取名:必须以字母开头,后面可以跟任意字母,数字,下划线,不能重名,不能是关键字(如 int ,float之类),推荐驼峰命名法要求首单词的首字母小写,其余每个单词的首字母大写。注意C#分大小写,X不是x。
C#中变量的声明方法:
int x = 0;
表明变量的类型 变量名字 变量初始化(可之后进行)
var x=0;//var表明程序自动通过初始化的值自动推断变量x的类型。
数据的储存方式:分为值类型和引用类型。
值类型有int float char…
引用类型有 string ,数组,类…
数据储存在内存中,内存存在栈和堆两个区域。
则数据在内存的方式:
int a = 0;
int[] b={1,2,3};//int数组
int[] c=b;
int d=a;
显然引用类型不包含存储在变量中的实际数据,但它们包含对变量的引用(在堆上的地址)。所以一旦通过b改变了数据的值,c也会跟着改变。而改变d的值却不会改变a的。
注意:字符串虽为引用类型,但有个称为字符串不变性的特点。
string a = “123”;
string b=a;
b=”abc”;
Console.WriteLine(a);//输出仍为123
运算符
即+,-,*,/,%,–,++,=。
%为取余数 5%3是2
–,++为自减和自增,–1为0,++1为2。
注意:–和++的位置。
int a=2;
int b=a--;
Console.WriteLine(a);//a为1
Console.WriteLine(b);//b为2
int c=2;
int d=--c;
Console.WriteLine(c);//c为1
Console.WriteLine(d);//d为1
=为赋值符号 a=b;//读作将b的值赋给a
=,-=,+=复合赋值符号,即a=b;//就是a=a*b;
同数学里一样,运算符有优先级。括号优先级最大,赋值优先级最小
关系运算符 > ,< ,>= ,<= ,!=,==
运算结果为bool类型的数据,即式子成立为true,不成立为false。
逻辑运算符 && ||
注意:
(式子1)&&(式子2)可见一旦式子1为false就可判定整个为假,不会运行式子2。
int a=0;
if(a!=0&&a++==1){}
Console.WriteLine(a);//a为0,因为a++没运行
(式子1)||(式子2)可见一旦式子1为true就可判定整个为true,不会运行式子2。
int a=0;
if(a==0||a++==1){}
Console.WriteLine(a);//a为0,因为a++没运行
2. 分支结构:程序通过对一个条件判断为真或假而选择不同的语句执行。
在C#中的实现方式:
if(判断式)
{语句1}//判断式为真时运行语句1,否则跳过。
if(判断式)
{语句1}
else
{语句2}//判断式为真时运行语句1,否则运行语句2。
if(判断式1)
{语句1}//判断式1成立时,运行语句1
else if(判断式2)
{语句2}//判断式1不成立但判断式2成立时,运行语句2
else
{语句3}//判断式1不成立同时判断式2不成立时,运行语句3
循环语句
1)while循环
while(判断式)
//判断式为真时运行循环体,之后再判断判断式是否为真。为真接着循环,为假就跳出循环。
{
循环体
}
do
{
循环体
}
while(判断式);//先运行一次循环体,之后判断判断式为真的话接着循环,假的话就推出循环。
注意:显然do-while循环无论第一次判断式的真假,循环体总会运行一次。
for(语句1;判断式;语句2)
{
循环体
}//语句1只在一开始执行一次。
4)显然循环体内可以有另一个循环,即循环可以嵌套。
例如:
while(判断式1)
{
while(判断式2)
{
循环体
}
}
4) break和continue关键字。
在循环体里使用break;的话,一旦运行到这行就会跳出最近的一层循环。
在循环体里使用continue;的话,一旦运行到这行就会结束本次的循环,回到判断式那行直接进行下一次的循环。
是一个存储相同类型元素的固定大小的序列。
1)数组的声明:
int[] a=new int[6];//声明一个有6个元素的int类型的数组
int[] a={1,2,3,4,5,6};//声明一个数组的同时可以赋值。
int[] a=new int[6]{1,2,3,4,5,6};//声明一个6个元素数组,同时可以赋值。
int[] a=new int[]{1,2,3,4,5,6};//有赋值的话可以不标明数组大小。
同理,二维数组的声明:
int[,] a=new int[6,5];声明一个有6x5个元素的int类型数组。
Int[,] a={{1,2,3},{4,5,6}};//{1,2,3}为第一行,{4,5,6}为第二行
Int[,] a=new int[2,3]{{1,2,3},{4,5,6}};
Int[,] a=new int[]{{1,2,3},{4,5,6}};
2)数组元素的索引和遍历
可以用数组名+[整数]来访问数组中的元素。注意这个整数的范围为0~数组长度-1。
int[] a={1,2,3,4,5,6};
a[0]//值为1
a[5]//值为6
string类型也可以通过索引访问字符串内字符
string str="abc";
Console.WriteLine(str[1]);//输出b
可用for循环来遍历数组
for(int i=0;i<数组长度-1;i++)
{
a[i];//遍历a中的元素
}
也可以用foreach来遍历数组,遍历顺序是从0~数组长度-1。
foreach(int element in a)
{
element;//element为数组中的元素
}
foreach也可以遍历二维数组
Int[,] a=new int[]{{1,2,3},{4,5,6}};
foreach(int element in a)
{
Console.WriteLine(element);//element为迭代变量,代表每一个数组的元素
}
//输出是1,2,3,4,5,6
注意:foreach中无法改变迭代变量的值,即无法通过foreach修改数组里的元素。
foreach(int element in a)
{
element =1;//会直接报错
}
方法是将一系列执行一个任务的代码组织起来,作为一个整体来使用。例如一个段代码中要在代码各处中执行交换两个数据的值的任务。为了避免在代码中重复写交换的代码,可以将交换的代码拎出来作为一个方法,然后再代码各处调用这个方法就行。
方法的定义:
int Func(int a)//第一个int 为方法的返回值(即输出)的类型,没有输出的话用void
//Func为方法名,要求基本和变量命名一样,一般来说首字母大写
//括号里的int a为形式参数的类型和名字,即调用时输入的数据的要求和在方法内部该数据的名字。没有参数要输入的话就可以不写。
{
方法实现代码;
}
方法的调用:
int b=Func(1);//方法名+(),如果有要传进去的参数的话,就写在括号里。没有也要留着括号。
注意:值类型的参数和引用类型的参数
int a=1;
Func(a);
Console.WriteLine(a);
void Func(int data)
{
data=2;
}
程序输出依然是1,因为值类型的参数是相当于复制一份数据进入方法。若只是在方法里修改了参数的数据,是不会影响原来的数据的。
int[] a={1,2,3};
Func(a);
foreach(var data in a)
Console.WriteLine(data);
void Func(int[] data)
{
data[0]=2;
}
程序输出是2,2,3,因为引用类型的参数同样是复制了原来变量里的数据进去,但复制的是内存地址(因为引用类型本来保存的就是内存地址),而这个内存地址是指向原数据同一个区域的,所以修改有效。