c# 与c 的一些感受

这几天在写c#调用c编写的dll,感觉很痛苦,因为c有两年没写了,c#只听过。它们最让我感到痛苦的是指针。大家都知道函数参数分为值类型和引用类型。在c中值类型传递参数时是先复制一份,然后将复制的传给函数,所以在函数中操作的是复制的参数,不会改变原来的值。但是当参数是数组时,有点不一样,它不会将整个数组复制传过去,它只是传一个地址过去,这样做的好处是可以节省时间。引用类型就不说了,就是一个地址。前面说的是c语言的。

c#是分托管和非托管,托管的意思是它自动管理资源,会自动释放内存,可以进行垃圾回收的功能,而非托管的,在应用程序中使用完这些非托管资源之后,必须显示的释放他们​。在定义数据的时候都要声明类型,作用是表示这个数据在内存中占多少字节,在使用的时候,先找到这个数据的地址,然后按该类型的​长度,读取相对于的长度,然后在处理。随意,对于不同语言之间的互调,只要将该数据的指针(内存地址)传递给另一个语言,在另一个语言中根据传过来的指针取所指向内存的数据存储长度进行操作就行了,不过由于虚拟机会让堆内存来回转移,因此,在进行互调的时候,要保证正在被互调的数据所在的内存一定要固定,不能被转移。但是c#恰好不满足,它char的字符与c有点不同,一般是一个字节代表一个字符,但是c#却是两个,导致的结果是在它们互相操作同一个字符数组时,会出现诡异的情况。所以在c#和c互相使用指针操作字符数组时,要小心。还有就是c#操作指针时,要在unsafe的状态下使用:

unsafe{

int * p ;​

}​

而指向数组的指针有点蛋疼​,首先使用 unsafe关键字,它允许在 Copy 方法内使用指针,在用 fixed语句,用于声明指向源数组和目标数组的指针。这将锁定源数组和目标数组在内存中的位置,使其不会因为垃圾回收操作而移动。这些内存块将在 fixed 块结束时取消锁定。

  char[] zz1 = new char[7] { '1', '2', '1', '2', '1', '2','1'};

 fixed (char* vv = zz1)

 {

 test(vv);

  }

在c#中,char是unicode编码为16位,所以为2个字节,而其他的一般是非unicode编码,为一个字节。​


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值