`
liujunsong
  • 浏览: 77584 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java中如何模拟指针操作,以迁移C++代码

阅读更多
1.前言
前段时间做了一项重要的工作,就是将原来开源的ICTCLAS的C++代码,全部迁移到了Java语言重新实现,在迁移完成以后,初步测试没有啥大问题,在此过程中得到了一点小小的经验,特记录下来,以供大家参考。

2.问题的分析
虽然说Java语言是从C++演化过来,语法关键词基本类似,但C++语言和Java语言相比,有一个最为关键的不同,就是Java不支持指针,无法直接进行地址的计算,这样的话,就给代码迁移带来了很大的困难。
例如下面这段代码,是C++的原始代码。
bool CContextStat::GetItem(int nKey,PMYCONTEXT *pItemRet)
{//Get the item according the nKey
	PMYCONTEXT pCur=m_pContext,pPrev=NULL;
	if(nKey==0&&m_pContext)
	{
		*pItemRet=m_pContext;
		return true;
	}
	while(pCur!=NULL&&pCur->nKey<nKey)
	{//delete the context array
		pPrev=pCur;
		pCur=pCur->next;
	}
    if(pCur!=NULL&&pCur->nKey==nKey)
	{//find it and return the current item
		*pItemRet=pCur;
		return true;
	}
	*pItemRet=pPrev;
	return false;
}


在这段代码中,要将这段代码使用Java来实现,最为头疼的地方就是*这个操作符号了,因为Java里面不能直接操作内存地址,因此必须采用转换的方式来进行模拟实现。

3.解决思路
在C语言里面,*操作符号和&操作符号是相对的,一个用来将指针所在地址赋值,一个用来获取一个内存地址。而在Java里面,内存地址是无法直接访问,也无法直接获取的。
因此在上面的例子中,我们首先定义一个PMYCONTEXT类。这个类代表一个一级指针。
/**
 * PMYCONTEXT的定义是一个指向结构体MYCONTEXT的指针, 是一个一级指针
 * @author liujunsong
 * 
 */
public class PMYCONTEXT {
	public MYCONTEXT p=null;// The chain pointer to next Context
	/**
	 * 带参数的构造函数
	 * @param tag
	 */
	public PMYCONTEXT(MYCONTEXT tag){
		p=tag;
	}
	
	/**
	 * 得到下一个节点,通过封装p来实现。
	 * @return
	 */
	public PMYCONTEXT next(){
		if(p!=null){
			return p.next;
		}else{
			return null;
		}
	}
	
	/**
	 * 从当前节点开始,递归到各个下级节点,然后释放所有链表的内存
	 * 这个方法用来释放内存。
	 */
	public void DestroyAll(){
		PMYCONTEXT pCur=next(),pTemp;
		//递归清理所有下级的节点
		while(pCur!=null){
			pTemp=pCur.next(); //得到下一节点			
			pCur.p.Destroy(); //当前节点内存释放
			pCur=pTemp; //指向下一节点
		}
		//清理本级指针对应节点
		if(p!=null){
			p.Destroy();
			p=null;
		}
	}
	
}

但在原来的C语言代码中,输入参数采用PMYCONTEXT *pItemRet的方式,实际上定义了一个二级指针出来,而Java不支持这样的直接定义,所以我们需要另外一个专门的二级指针对象,来模拟这个C语言里面的二级指针对象。
/**
 * 一个指向MYCONTEXT的二级指针
 * @author liujunsong
 *
 */
public class PPMYCONTEXT {
	public PMYCONTEXT p=null;
	
	/**
	 * 唯一可用的构造函数,可以传入一个null
	 * @param point
	 */
	public PPMYCONTEXT(PMYCONTEXT point){
		p=point;
	}
	
	/**
	 * 重新设置指针的值,这一方法不会生成新的PPMYCONTEXT对象
	 * 也不会重新分配内存。
	 * @param point
	 */
	public void setValue(PMYCONTEXT point){
		p=point;
	}	
}

有了这样一个对应的二级指针定义以后,就可以直接上面提到的C++语言代码,直接迁移改造成同等算法的Java代码,结果如下:
	/**
	 * 利用给定的key值,来检索一个MYCONTEXT对象,返回一个ppItemRet,二级指针
	 * <P>
	 * 在二级指针中设置指针的数据,不新增加内存。
	 * 
	 * @param nKey
	 * @param pItemRet
	 * @return
	 */
	private boolean GetItem(int nKey, PPMYCONTEXT pItemRet) {
		// Get the item according the nKey

		PMYCONTEXT pCur = _copy(m_pContext), pPrev = null;

		if (nKey == 0 && !_isNullPoint(m_pContext)) {
			pItemRet.setValue(m_pContext); // 如果nkey==0,返回头元素
			return true;
		}

		// pCur有效的情况下,循环查找,来按照nKey来查找
		// 此处代码有一个bug,假设是按照nkey来排序的
		// 但在Add的时候并没有进行排序处理
		// 所以要修改一个判断条件为不相等
		while (_isNotNullPoint(pCur) && pCur.p.nKey != nKey) {
			pPrev = _copy(pCur);
			pCur = _copy(pCur.next());
		}

		// 循环结束,判断循环结束点
		if (_isNotNullPoint(pCur) && pCur.p.nKey == nKey) {
			// find it and return the current item
			pItemRet.setValue(pCur);
			return true;
		}

		pItemRet.setValue(pPrev); // 设置最后一个有效节点
		return false;
	}

修改完成以后经过测试,程序运行正常。

4.小结
ictclas本身代码量有将近1M,原来的数据结构设计的非常严格,算法设计的也很巧妙,对于指针的使用非常频繁,几乎没有一段代码不涉及到指针的使用,采用上面这种方式进行数据结构的模拟,指针的模拟以后,在很短的时间内就将全部代码迁移到了Java语言重新实现。经过初步测试,系统功能完全正常。
同时由于存在一个作为样板目标的C++代码存在,当系统发生异常的时候,可以很方便的进行代码比较跟踪,查看那里修改算法出现了错误,这样就提高了程序开发的效率和质量。
欢迎大家下载本blog发布的ictclas,Java改写版本,其中附带有C++源代码,可以对比查看,确定效果如何。
如果大家还有其他C++代码迁移的案例,欢迎一起来讨论学习。
分享到:
评论

相关推荐

    C++代码转java工具

    然而,需要注意的是,由于C++和Java的语法和语义差异,直接的转换可能会遇到挑战,比如C++的模板、指针、运算符重载在Java中没有直接对应的概念,因此可能需要手动调整转换后的代码。 描述中的重复信息进一步强调了...

    C++转换JAVA工具

    "C++转换JAVA工具" 提供了一种解决方案,使得开发者可以从C++代码无缝过渡到Java代码,或者将Java代码转换为C++,以适应不同的开发需求和环境。这种工具的主要目标是提高开发效率,降低维护成本,以及实现平台间的...

    CPlus_to_Java_Converter;C++转java工具

    1. **数据类型转换**:C++中的指针在Java中通常对应于引用。转换器需要将C++的指针操作转换为Java的引用操作,同时处理内存分配和释放的差异,因为Java的垃圾回收机制会自动管理内存。 2. **面向对象的差异**:C++...

    c++ 转换 java c# 转换 java c++ 转换 c#

    C++中的模板、指针操作、运算符重载等功能在Java中没有完全对应的概念。转换时,C++的类需要映射到Java的类,指针通常会转化为Java的引用,而内存管理则从手动管理(C++的new和delete)转变为自动垃圾回收(Java的GC...

    C++,java互转

    例如,C++中的指针需要转换为Java的引用,C++的多态通常通过虚函数实现,而在Java中则利用接口和继承。此外,C++的模板和STL容器需要转换为Java的泛型和集合框架。 Java2Cpp是一款用于将Java代码转换为C++的工具,...

    C转java工具

    该工具的基本工作原理是:首先,它会读取C源代码文件,然后对C语言的语法结构进行分析,包括变量声明、函数定义、循环、条件语句、指针操作等。接着,它将这些结构映射到相应的Java语法,例如,将C中的指针转换为...

    Java语言与C++语言的对比分析.pdf

    指针类型数据在C++中非常常见,通过指针变量能够直接操作内存地址。 C++语言的应用主要表现在跨平台开发上。C++要求进行代码编译,编写策略制定时需要考虑跨平台的兼容性。C++程序的开发需要根据目标平台的不同进行...

    Java to C++ translator.zip

    转换器需考虑如何在C++中实现Java的并发特性。 7. **标准库和第三方库**:Java和C++都有各自的标准库,转换器需要考虑如何替换或映射这些库的功能。 8. **模板和泛型**:C++的模板可以用于创建类型安全的函数和类...

    巧妙规避Java与Ruby语言迁移过程中的风险

    然而,Java的复杂性,如C++风格的指针操作和内存管理,可能会带来学习曲线陡峭和潜在的代码错误问题。这些问题增加了采用Java的风险,尤其是在对性能要求严格的环境中。 相反,Ruby语言,特别是与Rails框架结合,因...

    顺序队列实现源码(C、C++、Java)

    在C++中,可以定义一个顺序队列类,包含数据成员如数组和头部、尾部指针,以及入队、出队、检查队列是否为空等成员函数。C++标准库中的`std::vector`也可以方便地用来实现动态数组,从而简化了数组大小的管理。 3. ...

    Java programming for C/C++ developers

    - 在Java中,一些C/C++中常见的特性如指针、全局变量和预处理器不存在,这要求开发者学习新的编程模式和实践。 - 需要特别注意的是,Java中的对象处理方式与C/C++大相径庭,Java通过垃圾回收机制自动管理内存,而C...

    解析成java代码

    例如,将C++代码解析为Java时,我们需要考虑C++的指针和模板如何映射到Java的引用和泛型。 此外,对于特定的数据格式,如XML或CSV,解析的目标可能是生成Java类,这些类可以方便地与这些格式交互。例如,当我们解析...

    Java大作业

    1. **简单性**:Java 简化了 C++ 中的一些复杂特性,如指针,以提高程序的安全性和易读性。 2. **面向对象**:Java 是一种纯面向对象的语言,它支持封装、继承和多态等面向对象特性。 3. **健壮性**:Java 通过严格...

    Java编程语言在大数据开发中的应用.pdf

    与C语言和C++语言相比,Java摒弃了难以理解的指针、运算符重载、多重继承等特性,增加了垃圾回收机制,减少了程序对内存的需求。同时,Java还引入了异常处理、泛型编程、类型安全和自动装拆箱等特性,从而提高了程序...

    java 基础教学

    此外,Java语言虽然在很多方面和C++类似,但它更加简洁,去除了指针、typedef、预处理器、结构体、联合体、多重继承、goto语句、运算符重载、自动类型转换以及全局变量等概念。这使得Java编程更加安全,更容易学习和...

    Java Web 开发教程

    在C/C++等语言中,指针操作需要格外小心,因为错误的指针操作可能导致严重的系统安全问题。Java语言取消了指针操作,不允许直接访问内存,所有的内存操作都由Java虚拟机负责管理。这样的设计大大提高了程序的安全性...

    计算机软件Java编程特点及其技术分析 (1).pdf

    这一特点大大提高了Java程序的可移植性,使其能够在不同的硬件平台和操作系统间轻松迁移。 Java语言的易学性也是它广受欢迎的原因之一。对于有C或C++背景的开发者来说,Java的语法结构和这两种语言非常相似,因此...

    完整版 Java基础入门教程 Java程序语言设计 01 java语言基础 Java语言概述(共24页).ppt

    1. **简单**:Java的语法简洁且类似C++,但避免了指针和多继承等复杂特性,以减少错误的可能性。内存管理采用自动垃圾回收机制,降低了程序员的负担。 2. **面向对象**:Java中一切都是对象,支持封装、继承和多态,...

    JAVA语言入门(CHM) JAVA语言入门(CHM)

    1. **简单性**:Java简化了许多C++中的复杂特性,如指针。 2. **面向对象**:Java完全支持面向对象编程(OOP),包括封装、继承和多态等特性。 3. **健壮性**:Java通过严格的编译时检查和运行时异常处理机制来提高...

Global site tag (gtag.js) - Google Analytics