第二章: C#基础语法
2.1 HelloWorld与Console
上一章的最后, 我们编写了第一个HelloWorld程序, 我们看程序的结构
using System;//程序使用到的引用
namespace HelloWorld//命名空间,和Java的包名类似
{
//类名
class Program
{
//主方法,程序的入口
static void Main(string[] args)
{
Console.WriteLine("Hello World!");//打印HelloWorld
Console.Read();//用于悬停窗口
}
}
}
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 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)
2^32 ~ 10亿量级 自然界中最经常使用的范围 int有正负之分,而uint则只能表示0和正整数
长整数类型 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则表示一个UTF-16标准下的Unicode字符 char无法表示中文:中文标准是GBK, 不属于UTF-16 中文得用string类型
中文得用string类型 string可以通过把多个Unicode字符拼接起来 显示中文、甚至是emoji object对象类型 dynamic动态类型
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";
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
2.5 决策与分支
最基本的决策就是使用if语句
if(条件){
//执行代码逻辑
}
//如果明天天晴,我就去游泳
//如果明天天阴,我就去上班
//如果都不是,我就在家睡觉
if(天晴) {
//我就去游泳
} else if(天阴){
//我就去上班
} else {
//我就在家睡大觉
}
多条件分支语句
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 (起始值;循环条件;变化量) {
//执行代码
}
示例
static void Main(string[] args)
{
for(int counter = 0; counter<10; counter++)
Console.WriteLine( counter);
}
Console.ReadLine();
}
当…的时候 先进行条件检查,只有当条件满足的时候才进入循环
int counter = 0;
while(counter<5){
//代码逻辑
counter = counter + 1;
}
示例2
int counter2 = 0;
while (counter2 < 5)
{
Console.WriteLine( counter2);
counter2++;
}
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#中,所有的指令都必须在方法中才能执行
(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#从入门到进阶