当前位置:
首页 > 编程开发 > Objective-C编程 >
-
c++程序员快速学习c#之一
制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
随着.NET的深入人心,作为一个程序员,当然不能在新技术面前停而止步,面对着C++在.NET中的失败,虽然有一丝遗憾,但是我们应该认识到,对于C++其实就不应该对其在.NET中的表现有太大的奢望,因为毕竟它并不是一个.NET下的正统语言。
.NET应该是c#的舞台,作为一个C++程序员,我们应该庆幸,因为我们学习c#其实是简单的直接的,需要我们接受的新知识其实不多,相对其他语言来说,我们应该可以更加平滑的过渡到c#的开发中。废话不多说,现在就让我们用C++的基础来学习这个渐渐壮大的新语言--C#。
对于C#的讲解我只讲解和C++有区别的地方,相同的部分我就一带而过。这样的对比学习可以让我们在已有知识的前提下快速掌握C#。
一.统窥:
一开始学习语言大部分的教程都会用一个Hello World程序来示范,我们也落入俗套,用Hello World来和C++中做一个比较:
C++:
#include <iostream>
using namespace std;
void main()
{
//C++程序
/* C++程序*/
cout<<"Hello World!"<<endl;
}
C#:
using System;
namespace HelloWorld
{
class Class1
{
//C#程序
/*C#程序*/
///C#程序
static void Main()
{
Console.WriteLine ("Hello World!");
}
}
}
一眼看上去两者差不多,心中一阵窃喜,可以说C#对语法的定义更加严格一些。
首先对于程序的进入点,最大的区别就是Main函数的开头必须要大写。因为C#是一个完全面向对象的程序语言,所以它的所有代码都必须定义在一个类中,Main函数也不例外,同时因为.NET程序在编译运行时都是先转为中间语言。
然后中间语言再编译为机器语言,这样的好处有2个:
一.如同Jave一样,写好的程序可以在不同的系统中运行,而不需要改变程序。二.使用不同的语言写的程序,因为要转化为相同的中间语言,所以在程序开发中可以使用不同的程序语言编写,而相互调用。
当使用不同语言开发或者进行分类开发时,各自开发的程序中会出现相同的变量名,函数名等,所以在写C#程序时,必须把程序包涵在一个名字空间内。
定义名字空间使用关键字:
namespace <空间名>
当一个命名空间中的代码需要使用在另一个名字空间中定义的名称,就必须包括对该命名空间的引用,使用点字符(.)
例:
namespace LevelOne
{
//name “A”defined
Namespace LevelTwo
{
//name “A”defined
}
}
这里就定义了两个名字相同的变量,我们可以使用LevelOne.A 和 LevelOne.LevelTwo.A 来独立使用它们,互不干扰。
建立了名字空间后,我们可以使用using关键字来简化对它们包含的名称的访问。和C++中使用using namespace std的含义相似;
对于主函数必须要有限定词static 这表明Main函数是静态的,在内存中只能有一个副本。
第一行中的using System.其命名空间是.NET应用程序的根名字空间,包涵了控制台应用程序所需要的所以基本功能。就如同C++中的头文件包涵在std这个名字空间中一样。
Console.WriteLine ("Hello World!");Console是system名字空间中的一个类,其有一个WriteLine方法,它的作用和cout一样,输出一行字符串。
二.数据类型
C#中的数据类型和C++是类似的。
1.浮点类型
浮点类型中添加了一个精度更高的decimal类型,对于金融方面的程序开发。此种数据类型用来定义钱币。
2.Bool类型
Bool类型的变量只能赋值为:false和true,虽然它们的含义仍然是0和非0,但是在使用中不能再给它们赋值成整数值,在判断语句中.if (bool a==1) 的使用都是错误的。
3.字符类型
Char类型在C#中是16位的,它也不能接收一个整数值
4.整数类型
整数类新中添加了byte(8位无符号整数),sbyte(8位有符号整数),short(16位有符号整数)
long变成了真正的64位有符号整数,它可以用在64位机器的编程中。
uint,ushort,ulong顾名思义是没有符号的整数,它和C++中的unsigned int是一样的,名字换了一下而已。
5.字符串类型
String类型是字符串类型,它是引用的类型,它的使用方法和C++中string的使用相似,可以进行+运算,String类型有一些方法可以给我们使用.例如:ToCharArray() 把字符串放入一个字符数组中 Length 返回字符串的长度等等,可以在MSDN中查找.。
6.类型的转换
C#是一个强类型的语言,它的数值类型有一些可以进行隐式转换,其他的必须显式转换,隐式转换的类型只能是长度短的类型转换成长的类型,例如int可以转换成long,float,double,decimal。反之必须显式的转换。
例:
int a=7;
float b=a;
//隐式转换
long c=12L;
//和C++一样必须加上后缀L才能
定义为long型不然就为int型了
a=(int)c;
//显示转换
使用上面的显示转换不能用在BOOL和string类型上,如果希望string或者bool类型和整数类型之间的转化可以使用一个方法。
Convert.To*****(val)
*****:一种数据类型(具体请参看MSDN)
val:可以是这种类型的变量
例:
int a=123;
string str=Convert.ToString(a);
bool m_bool=Convert.ToBoolean(a);
7.枚举类型
C++和C#的枚举类型,定义相同,使用也相同,只要注意C#中语句最后不需要;结束符,同时定义枚举类型时也不许放在主函数代码段中它只能放在执行代码外面.如下
using System;
namespace HelloWorld
{
enum week
{monday,tuesday,wednesday,thursday,friday,saturday,sunday}
class Class1
{
static void Main()
{
week day=week.friday ;
int a=(int)day;
int b=(int)week.saturday ;
}
}
}
8.指针类型
C++中奉为经典的指针类型,在C#中已经取消了,真不知道这个是一个好消息还是坏消息,不过在易用性方面来说因该是一个进步。不过c#中其实在隐藏了一个指针,我们会在后面说到,同时在C#中也可以包含不安全代码,这些代码就是使用了指针的代码。
9.结构类型
C#中的结构类型看上去和C++没有什么区别,定义使用也相似,但还有有很大的区别的,首先就和枚举类型相似, 最后不需要;结束符,同时定义时也不许放在主函数代码段中它只能放在执行代码外面。
其二最大的区别就是C#中的结构已经和类相似了,C++中的结构是公有的,而C#中是私有的,它和类的区别唯一就是不能继承,但是结构是在堆栈中创建的空间,所以最好是对小量的数据进行操作。
例:
using System;
namespace ConsoleApplication1
{
public struct student
{
public int a;
public double c;
}
enum week
{
monday,tuesday,wednesday,thursday,friday,saturday,sunday
}
class Class1
{
static void Main(string[] args)
{
week day=week.friday ;
int aa=(int)day;
int bb=(int)week.saturday ;
Console.WriteLine ("{0},{1}",aa,bb);
student a,b;
a.a=1;
a.c=1.1;
b=a;
a.c =2.6;
Console.WriteLine ("{0} {1} {2} {3}",b.c,b.a ,a.a ,a.c );
Console.WriteLine ("{1} {0} {3} {2}",b.c,b.a ,a.a ,a.c );
}
}
}
输出结果:
4,5
1.1 1 1 2.6
1 1.1 2.6 1
C#中的输出定位格式和C语言中的printf类似,但更加简洁,不需要在对不同类型的变量使用不同的占位符,只需对应后面跟着的变量,给出序号就可以了。
10.数组类型
数组的定义和C++有区别,看上去很别扭;定义语法为:
<类型>[] <变量名> 例: int[] num;
这样就定义了一个int类型的数组,但是切记它可和C++不同,[]里面可不要写内容哦!int[10] num可是错误的。确定数组的大小有两个办法,一.在定义时指定数据:
例:
int[] num={5,3,7,3}; 二.使用关键字new;例:int[] num=new int[4];
当然两者也可以合起来:
例:
int [] num=new int[4]{5,3,7,3};
注意:前面定义了4个数据,后面花括号里面就必须有4个数据不然就是错误的。
例:
int [] num=new int[4]{4,3} //错误;
对数据的使用和C++一样。
对多维数组的定义和C++是不同的,C++中定义为:
int num[3][4]={1,2,3,4,5,3,2,3,4,2,3,4};
C#中定义为:
int[,] num=new int[3,4]{{1,2,3,4},{5,3,2,3},{4,2,3,4}};
注意:和C++不同C#不能在数据列表中不分类,也就是说不使用{}把一组括起来是错误的,而在C++中是正确的,对数据的使用也相应的变为:
num[2,1]=3;
C#在数组中最富革命性的改变因该是添加了锯齿形数组,例如它可以添加一组{{1,2,3,4},{2,3},{2,3,1}}长度不一样的数据,在C++中只能创建一个[3][3]的数组,在C#中它能够产生这样一个锯齿形数组,第一组中有4个数据,第二组中有2个数组,第三组中有3个,这样可以不浪费内存。
锯齿数组的定义和前面的定义也有区别,它更象是一个数组中包含了一个数组:
int[][] num=new int[3][];
num[0]=new int[4]{1,2,3,4};
num[1]=new int[2]{2,3};
num[2]=new int[3]{2,3,1};
下面是上面的定义的一种简洁写法:
int[][] sum={new int[]{1,2,3,4},new int[]{2,3},new int[]{2,3,1}};
三.变量
变量的使用和作用域和C++类似,没有什么特别需要注意的。
但是首先我们应该看到,现在的程序都是包含在类当中了,也就是说定义的变量都变成了类的私有成员,如果要在别的类中使用变量就需要在定义语句前加上限制符public。
在C++中我们看到过这样在类中声名变量:
public:
int a;
int b;
a,b都是公有的,因为使用了public:,但是在C#中这样的语句没有了,我个人认为这样其实很好嘛,简洁明了。
在C#中必须给每个变量添加限制符:
public int a;
public int b;
C#中的限制符还有一些,如下:
internal:变量只能在当前程序中使用
new:从其他类继承而来的类,并隐藏了该类中的已有字段,这个关键字会在类中介绍.
private:私有的,和C++中含义一样
protected:保护类型,和C++中含义一样
static:静态的,和C++中含义一样
readonly: 只读,在变量初始化以后就不许改变
protected internal:当前程序中使用,或者在派生当前类型的其它类型中被访问,就是双重限定,但只有这一个组合
四.常量
常量的定义使用const关键字,和C++类似。
它和只读限定符的区别:
1.常量是静态的
2.必须在初始化时赋值
真不明白有什么实际的意义,发现C#也是一个累赘的语言。
然后中间语言再编译为机器语言,这样的好处有2个:
一.如同Jave一样,写好的程序可以在不同的系统中运行,而不需要改变程序。二.使用不同的语言写的程序,因为要转化为相同的中间语言,所以在程序开发中可以使用不同的程序语言编写,而相互调用。
当使用不同语言开发或者进行分类开发时,各自开发的程序中会出现相同的变量名,函数名等,所以在写C#程序时,必须把程序包涵在一个名字空间内。
定义名字空间使用关键字:
namespace <空间名>
当一个命名空间中的代码需要使用在另一个名字空间中定义的名称,就必须包括对该命名空间的引用,使用点字符(.)
例:
namespace LevelOne
{
//name “A”defined
Namespace LevelTwo
{
//name “A”defined
}
}
这里就定义了两个名字相同的变量,我们可以使用LevelOne.A 和 LevelOne.LevelTwo.A 来独立使用它们,互不干扰。
建立了名字空间后,我们可以使用using关键字来简化对它们包含的名称的访问。和C++中使用using namespace std的含义相似;
对于主函数必须要有限定词static 这表明Main函数是静态的,在内存中只能有一个副本。
第一行中的using System.其命名空间是.NET应用程序的根名字空间,包涵了控制台应用程序所需要的所以基本功能。就如同C++中的头文件包涵在std这个名字空间中一样。
Console.WriteLine ("Hello World!");Console是system名字空间中的一个类,其有一个WriteLine方法,它的作用和cout一样,输出一行字符串。
二.数据类型
C#中的数据类型和C++是类似的。
1.浮点类型
随着.NET的深入人心,作为一个程序员,当然不能在新技术面前停而止步,面对着C++在.NET中的失败,虽然有一丝遗憾,但是我们应该认识到,对于C++其实就不应该对其在.NET中的表现有太大的奢望,因为毕竟它并不是一个.NET下的正统语言。
.NET应该是c#的舞台,作为一个C++程序员,我们应该庆幸,因为我们学习c#其实是简单的直接的,需要我们接受的新知识其实不多,相对其他语言来说,我们应该可以更加平滑的过渡到c#的开发中。废话不多说,现在就让我们用C++的基础来学习这个渐渐壮大的新语言--C#。
对于C#的讲解我只讲解和C++有区别的地方,相同的部分我就一带而过。这样的对比学习可以让我们在已有知识的前提下快速掌握C#。
一.统窥:
一开始学习语言大部分的教程都会用一个Hello World程序来示范,我们也落入俗套,用Hello World来和C++中做一个比较:
C++:
#include <iostream>
using namespace std;
void main()
{
//C++程序
/* C++程序*/
cout<<"Hello World!"<<endl;
}
C#:
using System;
namespace HelloWorld
{
class Class1
{
//C#程序
/*C#程序*/
///C#程序
static void Main()
{
Console.WriteLine ("Hello World!");
}
}
}
一眼看上去两者差不多,心中一阵窃喜,可以说C#对语法的定义更加严格一些。
首先对于程序的进入点,最大的区别就是Main函数的开头必须要大写。因为C#是一个完全面向对象的程序语言,所以它的所有代码都必须定义在一个类中,Main函数也不例外,同时因为.NET程序在编译运行时都是先转为中间语言。
然后中间语言再编译为机器语言,这样的好处有2个:
一.如同Jave一样,写好的程序可以在不同的系统中运行,而不需要改变程序。二.使用不同的语言写的程序,因为要转化为相同的中间语言,所以在程序开发中可以使用不同的程序语言编写,而相互调用。
当使用不同语言开发或者进行分类开发时,各自开发的程序中会出现相同的变量名,函数名等,所以在写C#程序时,必须把程序包涵在一个名字空间内。
定义名字空间使用关键字:
namespace <空间名>
当一个命名空间中的代码需要使用在另一个名字空间中定义的名称,就必须包括对该命名空间的引用,使用点字符(.)
例:
namespace LevelOne
{
//name “A”defined
Namespace LevelTwo
{
//name “A”defined
}
}
这里就定义了两个名字相同的变量,我们可以使用LevelOne.A 和 LevelOne.LevelTwo.A 来独立使用它们,互不干扰。
建立了名字空间后,我们可以使用using关键字来简化对它们包含的名称的访问。和C++中使用using namespace std的含义相似;
对于主函数必须要有限定词static 这表明Main函数是静态的,在内存中只能有一个副本。
第一行中的using System.其命名空间是.NET应用程序的根名字空间,包涵了控制台应用程序所需要的所以基本功能。就如同C++中的头文件包涵在std这个名字空间中一样。
Console.WriteLine ("Hello World!");Console是system名字空间中的一个类,其有一个WriteLine方法,它的作用和cout一样,输出一行字符串。
二.数据类型
C#中的数据类型和C++是类似的。
1.浮点类型
浮点类型中添加了一个精度更高的decimal类型,对于金融方面的程序开发。此种数据类型用来定义钱币。
2.Bool类型
Bool类型的变量只能赋值为:false和true,虽然它们的含义仍然是0和非0,但是在使用中不能再给它们赋值成整数值,在判断语句中.if (bool a==1) 的使用都是错误的。
3.字符类型
Char类型在C#中是16位的,它也不能接收一个整数值
4.整数类型
整数类新中添加了byte(8位无符号整数),sbyte(8位有符号整数),short(16位有符号整数)
long变成了真正的64位有符号整数,它可以用在64位机器的编程中。
uint,ushort,ulong顾名思义是没有符号的整数,它和C++中的unsigned int是一样的,名字换了一下而已。
5.字符串类型
String类型是字符串类型,它是引用的类型,它的使用方法和C++中string的使用相似,可以进行+运算,String类型有一些方法可以给我们使用.例如:ToCharArray() 把字符串放入一个字符数组中 Length 返回字符串的长度等等,可以在MSDN中查找.。
6.类型的转换
C#是一个强类型的语言,它的数值类型有一些可以进行隐式转换,其他的必须显式转换,隐式转换的类型只能是长度短的类型转换成长的类型,例如int可以转换成long,float,double,decimal。反之必须显式的转换。
例:
int a=7;
float b=a;
//隐式转换
long c=12L;
//和C++一样必须加上后缀L才能
定义为long型不然就为int型了
a=(int)c;
//显示转换
使用上面的显示转换不能用在BOOL和string类型上,如果希望string或者bool类型和整数类型之间的转化可以使用一个方法。
Convert.To*****(val)
*****:一种数据类型(具体请参看MSDN)
val:可以是这种类型的变量
例:
int a=123;
string str=Convert.ToString(a);
bool m_bool=Convert.ToBoolean(a);
7.枚举类型
C++和C#的枚举类型,定义相同,使用也相同,只要注意C#中语句最后不需要;结束符,同时定义枚举类型时也不许放在主函数代码段中它只能放在执行代码外面.如下
using System;
namespace HelloWorld
{
enum week
{monday,tuesday,wednesday,thursday,friday,saturday,sunday}
class Class1
{
static void Main()
{
week day=week.friday ;
int a=(int)day;
int b=(int)week.saturday ;
}
}
}
8.指针类型
C++中奉为经典的指针类型,在C#中已经取消了,真不知道这个是一个好消息还是坏消息,不过在易用性方面来说因该是一个进步。不过c#中其实在隐藏了一个指针,我们会在后面说到,同时在C#中也可以包含不安全代码,这些代码就是使用了指针的代码。
9.结构类型
C#中的结构类型看上去和C++没有什么区别,定义使用也相似,但还有有很大的区别的,首先就和枚举类型相似, 最后不需要;结束符,同时定义时也不许放在主函数代码段中它只能放在执行代码外面。
其二最大的区别就是C#中的结构已经和类相似了,C++中的结构是公有的,而C#中是私有的,它和类的区别唯一就是不能继承,但是结构是在堆栈中创建的空间,所以最好是对小量的数据进行操作。
例:
using System;
namespace ConsoleApplication1
{
public struct student
{
public int a;
public double c;
}
enum week
{
monday,tuesday,wednesday,thursday,friday,saturday,sunday
}
class Class1
{
static void Main(string[] args)
{
week day=week.friday ;
int aa=(int)day;
int bb=(int)week.saturday ;
Console.WriteLine ("{0},{1}",aa,bb);
student a,b;
a.a=1;
a.c=1.1;
b=a;
a.c =2.6;
Console.WriteLine ("{0} {1} {2} {3}",b.c,b.a ,a.a ,a.c );
Console.WriteLine ("{1} {0} {3} {2}",b.c,b.a ,a.a ,a.c );
}
}
}
输出结果:
4,5
1.1 1 1 2.6
1 1.1 2.6 1
C#中的输出定位格式和C语言中的printf类似,但更加简洁,不需要在对不同类型的变量使用不同的占位符,只需对应后面跟着的变量,给出序号就可以了。
10.数组类型
数组的定义和C++有区别,看上去很别扭;定义语法为:
<类型>[] <变量名> 例: int[] num;
这样就定义了一个int类型的数组,但是切记它可和C++不同,[]里面可不要写内容哦!int[10] num可是错误的。确定数组的大小有两个办法,一.在定义时指定数据:
例:
int[] num={5,3,7,3}; 二.使用关键字new;例:int[] num=new int[4];
当然两者也可以合起来:
例:
int [] num=new int[4]{5,3,7,3};
注意:前面定义了4个数据,后面花括号里面就必须有4个数据不然就是错误的。
例:
int [] num=new int[4]{4,3} //错误;
对数据的使用和C++一样。
对多维数组的定义和C++是不同的,C++中定义为:
int num[3][4]={1,2,3,4,5,3,2,3,4,2,3,4};
C#中定义为:
int[,] num=new int[3,4]{{1,2,3,4},{5,3,2,3},{4,2,3,4}};
注意:和C++不同C#不能在数据列表中不分类,也就是说不使用{}把一组括起来是错误的,而在C++中是正确的,对数据的使用也相应的变为:
num[2,1]=3;
C#在数组中最富革命性的改变因该是添加了锯齿形数组,例如它可以添加一组{{1,2,3,4},{2,3},{2,3,1}}长度不一样的数据,在C++中只能创建一个[3][3]的数组,在C#中它能够产生这样一个锯齿形数组,第一组中有4个数据,第二组中有2个数组,第三组中有3个,这样可以不浪费内存。
锯齿数组的定义和前面的定义也有区别,它更象是一个数组中包含了一个数组:
int[][] num=new int[3][];
num[0]=new int[4]{1,2,3,4};
num[1]=new int[2]{2,3};
num[2]=new int[3]{2,3,1};
下面是上面的定义的一种简洁写法:
int[][] sum={new int[]{1,2,3,4},new int[]{2,3},new int[]{2,3,1}};
三.变量
变量的使用和作用域和C++类似,没有什么特别需要注意的。
但是首先我们应该看到,现在的程序都是包含在类当中了,也就是说定义的变量都变成了类的私有成员,如果要在别的类中使用变量就需要在定义语句前加上限制符public。
在C++中我们看到过这样在类中声名变量:
public:
int a;
int b;
a,b都是公有的,因为使用了public:,但是在C#中这样的语句没有了,我个人认为这样其实很好嘛,简洁明了。
在C#中必须给每个变量添加限制符:
public int a;
public int b;
C#中的限制符还有一些,如下:
internal:变量只能在当前程序中使用
new:从其他类继承而来的类,并隐藏了该类中的已有字段,这个关键字会在类中介绍.
private:私有的,和C++中含义一样
protected:保护类型,和C++中含义一样
static:静态的,和C++中含义一样
readonly: 只读,在变量初始化以后就不许改变
protected internal:当前程序中使用,或者在派生当前类型的其它类型中被访问,就是双重限定,但只有这一个组合
四.常量
常量的定义使用const关键字,和C++类似。
它和只读限定符的区别:
1.常量是静态的
2.必须在初始化时赋值
真不明白有什么实际的意义,发现C#也是一个累赘的语言。
然后中间语言再编译为机器语言,这样的好处有2个:
一.如同Jave一样,写好的程序可以在不同的系统中运行,而不需要改变程序。二.使用不同的语言写的程序,因为要转化为相同的中间语言,所以在程序开发中可以使用不同的程序语言编写,而相互调用。
当使用不同语言开发或者进行分类开发时,各自开发的程序中会出现相同的变量名,函数名等,所以在写C#程序时,必须把程序包涵在一个名字空间内。
定义名字空间使用关键字:
namespace <空间名>
当一个命名空间中的代码需要使用在另一个名字空间中定义的名称,就必须包括对该命名空间的引用,使用点字符(.)
例:
namespace LevelOne
{
//name “A”defined
Namespace LevelTwo
{
//name “A”defined
}
}
这里就定义了两个名字相同的变量,我们可以使用LevelOne.A 和 LevelOne.LevelTwo.A 来独立使用它们,互不干扰。
建立了名字空间后,我们可以使用using关键字来简化对它们包含的名称的访问。和C++中使用using namespace std的含义相似;
对于主函数必须要有限定词static 这表明Main函数是静态的,在内存中只能有一个副本。
第一行中的using System.其命名空间是.NET应用程序的根名字空间,包涵了控制台应用程序所需要的所以基本功能。就如同C++中的头文件包涵在std这个名字空间中一样。
Console.WriteLine ("Hello World!");Console是system名字空间中的一个类,其有一个WriteLine方法,它的作用和cout一样,输出一行字符串。
二.数据类型
C#中的数据类型和C++是类似的。
1.浮点类型
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数