这篇文章主要介绍“C#中的固定和活动变量介绍”,在日常操作中,相信很多人在C#中的固定和活动变量介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C#中的固定和活动变量介绍”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
&和fixed将变量分为两类:C#固定的和活动的变量。
固定的变量***的存在并不会被GC的操作影响。(例如局部变量,值参数和间接指针)活动的变量会被GC重新分配位置或是释放(例如对象中的字段,基础数据数组)。
&取固定变量的地址是没有限制的。但是活动变量容易受GC的影响,其地址只能通过fixed来获得,并且地址仅会在整个fixed语句的周期持续有效。
静态字段也是活动变量。还有标记为ref或out的也是活动变量,即使这个参数是传递给固定参数的。***,通过间接指针引用的变量总是固定变量。
指针转换
在不安全上下文中,下面的转换是隐式的:
◆从任何指针类型到void*
◆从null到任何指针类型
除此之外,下面的转换都是显式的:
◆从任何指针类型到另外的指针类型
◆从sbyte, byte, short, ushort, int, uint, long, or ulong到其他类型
◆从任何类型到sbyte, byte, short, ushort, int, uint, long, or ulong
指针转换并不改变指针的值。也就是说指针转换前后不影响地址的值。
当转换发生后,当结果指针没有按照正确的指针类型排列的话,当访问结果时结果是无法预知的。
下面的例子:
char c = 'A'; char* pc = &c; void* pv = pc; int* pi = (int*)pv; int i = *pi; // undefined *pi = 123456; // undefined
下面的例子会打印出double的8字节的值:
usingSystem; classTest { unsafestaticvoidMain(){ doubled=123.456e23; unsafe{ byte*pb=(byte*)&d; for(inti=0;i<sizeof(double);++i) Console.Write("{0:X2}",*pb++); Console.WriteLine(); } } }
打印结果取决于endian.
指针数组
在不安全上下文中,是允许指针数组的,只有几种用于其转换是允许的:
◆从任何数组类型到System.Array或是实现了其接口的隐式引用类型转换同样适用于指针数组。但是,任何试图通过System.Array或是实现了其接口访问数组元素都会引发一个 运行时错误,因为指针类型不能转化为object.
◆从一个一维数组类型S[]到System.Collections.Generic.IList<T>或是到其基接口,任何显示或是隐式的转换都是不行的。因为指针类型不能被用作类型参数,还有没有从指针类型到非指针类型的转换。
◆从System.Array或是实现了其接口到任何数组类型显示引用转换适用于指针数组。
◆从System.Collections.Generic.IList<T>或是到其基接口到一个一维数组类型T[],任何显示的转换都是不行的。原因同上面第2条。
还有就是对于foreach语句,不适用于指针数组。相反,下面的语句
foreach (V v in x) embedded-statement
中的x是一个数组类型T[,,…,],n是数组的维度减1,T和V是指针类型,被改写为:
{ T[,,…,]a=x; Vv; for(inti0=a.GetLowerBound(0);i0<=a.GetUpperBound(0);i0++) for(inti1=a.GetLowerBound(1);i1<=a.GetUpperBound(1);i1++) … for(intin=a.GetLowerBound(n);in<=a.GetUpperBound(n);in++){ v=(V)a.GetValue(i0,i1,…,in); embedded-statement } }
变量a,i0,i1,…对于x或者embedded-statement或者其余部分的代码是不可见的或是不可访问的。变量v在embedded-statement中是只读的。如果没有显示转换从T到V,那么就会有错误。如果x是个null,就会有空引用异常。
表达式中的指针
在不安全上下文中,一个表达式的值可以来自于一个指针类型;但是在上下文之外,会造成编译时期错误。
间接访问
一元的*表示一个指针,被用来获得指针指向的值。*用在void*类型表达式或是非指针类型表达式时,会造成编译期错误。
*被用在null指针时是由实现来决定的。不能保证在使用时会抛出System.NullReferenceException.
如果一个非法的值赋给指针,那么*的行为是不可预知的。
指针成员访问
在指针成员访问P->I中,P必须是除了void*之外的类型,I同时必须是一个可访问的成员。
P->I效果上相同于(*P)。I.例如:
usingSystem; structPoint { publicintx; publicinty; publicoverridestringToString(){ return"("+x+","+y+")"; } } classTest { staticvoidMain(){ Pointpoint; unsafe{ Point*p=&point; p->x=10; p->y=20; Console.WriteLine(p->ToString()); } } }
或是
classTest { staticvoidMain(){ Pointpoint; unsafe{ Point*p=&point; (*p).x=10; (*p).y=20; Console.WriteLine((*p).ToString()); } } }
指针元素访问
在指针元素访问P[E]中,P必须是除了void*之外的类型,同时E必须能隐式的转换为int, uint, long, or ulong的表达式。
P[E]效果上同*(P + E)。例如:
classTest { staticvoidMain(){ unsafe{ char*p=stackallocchar[256]; for(inti=0;i<256;i++)p[i]=(char)i; } } } 又如: classTest { staticvoidMain(){ unsafe{ char*p=stackallocchar[256]; for(inti=0;i<256;i++)*(p+i)=(char)i; } } }
到此,关于“C#中的固定和活动变量介绍”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。