一、C#简介
在C#中,万物皆是类,决不允许有一个独立于类的函数或变量。
在使用任意一个对象前,必须申明这个对象的类型。
二、基础语法
1.数据类型转换
short x=10;
int y = x; //隐式转换
x = y; //错误,不能编译
x = (short y) //显式转换
隐式转换是自动进行的,short(2字节)转为int(4字节),这个转换不会丢失信息,而反方向转换需要显式转换,因为可能会丢失信息。
2.标识符
标识符以字母或下划线开头,并区分大小写。
3.变量和常量
变量声明:
int a; //声明a
int b = a; //错误,不能编译,因为a在使用前没有被赋值
float c = 0.0f; //c值为0
c = 50.1f; //c值为50.1
常量声明:
const float PI = 3.14f;
PI = 500; //改变常量的值,不能通过编译
声明一个常量只需要在类型前面增加关键字 const,并在声明时为其赋值即可。
4.枚举
enum FRUIT
{
Apple = 0,
Banana, //值为1
Cherry, //值为2
}
FRUIT fruit = FRUIT.Apple; //当前水果类型为苹果
也可以用常量代替枚举,但代码之间就缺少联系了。
const int Apple = 0;
const int Banana = 1;
const int Cherry = 2;
int fruit = Apple;
5.数学操作符
常用数学操纵符:+(加)-(减)*(乘)/(除)%(模/求余)
任何数与10进行模计算得到的余数即是这个数字的最后一位数,用这个方法可以通过模计算获得一个数字的任意一位数。
int number = 4321;
int v = 0;
v= number%10; //返回1
v= number/10%10; //返回2
v= number/100%10; //返回3
v= number/1000%10; //返回4
6.关系操作符
关系操作符包括==、!=、>、>=、<、<=,返回布尔值(true或者false)
7.逻辑操作符
包括&&(与)||(或)!(非)
8.方法
对普通语句,C#按顺序执行,但大部分情况,在程序中都需要执行分支语句和循环语句。
分支语句分为无条件分支和有条件分支。无条件分支通过调用方法(函数)实现。当程序遇到方法时,会先处理方法中的语句,然后按顺序调用其他语句。
float Sum(float a,float b)
{
return a+b;
}
//...
float number1 = 5;
float number2 = 10;
//语句3,限制性方法Sum内的语句,再返回赋值给number3
float number3 = Sum(number1,number2);
Console.WriteLine(number3); //输出number3,值为15
如果方法的参数是内置类型,则在方法内部引用的是参数的副本,方法内的运算不会影响到参数本身。如果希望在方法内部改变内置类型参数的值,则需要添加ref或out标识符。
//定义一个方法,参数前面添加ref标识符,表示引用变量本身,而不是创建一个副本
void Change(ref int a)
{
a += 10;
}
int a = 0;
Change(ref a);
Console.Write(a); //因为变量的参数采用了引用,a的值现在是10
将ref替换为out,区别是必须在方法内部先初始化变量再使用它。
8.递归
实际上递归就是一个循环的过程,尾递归就是一个普通的for循环。
若函数在尾位置调用自身(或是一个尾调用本身的其他函数等等),则称这种情况为尾递归。尾递归也是递归的一种特殊情形。尾递归是一种特殊的尾调用,即在尾部直接调用自身的递归函数。
static void Print(int n)
{
if(n == 0) //一定要有退出条件
{
Console.Write{"{0},",n};
return;
}
//Console.Write{"{0},",n}; //输出在前
Print(n - 1); //尾递归相当于for循环
//Console.Write{"{0},",n}; //输出在后
}
假设输入的参数n为10,如果输出在后,输出结果就是0,1,2,3…10,如果输出在前,结果就是10,9,8…0。
注意:递归与普通循环相比效率还是很低的,不适合在项目中盲目使用,但递归对某些问题求解的步骤更加简练,因此递归问题常出现在一些试题中。
9.条件分支语句
条件分支语句通过条件语句创建,会使用到if、else、switch等关键字。
- if语句:当表达式的值为true时,会执行if后面{}内的语句。
int a = 1,b = 2 ,c = 0;
//如果a大于b,c的值等于a,否则等于b
if(a>b)
c = a;
else
c = b;
- switch语句:作用与if语句相似,但可读性更强。
using System;
namespace ConsoleApplication1
{
class Program
{
//定义枚举
enum FRUID
{
Apple = 0,
Banana,
Cherry,
}
static FRUID fruid = FRUID.Apple
static void Main(String[] args)
{
switch(fruid)
{
case FRUID.Apple: //如果fruid的值等于FRUID.Apple
Console.WriteLine("apple");
break; //使用break退出
case FRUID.Banana:
Console.WriteLine("banana");
break;
case FRUID.Cherry:
Console.WriteLine("cherry");
break;
}
//以上switch语句等同于
if(fruid == FRUID.Apple)
Console.WriteLine("apple");
else if(fruid == FRUID.Banana)
Console.WriteLine("banana");
else if(fruid == FRUID.Cherry)
Console.WriteLine("cherry");
Console.ReadKey(); //按任意键退出
}
}
}
10.循环语句
- while是一个条件循环语句,每次循环都会返回一个逻辑表达式的值,只有表达式的值为false时才会退出while循环,因此在实际使用中要避免程序进入死循环。
int n = 0;
while(n<10)
{
n++;
}
- for语句与while类似,不同的是,for语句可以更方便的控制循环次数。
for(int i = 0;i<10;i++)
{
//循环10次
}
- 需要在循环中直接退出或不再执行剩下的语句继续下一个循环,可以使用break或continue改变循环状态。
int n = 10;
while(true)
{
if(n==5)
break; //使用break直接退出循环
n--;
}
for(int i = 0;i<10;i++)
{
if(i==5)
continue; //当i=5时,将跳过后面的代码直接到下一个循环
//其他语句
}
11.三元操作符
如果表达式的返回值为true,则执行表达式1,否则执行表达式2。
//条件表达式?表达式1:表达式2
int a = 50,b = 100;
int max = a > b? a : b; //选取a,b中的较大值
12.预处理
使用预处理,可以是程序编译或不变异某些代码,相比于C++,C#的预处理不支持宏,功能比较少。
使用预处理首先要使用关键字#define 定义一个预处理标识符,名称任意,但只影响当前的C#代码,它必须被定义到using语句之前,然后使用#if、#else、#endif等关键字处理判断预处理是否存在。
#define CLIENT //不需要分号结束,定义在using语句之前
using System;
namespace ConsoleApplication{
class Program
{
static void Main(string[] args)
{
#if SERVER
Console.WriteLine("Server"); //如果定义SERVER,编译这里
#elif CLIENT
Console.WriteLine("Client"); //如果定义CLIENT,编译这里
#else
Console.WriteLine("?"); //否则编译这里
#endif
}
}
}
定义全局的预处理,可以在C#控制台工程属性的 Build->Conditional Complication symbols中添加预处理名称。(Unity定义全局预处理的方式是不一样的)。