【慕课C#学习笔记】第二章: C#基础语法

第二章: C#基础语法

2.1 HelloWorld与Console

上一章的最后, 我们编写了第一个HelloWorld程序, 我们看程序的结构

  • Hello World!
using System;//程序使用到的引用

namespace HelloWorld//命名空间,和Java的包名类似
{
	//类名
	class Program
	{
		//主方法,程序的入口
		static void Main(string[] args)
		{
			Console.WriteLine("Hello World!");//打印HelloWorld
			
			Console.Read();//用于悬停窗口
		}
	}
}
  • System.Console

IO操作工具集 (i代表input, o代表output)

Console常用方法 备注
Wirte(参数)
ReadKey() 读取输入键或字符的ASCII值
WirteLine(参数)
ReadLine()
Read()
Clear()
  • 示例
static void Main(string[ ] args)
	Console . writeLine("Hello world" );

	ConsoleKeyInfo a = Console.ReadKey();//读取键
	Console.WriteLine(a.Key);//打印字符
	Console.Clear( );//清除
	
	Console.Read();
}

2.2 变量与数据类型

  • 变量

保存临时数据

  • 基本定义
type name = data //数据类型 变量名 = 具体数据
  • 一些重要的类型
示例
float (小数) float pi=3.1415
bool (真, 假) bool isEarthRound = true
String(一段文字, 字符串) -> 等价于string string hello = “hello world”
char (字符)
double (双精度小数)
  • 类型产生的历史原因
早期计算机编程,汇编代码->机器码
编译器无法识别变量的含义和类型, 经常会因为内存问题报错
指定内存可以避免内存空间的浪费
习惯成自然:C++, Java, C#
但, JavaScript是个奇葩
放弃指定类型
通过上下文自动由编译器自动判断当前变量类型
对开发非常友好,简单、容易上手
无类型是把双刃剑: CoffeScript, TypeScript
  • 未来…
会弱化数据类型
更加接近人类的自然语言
  • 示例: 声明变量
static void Main(string[] args)
{
	int number1;//声明
	number1 = 15;//赋值
	
	int number2, number3, number4;//声明多个
	
	Console.Read();
}

2.3 基本数据类型

  • 基本数据类型

Primitive Types
C#有13种基本数据类型, 这些是预先定义好的内建类型,可以直接使用.

类型 含义 取值范围 精度/内存大小
sbyte 有符号8位整数类型 -128 ~ 127 8 bit
byte 无符号8位整数 0~255 8 bit
short 有符号16位整数 -32,768到32,767 16 bit
ushort 无符号16位整数 0到65,535 16 bit
int 有符号32位整数 -2,147 483,648 ~ 2,147,483,647 32 bit
uint 无符号32位整数 0 ~ 4,294,967,295 32 bit
long 有符号64位整数 -9,223.372,036,854,775,808 ~ 9,223,372,036,854,775,807 64 bit
ulong 无符号64位整数 0 ~ 18,446,744,073,709,551,615 64 bit
float 单精度32位浮点数 -3.4x 1038 ~ +3.4 x 1038 32 bit
double 双精度64位浮点值 64 bit
decimal 128位浮点数据 (-7.9x 1028- 7.9x 1028)/ (100 - 28) 128 bit
bool 布尔值 True / false 8 bit
char Unicode UTF-16字符 U+0000到U+FFFF 16 bit
  • byte与sbyte
byte
byte中文翻译为字节,但是在类型中却表示整数
00 00 00 00
一个byte有8个bit, 可以表示2^8个数字
byte类型不能表示负数,取值范围0到255
sbyte
2^7-> x0 00 00 00
sbyte同样只有8位
第一位表示正负号,表示真正数字只有7位
取值范围是 +2^7 (-128 ~ 127)
  • short与ushort
x0 00 00 00 <> 00 00 00 00
16位, 可表示2^16个数字
short第一位为正负号, ushort则没有正负号
short ( -32,768 ~ 32,767 ), ushort ( 0 ~ 65,535 )
u = unsigned, 无符号的意思
https://baike.baidu.com/item/unsigned/8604216?fr=aladdin
  • int与uint
2^32 ~ 10亿量级
自然界中最经常使用的范围
int有正负之分,而uint则只能表示0和正整数
  • long与ulong
长整数类型
long有正负号,≈±9,223,372,036,854,775,807
ulong无正负号,≈18,446,744,073,709,551,615
满足目前世界科技水平的运算量了
  • 为什么要创建这么多整数类型
历史局限性
为了减少内存浪费
未来,这种计数方式也许会被慢慢淘汰
  • 小数
float(单精度浮点数), double(双精度浮点数) 和 decimal
精度: float(32位) < double(64位) < decimal(128位)
decimal常用于财务会计, 货币金额, 利息利率
  • bool与char
bool表示布尔值,真或假
char则表示一个UTF-16标准下的Unicode字符
char无法表示中文:中文标准是GBK, 不属于UTF-16
中文得用string类型
  • 内建类型,但不属于基本类型
中文得用string类型
string可以通过把多个Unicode字符拼接起来
显示中文、甚至是emoji
object对象类型
dynamic动态类型

2.4 字符串方法与操作

string类型表示一个字符序列(零个或更多Unicode字符). string 是.NET Framework中String的别名.

  • 字符串操作
//字符串拼接
string hello = "hello";
string message = hello + "Alex";

//字符串格式化处理
string name = "Alex";
int age = 18;
Console.WriteLine("My name is {0}. I am {1} years old.", name, age);

//字符串内嵌
string message3 = $"My name is {name}. I am {age} years old.";

//字符串转义
string message4 = "My name is {0}.In I am {1} years old.\n 
i am a developer";

//原意字符串
string message5 = @"My name is {name}. \n 
I am {age} years old.\n

I am develper";

2.5 决策与分支

  • 代码决策decisions

最基本的决策就是使用if语句

if(条件){
	//执行代码逻辑
}
  • 举例
//如果明天天晴,我就去游泳
//如果明天天阴,我就去上班
//如果都不是,我就在家睡觉

if(天晴) {
	//我就去游泳
} else if(天阴){
	//我就去上班
} else {
	//我就在家睡大觉
}
  • switch

多条件分支语句

switch(条件表达式) {
	case 情况1:
		//执行逻辑1;
		break; //跳出分支, 不加的话, 会进入到下一个分支, 灵活选用
	case 情况2:
		//执行逻辑2;
		break;
	...

	default: /*默认情况,可选*/
		//执行默认逻辑;
		break;
}
  • ?:操作符(三元操作)

先看看语法

condition ? consequent : alternative
条件 ? 结果1 : 结果2
condition的部分输出布尔值(true or false)
condition为true, 进入结果1, 否则进入结果2

2.6 程序循环

  • 程序循环
节省程序员大量的开发精力
轻易的重复某段代码或者某个功能模块
可以处理大量数据
  • 循环类型
for 循环 while 循环 do while 循环
  • for loop
for (起始值;循环条件;变化量) {
	//执行代码
}

示例

static void Main(string[] args)
{
	for(int counter = 0; counter<10; counter++)
		Console.WriteLine( counter);
	}
	Console.ReadLine();
}
  • while loop
当…的时候
先进行条件检查,只有当条件满足的时候才进入循环
int counter = 0;
while(counter<5){
	//代码逻辑
	counter = counter + 1;
}

示例2

int counter2 = 0;
while (counter2 < 5)
{
	Console.WriteLine( counter2);
	counter2++;
}
  • do-while loop
while循环的亲戚
先循环, 再检查
int counter = 0;
do {
	//代码逻辑
	counter = counter + 1;
}while(counter<5)

示例2

int counter3 = 0;
do
{
	Console.WriteLine(counter3);
	counter3++;
} while(counter3 < 5);
  • 循环终止
for(int counter = 0; counter<10; counter++ )
{
	Console.WriteLine(counter);
	if(counter==3){
		Console.WriteLine("循环终止”);
		break;//循环终止
	}
}
  • 跳出此次循环
for(int counter = 0; counter<10; counter++)
{
	Console.WriteLine(counter);
	if(counter==3)
		Console.WriteLine(”跳出此次循环”);
		continue;//仅跳出此次循环, 但循环不终止
	}
}

2.7 方法

  • 方法的定义

我们接触的第一个方法就是main方法

花括号包起来的代码块
可以调用,可以执行
在C#中,所有的指令都必须在方法中才能执行
  • 方法签名(方法的组成)
<Access Specifier> <Modifier> <Return Type> <Method Name> (Parameter List)
{	
	Method Body
}

访问修饰符 声明修饰符 返回类型 方法名称 (参数) {
	代码逻辑
}
  • 访问修饰符
Public 公有方法,可以被外部调用
Private 表示私有,方法会被隐藏起来,其他class不可调用
Protected 表示受保护,只能在它的类本身或者它的派生类中访
Private protected
Internal 内部方法,同一个程序集中的所有类都可以访问
Protected internal
  • 声明修饰符
Static 表示静态类型
Abstract 表示抽象类型
Virtual 许派生类重写的虚函数
Override 允许方法继承后重写
New 可以隐藏基类成员
Sealed 表示不能被继承
Partial 允许在同一个程序集分散定义
Extern 用于声明外部实现的Extern
  • 方法签名综上
Access Specifier 访问修饰符,决定了方法是否可以外部访问
Return type 返回类型,方法的最终计算结果,如果方法不返回何值,则返回类型为void
Method name 方法名称,用以从外部调用
Parameter list 参数列表,可选项目
  • 形参与实参
形参 parameter ,形式上的参数
实参 argument ,真正调用方法过程中传入的具体数据

实参

int result = FindMax(1, 99); 

形参

public static int FindMax(int num1, int num2){...}

判断形参与实参

形参定义在方法中
实参定义在方法外部

  • 方法返回
return, 方法的返回值, 也就是方法的最终计算结果
如果方法不返回任何值,则返回类型为void
使用return则意味着方法彻底停止
特殊需要, 你也可以使用return来提前结束代码
  • 方法表达式

C#也有类似Kotlin一样的语法糖

public static int FindMax (int num1, int num2) => num1>num2?num1:num2;

2.8 方法参数的传递

  • 值传参

参数传递的默认方式

为每个值参数创建一个新的存储位置
值传参是c#中世数传递的默认方式。我们之前的代码练习使用的全部都是这种传参方式。
在这种方式下,当调用个方法时,会为每个值炒数创建个新的存储位置,
实际参数的值会复制给形参,实参和形参使用的是两个不同内存中的值。所以,当形参的值发生改变时,不会影响实参的值,从而保证了实参数据的安全
  • 引用传参
int a = 100;
int b = 500;
swap(ref a, ref b);
static void swap(ref int x, ref int y)
{
	int temp;
	temp = x;
	x = y;
	y = temp;
}
  • 输出传参
int a = 100;
getValue(out a)
static void getvalue(out int x)
{
	x=5;
}
  • 引用传参和输出传参的区别

可以看到引用传参和输出传参都不会创建新的存储位置, 及对实参进行更改, 那么两者的区别是什么: 输出传参不需要数据进行初始化, 未初始化的引用传参则是非法的.

笔记记录自慕课C#从入门到进阶

猜你喜欢

转载自blog.csdn.net/weixin_42473228/article/details/126501482