Category Archives: Programming

C#内存管理

值类型,引用类型

string,class为引用类型,其他是值类型。值类型分配在栈上[1],引用类型分配在堆上。


堆栈

值类型分配在栈上,局部变量直接存储值。引用类型分配在托管堆,栈上存储一个地址在局部变量引用堆内存。

例如:

Person foo = new Person();

foo存储一个4字节地址,引用堆内存Person分配的空间。

int bar = new int(); 

因为bar是值类型,所以new分配在栈上[2],并且值类型bar直接存储的数据。

[1]《深入理解C#》中提到, 值类型一定分配在栈上并不准确。值类型是跟声明的对象一起放在一起存储的,作为引用类型class的成员的时候跟着class放在堆上。

[2]这点和C++语言不同,new是堆分配关键字,调用new即分配在堆上。


垃圾回收

堆上的内存没有引用会在垃圾回收的时候回收,垃圾回收会暂停其他线程,会压缩重排堆内存以减少碎片。

装箱拆箱

装箱会在堆上分配内存,把栈上的值拷贝的堆上。

拆箱会在栈上分配对象,把堆上的内存拷贝到栈上。栈上的类型和拆箱的类型不一致会报错。

2D坐标系中旋转一个点

2D坐标系中一个点x, y逆时针旋转角度θ后新坐标点x’, y’位置。要用到三角和公式:

cos(Ф+θ) = cosФcosθ – sinФsinθ

sin(Ф+θ) = sinФcosθ + cosФsinθ

查看源图像
Image from 2-D Transformations. Kurt Akeley CS248 Lecture 7 

由上图,运用三角和公式后,将r·cosФ代入为x, r·sinФ代入为y,就可以通过x, y坐标得出新的x’, y’坐标了:

x’ = xcosθ – ysinθ

y’ = xsinθ + ycosθ

顺时针旋转可以理解为逆时针一个负角度,根据sin(),cos()的奇偶性,即sin(-θ)=-sin(θ),cos(-θ)=cos(θ),可得顺时针旋转的变换公式:

x’ = xcosθ + ysinθ

y’ = ycosθ – xsinθ

另一个问题,三角和公式怎么推导出来。下图用几何法证明了三角和公式的推导:

Reference:

平面内直角坐标系中坐标旋转变换公式https://blog.csdn.net/sinat_33425327/article/details/78333946

两角和差的正余弦公式的若干证明方法https://zhuanlan.zhihu.com/p/361839484

https://www.slideserve.com/kirima/chapter-4-2-d-transformations-cartesian-coordinates