第二章: 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动态类型
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 决策与分支
最基本的决策就是使用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#中,所有的指令都必须在方法中才能执行
<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#从入门到进阶