c语言移植到java语言时应注意的要点


作者:hunhun1981
出自:http://blog.csdn.net/hunhun1981/

做过几次c语言向java移植的项目,深切体会到它决不是想像中那么简单。在此记录下移植过程中让我最头疼的一些事,忽略掉一些基本的知识点,请见谅。(并且在此强烈鄙视那些自以为是的家伙,曾经请教过很多人都说简单,但我现在可以很肯定的说这些人都没真正做过项目的移植,特别是算法型的项目。)

按照我现在形成的移植习惯,拿到一个新的算法包,自然应该先了解其结构,尽量从程序入口下手。
1,创建一个可用的调试环境(j2me项目最好先采用j2se的环境来做,应为它的调试可以定位到出错的具体位置,而开发j2me时大部分sdk都是不行的)。
2,备份文件,然后改名为*.java文件,使用带有检查功能的IDE打开文件,推荐eclipse3.x(如果您坚持要使用记事本,那么下面的内容请不要再看了,太弱智)。
3,从入口函数开始,按调用顺序逐个打开文件进行翻译。
a,拷贝头文件中定义的变量,常量以及结构体等等。
b,简单语法和基础数据类型的替换。
c,数组指针转换为索引。
d,malloc等内存分配函数的替换,以及创建对象(结构)数组是的初始化问题。
c,函数参数的修正。

4,测试和分析,以上基本能够让代码能够调试,接着最困难的部分是测试以及分析对象赋值的深浅拷贝问题。

下面简单说说以上步骤中特别需要注意的问题。
1,语法替换时,千万要小心,难度不大,但是绝对能搞得你手软。
比如删除*号和&符号,不能使用查找替换,每一步都要小心判断,并不是所有变量前的*号和&号都删除。除非自己能够确定它的作用,有些*属于数组,有些属于变量,必须区分对待。不然会影响后面的工作,直接导致项目失败。

2,发现结构数组的定义时,一定要小心。
比如c中的:
Point *p = new Point[10];
和java中的:
Point[] p = new Point[10];
c中的数组在new的时候就已经分配空间,但java中只是创建了数组,并没有创建Point对象。
java中可以这样干:
Point[] p = new Point[10];
for(int i = 0;i < p.length;i++){
p[i] = new Point();
}
当然可以自己写个函数包装一下。

3,注意函数的参数传递情况,c语言中使用一下引用就可以在函数中修改参数的值,java中也可以,但是int,short等基本类型除外。
比如c中的:
void func(int *p){

}
…调用时使用func(&x);就可以在函数内部修改x的值。在c中,经常见到这样的函数。很让人恶心。
java中的参数都是引用传递,但是如果是基本类型,而不是对象类型,就不可能改变实参的值。
例如上面的函数我们在java中可以改写为:
void func(Integer p){

}
或者
void func(int[] p){

}
只要对原来的p稍微进行加工,就可以了。当然,如果这样零散的变量多,或者经常用。可以自己创建一个对象使用这个对象来传递实参。
例如:
public class Param{
int x;
int y;
}
这样在参数传递时,可以直接传递Param对象,然后在引用的时候做一些调整。

4,malloc等函数可以直接使用new替代,但是对象(结构)数组的初始化例外,因为new不会初始化对象,它只处理数组的初始化。对于realloc,可以使用Vector替代,前面的文章已经介绍过Vector,请认真理解之后再使用。

5,数组指针与索引的变换。c语言中经常使用数组的指针来遍历数组,甚至还会将这个指针单独传递到某个函数中使用,这样的效果相当于把数组的一部分传递到函数中。……
所以我们得把指针该成索引,传递参数时,将数组跟索引都一起传递过去,就可以达到跟前面一样的效果。
例如:
int num[] = {1,2,3,4,5};
int *p = num;
应该把p改成
int p = 0;
然后把使用p的地方替换成num[p],p++这样的操作不变。

6,最最重要的一个问题,就是深拷贝。请看如下代码
Point p1 = …
Point p2 = …

p1 = p2;

在c转换到java时,这个代码会给程序带来灾难性的后果。它隐蔽,很难发现,不报错,只会影响结果错误。
在c中,p2会赋值给p1,此时如果再改变p2,p1则仍然是原来p2修改前的值。
但java中不这样,p1 = p2;只是把p1指向了p2,原有的p1对象,如果没有别的引用,将会被释放,此时,p1,p2同事指向p2的对象,改动p2则p1跟着变,因为它们指向一个对象。
怎么修改呢?我们可以自己写一个深拷贝的函数,根据p2的值重新创建一个对象,再让p1指向它。
这个问题改起来并不难,但是难于发现。一个赋值语句很容易被忽视。我也没有什么好办法,看来只有仔细调试代码了。当然,大家可以在进行前面工序的时候多个心眼。

总之,以上的东西说起来都不难。但是往往就是这些问题给我们造成了极严重的后果。移植技巧当然不止就这些,真要写起来还是很烦的,一时也想不起来。有兴趣的朋友可以多讨论一下。 

更多信息,请关注hunhun1981的专栏

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值