c#数据类型/变量/常量/计算机数据存储(进制之间的相互转化)
一c#数据类型
注:
**值类型:**值直接存储在堆栈中(存储空间小,调用速度快);
**引用类型:**值存储在堆中(存储空间大,调用速度慢)
1.值类型
a. 值类型变量可以直接分配给一个值.它们是从类System.ValueType中派生的.
b.值类型直接存储其值.
c.值类型的实例通常是在线程栈上分配的(静态分配),但是在某些情形下可以存储在堆中.
d.值类型总是分配在它声明的地方:作为字段时,跟随其所属的变量(实例)存储;作为局部变量时,存储在栈上.栈的内存是自动释放的.
e.值类型在内存管理方面具有更好的效率,并且不支持多态, 适合用做存储数据的载体.
f.C#的值类型包括:结构体(数值类型、bool 型、用户定义 的结构体),枚举,可空类型.
2.引用类型
a.引用类型不包含存储在变量中的实际数据,但它们包含对 变量的引用.继承自System.Object 类.
b.引用类型存储对其值的引用.它们指的是一个内存位置.使用多个变量时,引用类型可以指向一个内存位置.如果内存位置的数据是由一个变量改变的,其他变量会自动反映这种值的变化.
c.引用类型当声明一个类时,只在栈中分配一小片内存用于容纳一个地址,而此时并没有为其分配堆上的内存空间.当使用new 创建一个类的实例时,分配堆上的空间,并把堆上空间的地址保存到栈上分配的小片空间中.
d.引用类型的对象总是在进程堆中分配(动态分配).
e.引用类型在栈中存储一个引用,其实际的存储位置位于托管堆.简称引用类型部署在托管推上. (堆内存是.NET 中会 由 GC 来自动释放).
f.引用类型可以派生出新的类型,而值类型不能,因为所有的值类型都是密封(seal).
g.引用类型可以包含 null 值,值类型不能(可空类型功能允 许将 null 赋给值类型,如 int? a = null; ).
h.引用类型变量的赋值只复制对对象的引用,而不复制对象 本身.而将一个值类型变量赋给另一个值类型变量时,将复制包含的值.
i. C#的引用类型包括:
内置的 引用类型有:object、dynamic 和 string。
①对象(Object)类型是C#通用类型系统(Common Type System - CTS)中所有数据类型的终极类.ObjectSystem.Object 类的别名.所以对象 (Object)类型可以被分配任何其他类型(值类型、 引用类型、预定义类型或用户自定义类型)的值. 但是,在分配值之前,需要先进行类型转换.
② 动态(Dynamic)类型您可以存储任何类型的值在动 态数据类型变量中.这些变量的类型检查是在运行时发生的.动态类型与对象类型相似,但是对象类型变量的类型检查是在编译时发生的,而动态类型 变量的类型检查是在运行时发生的.
③字符串(String)类型允许给变量分配任何字符串值.字符串(String)类型是 System.String 类的别名它是从对象(Object)类型派生的.字符串(String)类型的值可以通过两种形式进行分配: 引号和 @引号.
用户自定义引用类型有:class、数组、interface 或 delegate.
3.类型的转换
数据类型转换的方式:
(1):隐式类型转换
这些转换是C#默认的以安全方式进行的转换
(2):显式类型转换
这些转换是通过用户使用预定义的函数显式完成的。显式转换需要强制转换运算符。
Convert对象完成数据类型转换:
(3):int.Parse()方法
该方法只能将string类型数字字符串强制转换为int类型
(4).(char)Num
整数前使用(char)将Num当成十进制ASCII码转成其对应的字符
(xxx)NNN:如果可以的话,将NNN类型强制转换为xxx类型
(5).XXX.ToString()方法
ToString方法是每个对象基本上都具有的一个方法,其作用是将这个对象直接转成string类型
案例1:计算器
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace form_01
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//设置在comboBox1中不能输入内容
comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
}
private void button1_Click(object sender, EventArgs e)
{
//把textBox1.Text强制转换成double类型,convert.ToDouble是强转换符
double num1 = Convert.ToDouble(textBox1.Text);
double num2 = Convert.ToDouble(textBox2.Text);
double num3 = 0;
//ToString()是一种方法
//获取textBox1.Text的索引值 用res来接收 然后做判断
/* string res = comboBox1.SelectedIndex.ToString();
//0,1,2,3,4表示的是索引值
if (res == "0")
{
//假如索引值为0,则为两者相加
num3 = num1 + num2;
}
if (res == "1")
{
num3 = num1 - num2;
}
if (res == "2")
{
num3 = num1 * num2;
}
if (res == "3")
{
num3 = num1 / num2;
}
if (res == "4")
{
num3 = num1 % num2;
}
textBox3.Text = num3.ToString();
}*/
//通过获取combobox1中的内容来获取
string res = comboBox1.Text.ToString();
if (res == "+")
{
num3 = num1 + num2;
}
if (res == "-")
{
num3 = num1 - num2;
}
if (res == "*")
{
num3 = num1 * num2;
}
if (res == "/")
{
num3 = num1 / num2;
}
if (res == "%")
{
num3 = num1 % num2;
}
textBox3.Text = num3.ToString();
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
}
}
}
3.数据类型转换需要注意的问题
(1). 在将字符串或其他类型转成数字类型的过程中必须要注意,字符串必须是纯数字类型的字符串
( 2). 当我们在属性赋值过程中一定要注意等号右边所赋予的结果是否和等号之前的类型一致,如果不一致,并且编译报错则必须要进行显式转换
(3):不仅在数学运算中需要进行数据类型转换,在比较等其他特殊的操作中也需要进行数据类型转换
案例2:随机验证码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace window_02
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//定义一个含10种字体的数组
// string[] ziti = { "Arial", "Verdana", "Comic Sans MS", "Impact", "Haettenschweiler", "Lucida Sans Unicode", "Garamond", "Courier New", "Book Antiqua", "Arial Narrow" };
string code = "";
//窗口加载时候我们有一张验证码 验证码的长度为5个字符 随机的数字或者字母
//此时我们用到了随机函数 还需要用到ascll码表
Random run = new Random();
//设置随机字体不用数组的方法
string set = "";
int best = run.Next(0,3);
if (best == 0)
{
set = "Garamond";
}
if (best ==1)
{
set = "微软雅黑";
}
if (best ==2)
{
set = "Comic Sans MS";
}
//此是我们需要5个字符 我们用for循环
for (int i = 0;i< 5; i++)
{
//这里run.next默认转化成int类型 随机取这两个参数之间的整数可以取到最小的,取不到最大的
int type = run.Next(0,3);
//当我们取到0的时候显示的是0-9之间的随机数字
if (type==0) {
// 随机取这两个参数之间的整数可以取到最小的,取不到最大的
code += run.Next(0,10);
}
else if(type == 1)
{
//当我们取到1的时候显示的是随机小写的字母
//整数前使用(char)将Num当成十进制ASCII码转成其对应的字符
code += (char)run.Next(97, 123);
}
else if (type == 2)
{
//当我们取到2的时候显示的是随机大写的字母
//整数前使用(char)将Num当成十进制ASCII码转成其对应的字符
code += (char)run.Next(65,91 );
}
label1.Text=code;
//设置随机颜色用rgb来表示rgb(0,255)
label1.ForeColor = Color.FromArgb(run.Next(0,255),run.Next(0,255), run.Next(0, 255));
//设置随机字体大小/随机字体
//Font textFont = new Font(ziti[rd.Next(9)], 30, FontStyle.Bold);//字体随机,字号大小30,加粗
// label1.Font = new Font(ziti[run.Next(9)], run.Next(10,30));
label1.Font = new Font(set, run.Next(10, 30));
}
}
private void button1_Click(object sender, EventArgs e)
{
//定义一个含10种字体的数组
// string[] ziti = { "Arial", "Verdana", "Comic Sans MS", "Impact", "Haettenschweiler", "Lucida Sans Unicode", "Garamond", "Courier New", "Book Antiqua", "Arial Narrow" };
string code = "";
//窗口加载时候我们有一张验证码 验证码的长度为5个字符 随机的数字或者字母
//此时我们用到了随机函数 还需要用到ascll码表
Random run = new Random();
//此是我们需要5个字符 我们用for循环
string set = "";
int best = run.Next(0, 3);
if (best == 0)
{
set = "Garamond";
}
if (best == 1)
{
set = "微软雅黑";
}
if (best == 2)
{
set = "Comic Sans MS";
}
for (int i = 0; i < 5; i++)
{
//这里run.next默认转化成int类型 随机取这两个参数之间的整数可以取到最小的,取不到最大的
int type = run.Next(0, 3);
//当我们取到0的时候显示的是0-9之间的随机数字
if (type == 0)
{
// 随机取这两个参数之间的整数可以取到最小的,取不到最大的
code += run.Next(0, 10);
}
else if (type == 1)
{
//当我们取到1的时候显示的是随机小写的字母
//整数前使用(char)将Num当成十进制ASCII码转成其对应的字符
code += (char)run.Next(97, 123);
}
else if (type == 2)
{
//当我们取到2的时候显示的是随机大写的字母
//整数前使用(char)将Num当成十进制ASCII码转成其对应的字符
code += (char)run.Next(65, 91);
}
label1.Text = code;
//设置随机颜色用rgb来表示rgb(0,255)
label1.ForeColor = Color.FromArgb(run.Next(0, 255), run.Next(0, 255), run.Next(0, 255));
//设置随机字体大小
label1.Font = new Font(set, run.Next(10, 30));
// label1.Font = new Font(ziti[run.Next(9)], run.Next(10, 30));
//设置随机字体大小/随机字体
// label1.Font = new Font("宋体,楷体,仿宋,微软雅黑", run.Next(10, 30));
}
}
}
}
二.变量
一个变量只不过是一个供程序操作的存储区的名字.在 C# 中, 每个变量都有一个特定的类型,类型决定了变量的内存大小和布 局.范围内的值可以存储在内存中,可以对变量进行一系列操作.
1. C# 中提供的基本的值类型大致可以分为以下几类:
C# 允许定义其他值类型的变量,比如 enum,也允许定义引用类型变量,比如 class.这些我们将在以后的章节中进行讨论.在本章节中,我们只研究基本变量类型.
2. 变量的声明
C#中变量定义的语法
<data_type> <variable_list>;
data_type:必须是一个有效的C# 数据类型,可以是 char、 int、float、double 或其他用户自定义的数据类型.
variable_list:可以由一个或多个用逗号分隔的标识符名称组成.
一些有效的变量定义如下所示
int i, j, k;
char c, ch;
float f, salary;
double d;
3.变量的初始化
变量通过在等号后跟一个常量表达式进行初始化(赋值).
a. 变量初始化是C#强调安全性的另一种方式.简单的说,C# 编译器需要用某个初始值对变量进行初始化,之后才能在操作中引用该变量.大多数现代编译器把未初始化标记为警告,但 C#编译器把它当作错误来看待.这样可以防止我们无意中从其他程序遗留下来的你内存中获取垃圾值.
b. C#确保变量在使用前初始化的两个方法
变量直接定义在类中或者结构中,如果没有显示初始化,那么在创建变量的时候会有默认值
方法、事件内的变量必须在代码中显示初始化,之后才能在语句中使用它们的值.此时初始化不是声明该 变量时进行的,但编译器会通过方法检查所有可能的路径,如果检测到局部变量在初始化之前就使用了他的值,直接报错.
4. 变量的作用域
变量的作用域是可以访问该变量的代码区域。一般情况下, 确定作用域遵循以下规则:
全局变量:只要类在某个作用域内,其成员变量也在该作 用域内
局部变量:存在于表示声明该变量的块级语句或方法结束 的大括号之前的作用域内
局部变量:在 for、while 或类似语句中声明的局部变量存 在于该循环语句内 5
5.变量的作用域冲突
局部变量,同一局部内有至少两个变量的变量名相同,那 么程序编译会报错.
全局变量,在同一个类里面有至少两个全局变量的变量名相同,那么程序编译会报错.
一个全局变量和多个不同局部的局部变量的变量名相同,那么变量遵循就近原则.
三. 常量
常量是固定值,程序执行期间不会改变.常量可以是任何 基本数据类型,比如整数常量、浮点常量、字符常量或者字符串常量,还有枚举常量.
常量可以被当作常规的变量,只是它们的值在定义后不能被修改.
1. 整数常量
整数常量可以是十进制、八进制或十六进制的常量.前缀 指定基数:0x 或 0X 表示十六进制,0 表示八进制,没有前缀则表示十进制.
整数常量也可以有后缀,可以是 U 和 L 的组合,其中, U 和 L 分别表示 unsigned 和 long.后缀可以是大写或者小写,多个后缀以任意顺序进行组合.
2. 浮点常量
- 一个浮点常量是由整数部分、小数点、小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量。
- 使用小数形式表示时,必须包含小数点、指数或同时包含两者。使用指数形式表示时,必须包含整数部分、小数部分或同时包含两者。有符号的指数是用 e 或 E 表示的。
3. 字符常量
字符常量是括在单引号里,例如,‘x’,且可存储在一个简 单的字符类型变量中.
一个字符常量可以是一个普通字符(例如 ‘x’)、一个转 义序列(例如 ‘\t’)或者一个通用字符(例如 ‘\u02C0’).
在 C# 中有一些特定的字符,当它们的前面带有反斜杠时 有特殊的意义,可用于表示换行符(\n)或制表符 tab(\t).在这里,列出一些转义序列码:
4. 字符串常量
字符常量是括在双引号 “” 里,或者是括在 @"" 里.字符串常量包含的字符与字符常量相似,可以是:普通字符、 转义序列和通用字符
使用字符串常量时,可以把一个很长的行拆成多个行,可以使用空格分隔各个部分.
5. 常量的声明
常量是使用 const 关键字来定义的.定义一个常量的语法如下:
const <data_type> <constant_name> = value;
(1). 常量声明之后不允许进行改变其值
(2). 常量命名全部使用大写字母
四.计算机数据存储
整数在计算机中存储是以补码的方式存储的,想要知道补码,必须先知道数字进制转换和原码和反码.
1. 不同进制的组成和输出
二进制:以 0b 开头,由 0 和 1 组成
八进制:以 0 开头,由 0-7 组。(C#中没有现成的表示方式)
十进制:默认就是十进制,由 0-9 组成
十六进制:以 0x 开头,由 0-9+A-F 组成
2. 进制之间的转换算法
其他进制转十进制
√口诀:将所有的位上面的值进制数的次方连起来既可以得到十进制
√位值:每一个位数上面对应的值
√进制数:本身是多少进制,进制数就是多少
√次方:从右向左,从 0 开始编号,对应位上面的编号就 是改位的次方
① 十进制=》十进制
1234=1000+200+30+4
=1103+2102+31001+4100=1234
② 二进制=》十进制
0b100100=125+024+023+122+021+020
=32+0+0+4+0+0=36
③八进制=》十进制
011223=184+183+282+281+38^0
=4096+512+128+16+3=4755
④十六进制=》十进制
0x11c0a=1164+1163+12162+0*161+1016^0
=65536+4096+3072+0+10=72714
十进制转其他进制
除以要转换的进制数,直至商为 0,余数反转
将 x 进制转成 y 进制快速转换法
√利用8421码(将每个二进制对应的位上计算一个固定的 十进制数)
1 1 1 1 1 1 1 1
128 64 32 16 8 4 2 1
二进制 2 位数组合
八进制 3 位数组合
十六进制 4 位数组合
例如: 将二进制 0b100100 转成 8 进制
0b100100=>100 100=>4 4=44
将二进制 0b100100 转成 16 进制
0b100100=>10 0100=>2 4=24
√以十进制为桥梁
x 进制>十进制>y 进制
3. 原码
将一个整数转换成二进制,然后最高位用来表示符号位(0 表示正数,1 表示负数,其余位表示数值位)
例如:7:00000111 -7:10000111
4. 反码
正数的反码和原码一致,负数的反码位数全部取反,除最高位
5. 补码
正数的补码和原码一致,负数的补码在反码的基础上末尾+1
6. 十进制负整数转二进制算法
将十进制输转化成二进制数,不管符号.
对转化的二进制数逐位取反.
对取反后的二进制数加 1,结果就是十进制负数转化成的二进制数.
7.二进制负数转十进制算法
对二进制数逐位取反
对取反后的二进制数加 1,加上负号,结果就是二进制负数转化成的十进制数.
上一篇: 缝合葡萄皮的机器人做手术 今日网络直播
下一篇: 线程池原理及其实现