C#程序设计.唐大仕.02.C#语言基础

C# 语言基础——数据运算、流程控制、数组

一. 数据类型、变量与常量

1. 变量与常量

  • 程序的基本任务是:对数据进行处理
  • 变量与常量
    • 变量(variable)是值可以改变,本质上是内存的空间,用来存储信息
    • 常量的值是固定的,直接写出来的,称字面常量(literal)
  • 变量(identifier,标识符)命名规范
    • 不能是C#关键字
    • 由字母、数字、下划线构成
    • 第一个字符必须是字母或下划线
    • 不要太长,一般不超过31个字符为宜
    • 变量名最好不要与库函数名、类名相同。
  • C# 是大小写敏感的

2. 数据类型

  • 数据类型:本质上是数据的存储方式及其能参与的运算的抽象

  • C# 的数据类型分两大类

    • 值类型(Value Type)
      • int, double, Point, Size, DateTime
    • 引用类型(Reference Type)
      • Button, Label, Book, Person
  • 它们都是类型

    • 任何变量都有类型

    1
    2
    3
    4
    int a= 5;
    DateTime t = new DateTime(2020, 12, 31);
    Button btn= new Button();
    double.Parse();

  • 它们都是 Object

    • 它们都能.ToString()

    1
    Label1.Text = age.ToString();

    • 都能用于字符串的连接(+)

等价类型

  • 每种简单数据类型都有一个关键词
    • int 相当于 System.Int32
    • double 相当于 System.Double
    • bool 相当于 System.Boolean
    • string 相当于 System.String
      • 如果 using System,则 string 相当于 String

简单类型

整数类型
  • 有符号 sbyte (1),short (2),int (4),long (8)
    • 如 87L,0x1F (没有八进制写法
  • 无符号 byte,ushort,uint,ulong,
    • 如 87UL
字符类型
  • char (2)
    • Unicode 表示
    • 如 'a','0B1' 表示 Unicode ''(回车)
实数类型
  • float (4)
    • 如3.14F
  • double (8)
    • 如 3.14,1.5E-3,3.14D (后面这个D可以省略)
十进制类型
  • Decimal

    • 如 120.50M
布尔类型
  • bool
    • 如 true false(小写)
    • 不能用 0 或 1 代替

转义符

  • 转义字符含义
    • \uxxxx:1到4位十六进制数所表示的字符(xxxx)
    • \':单引号字符
    • \":双引号字符
    • \\:反斜杠字符
    • \r:回车(return)
    • \n:换行(new line)
    • \f:走纸换页
    • \t:横向跳格
    • \b:退格

字符串类型

  • String
  • 引用类型但对字符串常量有特殊处理
  • 字符串前可使用 @
    • 可以不进行 \ 转义
    • 可以换行
    • 双引号则用两个双引号表示一个双引号
1
2
3
4
5
6
"abcd1234"

@"abcd
Pqrst"

@"c:\windows\system32\aaa.txt"

注意

  • 针对 C++ 程序员

    • 引用类型与值类型是由其类型定义的,而不是由其使用决定的
    • 如 C++ 中

    1
    2
    3
    4
    5
    // C++
    Book b;
    Book * b;
    Book &b;
    Book *& b;

  • 针对 JavaScript 程序员

    • 类型是严格的 TextBox1.Text = a.ToString();
  • 针对 VB 程序员

    • int 为 32 位长
    • 字符(char)与字符串(string)不同

C# 新版本中的特殊类型

  • 推断类型(C# 3.0)

    1
    var a = 1 + 2;

    • 与 javascript 中不同,其类型由编译器推断,在编译时就确定了的
  • Nullable 类型(C# 3.0)

    • 可以有值,也可以没值
    • 一般主要用于数据库

    1
    2
    int? a = 32;
    if(a.HasValue) {}

  • Dynamic(C# 4.0)

    • 由DLR 支持
    • 编译时不检查,运行时才确定,主要用于与 COM 组件或其他语言交互

    1
    dynamic x = new Cell();

二. 运算符与表达式

1. 运算符

  • 和 C++ 相似

算术运算符

1
+, -, *, /, %, ++, --

关系运算符

1
>, <, >=, <=, ==, !=

逻辑运算符

1
!, & , | , ^ , &&, ||

位运算符

1
&, |, ^, ~ , >>, <<
  • &&, || 是短路(short-circuit)运算符

赋值运算符

1
=

扩展赋值运算符

1
+=, -=, *=, /=

字符串连接运算符

1
+
  • + 运算符两侧的操作数中只要有一个是字符串(String)类型,系统会自动将另一个操作数转换为字符串然后再进行连接
1
2
strings = "hello," + 300 + 5 + "号";
// hello,3005号

2. 表达式

  • 表达式是符合一定语法规则的运算符和操作数的序列
  • 三目运算
1
m = a > b ? a : b;

表达式的类型和值

  • 对表达式中操作数进行运算得到的结果称为表达式的值
  • 表达式的值的数据类型即为表达式的类型

赋值时的类型转换

  • = 两侧的数据类型不一致时,可以适用默认类型转换或强制类型转换(casting)原则进行处理
1
2
long l= 100;
int i= (int)l;
  • 特例:可以将整型常量直接赋值给 byte、short、char 等类型变量,而不需要进行强制类型转换,只要不超出其表数范围
    • 编译器在编译的时候可以识别出来常量
1
2
byte b = 12;   //合法
byte b = 4096; //非法

表达式中的类型转换

  • 当有不同种类的混合运算时:
    • int -> long -> float -> double
  • 另外,注意整型提升
    • 所有的 byte、short、char 等转为 int
    • 只要参与运算就转成 int
    • byte + byte 也会转化为 int 之后再进行相加

类型转换函数

  • 字符串转成数值
1
2
double.Parse(s);
int.Parse(s);
  • 数字转成字符串
1
2
10.ToString();
"" + 10;
  • 使用 Convert
1
2
3
Convert.ToInt32(textbox1.Text)
Convert.ToDouble("123.45")
Convert.ToDateTime("2009-10-01 14:00")

运算符优先级与结合性

  • 单目 > 算术 > 关系 > 逻辑 > 三目 > 赋值
Separator . ( ) { } ; ,
Associative Operators
R to L ++ --~ ! (data type)
L to R * / %
L to R + -
L to R << >> >>>
L to R < > <= >= instanceof
L to R == !=
L to R &
L to R ^
L to R \(|\)
L to R &&
L to R \(||\)
R to L ?:
R to L = *= /= %= += -= <<= >>= &= ^=

三. 流程控制语句

  • 结构化程序设计的三种基本流程
    • 顺序分支循环

简单语句

  • 最简单的语句:方法调用语句赋值语句
    • 后面有个分号
  • 没有表达式语句一说
    • 2+3; 不能成为一个语句
    • 编译报错

分支语句

  • if-else 语句
  • switch 语句
    • case 变量:整型、枚举、字符串
    • 不能随便贯穿,必须有 break
      • 除非几个 case 连起来,中间没有别的语句
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 编译错误
switch(s){
case 1:
Console.WriteLine("1");
// break;

case 2:
Console.WriteLine("2");
break;
default:
Console.WriteLine("default");
break;
}

// OK
switch(s){
case 1:
// break;
case 2:
Console.WriteLine("2");
break;
default:
Console.WriteLine("default");
break;
}

循环语句

  • 循环语句功能
    • 句的在循环条件满足的情况下,反复执行特定代码
  • 循环五要素
    • 初始化部分(init_statement)
    • 循环条件部分(test_exp)
    • 循环体部分(body_statement)
    • 迭代部分(alter_statement)我称为“循环改变”
    • ”结束后处理”
  • for 循环、while 循环、do-while 循环

  • 跳转语句
    • break
    • continue
    • goto
      • 可以从内层跳到外层
      • 标号的写法:标识符加个冒号(:)
    • try-catch

四. 数组

  • 数组是多个相同类型数据的组合
  • 数组属引用类型

一维数组声明

  • 一维数组的声明方式
1
2
3
int[] a1; // 注意方括号写到变量名的前面
double []b;
Mydate []c;
  • C# 语言中声明数组时不能指定其长度(数组中元素的个数)
    • 因为是引用类型
1
int a[5]; // 非法

数组初始化

动态初始化

  • 数组定义与为数组元素分配空间并赋值的操作分开进行
1
2
3
4
5
6
7
8
9
10
int[] a = new int[3];
a[0] = 3;
a[1] = 9;
a[2] = 8;

MyDate[] dates;
dates = new MyDate[3];
dates[0] = new MyDate(22, 7, 1964);
dates[1] = new MyDate(1, 1, 2000);
dates[2] = new MyDate(22, 12, 1964);

数组初始化

  • 在定义数组的同时就为数组元素分配空间并赋值。
1
2
3
4
5
6
7
8
9
int[] a = {3, 9, 8};
int[] a = {3, 9, 8,}; // 最后可以多一个逗号
int[] a = new int[]{3, 9, 8};

MyDate[] dates= {
new MyDate(22, 7, 1964),
new MyDate(1, 1, 2000),
new MyDate(22, 12, 1964)
};

数组元素的默认初始化

  • 数组是引用类型,它的元素相当于类的成员变量
  • 因此数组一经分配空间,其中的每个元素也被按照成员变量同样的方式被隐式初始化
    • 数值类型是 0,引用类型是 null

数组元素的引用方式

  • index为数组元素下标,可以是整型常量或整型表达式
1
a[3], b[i], c[6*i];
  • 数组元素下标从 0 开始
    • 长度为n的数组合法下标取值范围:0 ~ n-1
  • 每个数组都有一个属性 Length 指明它的长度

foreach 语句

  • foreach 是只读式的遍历
1
2
3
4
int[] ages = new int[10];
foreach( intage inages ) {
// ...
}

Array.Copy()

1
2
3
4
5
6
7
8
//源数组
int[] source = { 1, 2, 3, 4, 5, 6 };
//目的数组
int[] dest = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };

// 复制源数组中从下标 0 开始的 source.length 个元素到
// 目的数组,从下标 0 的位置开始存储。
Array.Copy(source, 0, dest, 0, source.Length);

多维数组

  • 二维数组举例
1
2
int[,] a = {{1,2,5},{3,4,0},{5,6,7}};
Button[,] buttons = new Button[4, 4];
  • 可以用 a.GetLength(0) , a.GetLength(1) 来获得各个维度的长度

交错数组

  • C#中交错数组是数组的数组
1
2
3
4
int[][] t = new int[3][];
t[0] = new int[2];
t[1] = new int[4];
t[2] = new int[3];
  • C# 中多维数组的声明和初始化应按从高维到低维的顺序进行
1
int t1[][] = new int[][4]; // 非法, 这与C++是不一样的

五. 其他

屏保程序

  • 放到文件夹 C:\windows\system32\ 下,修改文件名为 xxx.scr

匈牙利命名法

  • lbl(label)、btn(button)、txt(textBox)、lst(listBox)、frm(form)
  • 修改 Name 属性修改名字

事件的 sender

1
2
3
4
5
//按钮点击事件处理
void btn_Click(object sender, EventArgs e) {
Button btn = sender as Button; // 当前点中的按钮
// ...
}