第3章 更多数据类型
3.1 类型的划分
一个类型要么是值类型,要么是引用类型。区别在于 拷贝方式:值类型的数据总是拷贝值;引用类型的数据总是拷贝引用。
3.1.1 值类型
除了string,本书目前讲到的所有预定义类型都是值类型。值类型直接包含值。变量引用的位置就是内存中实际存储值的位置。因此,将一个值赋给变量1,在将变量1赋给变量2,会在变量2的位置创建值的拷贝,而不是引用变量1得位置。
3.1.2 引用类型
引用类型得变量存储对数据存储位置得引用,而不是直接存储数据。要去那个位置才能找到真正的数据。所以为了访问数据,“运行时”要先从变量中读取内存位置,再“跳转”到包含数据的内存位置。
为引用类型的变量分配实际的内存区域称为 堆
引用类型不像值类型那样要求创建数据的内存拷贝,所以拷贝引用类型的实例比拷贝大的值类型实例更高效。
事实上,每个引用总是系统的“原生大小”:32位系统拷贝32位引用,64位系统拷贝64位引用,依次类推,显然,拷贝对一个大数据块的引用,比拷贝整个数据块快的多。
除了string和自定义类,本书目前讲到的所有类型都是值类型,但大多数类型都是引用类型。虽然偶尔需要自定义的值类型,但更多的还是自定义的引用类型。
3.2 可空修饰符
隐式类型的局部变量
C#3.0新增上下关键字var来声明隐式类型的局部变量。
设计规范
•避免使用隐式类型的局部变量,除非所赋的值的数据类型显而易见。
高级类型:匿名类型
3.3 元组
允许再一个语句中完成所有变量的赋值。
(string country,string capital)=("China","BeiJin");
设计规范
•要为元组语法的变量声明使用camelCase大小写规范。
•考虑位所有元组项名称使用PascalCase大小写风格。
元组声明和赋值的示例代码:
3.4 数组
C#的数组索引从零开始,所以我们说C#数组基于零
初学者主题:数组
3.4.1 数组的声明
string [ ] languages;
方括号指定了数组的秩,或者说维数。
3.4.2 数组实例化和赋值
声明数组的同时赋值:
string[] languages={"C#","Java","C++"};
声明数组后赋值:
string[] languages;
languages=new string[]{"C#","Java","C++"};
使用new关键字:
string[] languages=new string[]{"C#","Java","C++"};
•引用类型 比如string 初始化为null
•数值类型初始化为0
•bool初始化为false
•char初始化化为\0
注意 从C# 2.0起可以使用default()操作符获取数据的默认值。例如default(int)返回值为0
3.4.3 数组的使用
string[] languages=new string[3]{"C#","Java","C++"};
注意 Length成员返回数组元素个数,而不是返回最高索引值。languages变量的Length成员是9,而languages变量的最高索引是8,那是从起点能到达的最远位置
3.4.4 字符串作为数组使用
访问string类型的变量类似于访问字符数组。例如,可调用palindrome[3]获取palindrome字符串的第4个字符。注意由于字符串不可变,所以不能向字符串中的特定位置赋值。
string[] args;
if(args[0][0]='-')
{
//This parameter is an option
}
注意,第一个数组访问符[]获取字符串数组args的 第一个元素,第二个数组访问符则获取该字符串的第一个字符。
3.4.5 常见的数组错误