语法基础
01.cs文件结构
程序的第一行 using System: -using 关键字用于在程序中包含 System 命名空间。一个程序一般有多个 using 语句。
下一行是 namespace 声明。一个namespace 是一系列的类。WebApplication1 命名空间包含了类的Program。
下一行是class声明。类Program包含了程序使用的数据和方法声明。类一般包含多个方法。方法定义了类的行为。在这里,Program类只有一个 Main 方法。
下一行定义了 Main 方法,是所有C#程序的入口点。Main方法说明当执行时 类将做什么动作。
Main方法通过方法体中的语句指定它的行为。
以下几点值得注意:
一个cs文件的结构大约是由以上几个部分组成,但是根据不同的需求和作用,会有不同的内容;
程序的执行从 Main 方法开始的。
02.C#基本语法
注意:
C#是大小敏感的。
所有的语句和表达式必须是以分号(;)结尾。
与 Java 不同的是,文件名可以不同于类的名称。
-
C#是一种面向对象的编程语言。在面向对象的程序设计方法中,程序由各种对象组成。相同种类的对象通常具有相同的类型。
案例:
以人类为例,从人类中诞生出的具体对象“C罗”和梅西“,同类人类,故两个人的类型相同。
2.1关键字
关键字,是对编译器有 特殊意义 的 预定义保留标识符,它们 不能 在程序中用作标识符
-
using 关键字
在任何 C# 程序中的第一条语句都是:
using System;
using 关键字用于在程序中包含命名空间。一个程序可以包含多个 using 语句。
-
class 关键字
class 关键字用于声明一个类。
2.2注释
-
C#的注释方式
/*这个程序演示
C#语言的多行注释
语法*/
单行注释是用 ‘//’ 符号表示。例如:
//这是C#语言的单行注释方法
文档注释用 ‘///’ 符号表示。例如
/// <summary>
/// 这是主程序入口
/// </summary>
/// <param name="args">需要传入的参数</param>
public static void Main(string[] args)
{
}
注释的作用:
解释:说明代码作用
注销:将暂时不需要的代码注销
铭记:
1.不写注释是流氓
2.名字瞎起是扯淡
3.相比注销,注释意义更大
4.要做到别人一看就能看懂
2.3变量
-
变量是一个供程序存储数据盒子。在C#中,每个变量都有一个特定的类型,不同类型的变量其内存大小也不尽相同。
C# 中提供的基本类型大致可以分为以下几类:
类型 | 举例 |
---|---|
整数类型 | byte、short、int、long |
浮点型 | float和double |
十进制类型 | decimal |
布尔类型 | bool |
字符类型 | string、char |
空类型 | null |
语法进阶
01.表达式
-
表达式由操作数(operand)和运算符(operator)构成。运算符的实例包括 +、-、*、/ 和 new 。操作数的示例包括文本、字段、局部变量和表达式。
-
当表达式包含多个运算符时,运算符的优先级(precedence)控制各运算符的计算顺序。例如,表达式 x + y * z 按 x + ( y * z ) 计算,因为*的运算符优先级高于+的运算符。
-
(了解)大多数运算符都可以重载(overload)。运算符重载允许指定用户定义的运算符实现来执行运算,这些计算的操作数中至少有一个,甚至所有操作数都属于用户定义的类类型和结构类型。
-
下表总结了C#简单常用的运算符,并按优先级从高到低的顺序列出各运算符类别。同一类别中的运算符优先级相同。
类别 | 表达式 | 说明 |
---|---|---|
基本 | x.m | 成员访问 |
x(...) | 方法和委托调用 | |
x[...] | 数组和索引器访问 | |
new T(...) | 对象和委托创建 | |
new T(...){...} | 使用初始值设定项创建对象 | |
new{...} | 匿名对象初始值设定项 | |
new T[...] | 数组创建 | |
一元 | +x | 恒等 |
-x | 求相反数 | |
!x | 逻辑求反 | |
~x | 按位求反 | |
++x | 前增量 | |
--x | 前减量 | |
x++ | 后增量 | |
x-- | 后减量 | |
T(X) | 将 x 显式转换为类型 T | |
二元 | x * y | 乘法 |
x / y | 除法 | |
x % y | 求余 | |
x + y | 加法、字符串串联 | |
x - y | 减法 | |
x << y | 位左移 | |
x >> y | 位右移 | |
x > y | 大于 | |
x < y | 小于 | |
x <= y | 小于或等于 | |
x >= y | 大于或等于 | |
x is T | 如果 x 为 T,则返回 true,否则返回 false | |
X as T | 返回转换为类型 T 的 x,如果 x 不是 T 则返回 null | |
x == y | 等于 | |
x != y | 不等于 | |
x & y | 整形按位 AND,布尔逻辑 AND | |
x | y | |
x && y | 仅当 x 为 true 时,才对 y 求值 | |
**x | ||
x ?? y | 如果 x 为 null ,则计算结果为 y ,否则计算结果为 x | |
三元 | x ? y : z | 如果 x 为 true ,则对 y 求值;如果 x 为 false,则对 z 求值 |
赋值或匿名函数 | x = y | 赋值 |
x = x + y | 复合赋值 | |
(T x) => y | 匿名函数(lambda表达式) |
02.分支语句
作用域:当前这个东西能做用到哪些范围。
if语句
if(i>1){
}
if-else语句
//如果
if(i>1){
...
}
else{
...
}
if(i >= 10){
...
}
else if(i > 0 && i < 10){
...
}
else{
...
}
switch语句
switch(i){
case 1:
...
break;
case 2:
...
break;
case 3:
...
break;
default:
...
break;
}
03.循环语句
for循环(知道循环次数)
for(int i = 0; i<10; i++)
{
...
}
while循环(不知道要循环多少次,直到满足要跳出循环的条件为止)
while(i<10)
{
...
}
do-while循环(至少执行一次)
do{
...
}
while(i<10)
{
...
}
//break;直接跳出循环 //continue;跳过当前循环中的剩余代码,继续下一次循环的执行
04.数组
-
数组是一组相同类型的数据。
-
数组中的数据需要通过数字索引来访问。
4.1数组的声明
-
数组的声明需要使用 new 关键字。
-
在声明数组时,可以使用 {} 来初始化数组中的元素。
-
如果在数组声明之初没有使用大括号来初始化数组中的元素,则需要指定数组的大小。
-
在声明初始化有元素的数组时,也可以指定数组的大小。
//声明没有元素的数组
int[] ints = new int[6]
//声明初始化有元素的数组
int[] ints = new int[]{1,3,5,6}
//在声明初始化有元素的数组时,也可以指定数组的大小
string[] strings = new string[5]{"H","E","L","L","O"}
更简单的声明方式
int[] str3 = { 1, 2, 3, 4 };
4.2通过索引获取数组中的元素
-
给数组指定长度时,数组准备存放多少元素,长度就设置为多少。
-
用索引获取数组内的元素时,索引从0开始获取。
-
所以数组中最大的索引数字,比指定数组长度小1。
//声明初始化有元素的数组
int[] ints = new int[]{1,3,5,6}
//获取数组中第1个的元素
int i1 = ints[0];
//给数组内的元素赋值
ints[0] = 1
05.总结提升
案例一:买西瓜
-
西瓜单价1.9元/斤
-
买了6斤
-
满10元优惠7.5折
-
问:买西瓜花了多少钱?
int count = 6;
double price = 1.9;
double discount = 0.75;
double totalPrice = 0;
totalPrice = price * count;
if (totalPrice >= 10)
{
totalPrice *= discount;
}
MessageBox.Show($"最后付了{totalPrice}元");
思考
-
以上案例需要设置几个变量?
-
需要声明何种类型的变量?
-
如果题中要求满几个10元,就在几个10元上打7.5折应如何计算?
//西瓜单价1.9元/斤,满10个打75折
int count = 36;
double price = 1.9;
double discount = 0.75;
double totalPrice = 0;
//总价=单价*个数
totalPrice = price * count;
//有多少个10=总价/10 (对10取整)
double discountNumber = (int)(totalPrice / 10);
//定义一个优惠的有多少个10的总价赋0值
double totalDiscountPrice = 0;
//for (int i = 0; i < discountNumber; i++)
//{
// double discountPrice = 10 * discount;
// totalDiscountPrice += discountPrice;
//}
//优惠的有多少个10的总价=有多少个10 * 优惠单价
totalDiscountPrice = 10 * discountNumber * discount;
//剩下的不优惠的总价=总价 % 10 (对10取余)
double lastPrice = totalPrice % 10;
//总价=优惠的有多少个10的总价+剩下的不优惠的总价
totalPrice = totalDiscountPrice + lastPrice;
MessageBox.Show($"最后付了{totalPrice}元");
总结
-
变量名只有在某一区域内第1次出现时才要声明变量。
-
变量名在区域内第二次出现时不需要声明变量,而是直接使用之前声明的变量。
-
变量名命名是我们一般遵循驼峰命名法,即以小写字母开头,多个单词拼接时,除第一个单词外,其余首字母大写。
-
在程序开发中可以修改之前保存的变量值。
拓展
-
(int)表示使用显式强制转换,是一种类型转换,C#默认整形是 int32 因此使用此方法转成 int32 位,不遵循四舍五入,只截取整数部分;
-
(int)5.21 //输出5
-
Int.Parse():只支持将 string 类型转成 int ,Parse 就是把 string 类型 int,char,double......等,也就是 *.Parse(string) 括号中的一定要是string类型。
String st="5.21";
double n=5.21;
Int.Parse(st); //输出5
Int.Parse(n); //报错
-
.Convert.Tolnt32(double value),不完全遵循四舍五入,如果 value 为两个整数中间的数字,则返回二者中的偶数,对比下面例子:
四舍六入五保双
Console.writeLine(Convert.ToInt32(4.3)); //四舍五入,输出4
Console.writeLine(Convert.ToInt32(4.5)); //第一位小数为5时,4.5在4和5之间,输出偶数4
Console.writeLine(Convert.ToInt32(4.53)); //四舍五入,输出5
Console.writeLine(Convert.ToInt32(5.3)); //四舍五入,输出5
Console.writeLine(Convert.ToInt32(5.5)); //第一位小数为5时,5.5在5和6之间,输出偶数6
Console.writeLine(Convert.ToInt32(5.53)); //四舍五入,输出6
注意:Convert.ToInt32() 和 int.Parse() 对于空值(null)的处理不同,Convert.ToInt32(null) 会返回0而不会产生任何异常,但int.Parse(null) 则会产生异常
06.函数初识
-
函数好比就是对象的动作行为。
-
在定义函数要想好函数所承担的作用,职责(作用)越单一越好。
函数的命名规范
-
函数命名使用大驼峰命名,即开头首字母大写,
-
多个单词拼接时,所有单词首字母大写。
Add();
AddCount();
GetUserInfo();
6.1函数的参数设置&传参行为
-
参数可认为是外部需要函数帮忙处理的数据。
-
外部通过传递参数的形式,将需要处理的数据交给函数处理。
/// <summary>
/// 加法方法
/// </summary>
/// <param name="firstCount">数字1</param>
/// <param name="secondCount">数字2</param>
public void Add(int firstCount, int secondCount)
{
int totle = firstCount + secondCount;
}
6.2函数返回值的设置
-
函数返回值可以认为是外部调用某种行为后得到的一种反馈。
/// <summary>
/// 加法方法
/// </summary>
/// <param name="firstCount">数字1</param>
/// <param name="secondCount">数字2</param>
public int Add(int firstCount, int secondCount)
{
int totle = firstCount + secondCount;
return totle;
}
6.3拓展——参数修饰符
修饰符种类
-
无修饰符:如果一个参数没有用参数修饰符标记,则认为它将按值进行传递,者将意味着被调用的方法收到原始数据的一份副本。
-
out:输出参数由被调用的方法赋值,因此按引用传递,如果被调用的方法没有给输出参数赋值,就会出现编译错误。out 最大的用途就是调用者只使用一次方法的调用就能获得多个返回值。(在C#7.0 中要实现一次方法的调用就能获得多个返回值,建议使用元组。是元组不是元祖)
private void btnOut_Click(object sender, EventArgs e)
{
Sub(2, 1, out int res);
MessageBox.Show(res.ToString()); //输出1
}
void Sub(int leftNum, int rightNum,out int res)
{
res=leftNum - rightNum;
}
3. ref:调用者赋初值,并且可以由被调用的方法可选的重新赋值(数据是按 引用传递 的)。如 果被调用的方法未能为给 ref 参数赋值,也不会有编译器错误。
4. 了解即可 params:这个参数修饰符允许将一组可变的数量的参数作为单独的逻辑参数进行传 递,方法只能有一个 params 修饰符,而且必须是方法的最后一个参数。
private void btnParams_Click(object sender, EventArgs e)
{
//var res=Add2(1,2); //和下面一行效果一样
var res = Add2(new int[] { 2,1});
MessageBox.Show(res.ToString());
}
int Add2(params int[] ints)
{
int res2 = ints[0]+ints[1];
return res2;
}
out 和 ref 的区别
-
out 修饰的参数必须在方法内修饰,而 ref 可以修改也可以不修改;
-
out 在传入参数的时候,参数是局部变量的话,可以不用赋值,因为 out 一定会对其进行赋值
-
而 ref 修饰的参数,在实参必须有初始值才能调用。因为 ref 修饰的不一定会给它赋值。
案例:封装——买西瓜
-
封装上一个买西瓜的案例
-
将最后的价格通过返回值返回给主函数并打印出来。
private void btnCaseOne_Click(object sender, EventArgs e)
{
double totalPrice = BuyWatermelon(6);
MessageBox.Show($"最后付了{totalPrice}元");
}
double BuyWatermelon(int count)
{
double price = 1.9;
double discount = 0.75;
double totalPrice = 0;
//这里是会有精度损失
totalPrice = price * count;
if (totalPrice >= 10)
{
totalPrice *= discount;
}
return totalPrice;
}
下一篇:面向对象基础 敬请期待