C+to+Java自动转换系统中C指针的实现
- 格式:pdf
- 大小:270.92 KB
- 文档页数:5
c语言程序设计--指针一、地址1.内存是计算机进行数据运算的物理空间,地址即内存中的指定位置。
2.操作符“&”作用于变量,找到地址。
操作符“*”作用于地址,取得该地址内存中存储的变量。
二、地址应用1.变量地址做函数参数void fun1(int *a){函数体;}int main(){int a=5;fun1(&a);return 0;}2.数组做函数参数void fun1(int a[]){函数体;}int main(){int a[5]={5,4,3,21,7};fun1(a);return 0;}三、指针1.指针是存放变量地址的变量2.声明格式:类型说明符*标识符;3.指针可以指向变量、常量、数组、字符串、结构体、函数。
4.指针需要初始化例:int *a;int num=5;a=#5.指针指向同一变量时可以进行比较运算,例如当两个指针指向同一数组时,比较运算表示比较两个指针在数组中位置的大小。
两个指针相等表示他们指向数组中的同一个元素。
6.指针和整数进行加减运算,编译器会根据所指对象的数据长度对该整数进行放大,char的放大因子为1,int和short的放大因子为2,long和float的放大因子为4,double的放大因子为8。
7.当两个指针指向同一变量时,他们可以进行减运算。
例如,当两个指针指向同一个数组时,他们的差是两个指针之间元素的个数。
相减的结果遵守对象类型的字节长度的缩减规则。
8.指向数组的指针数组在内存空间中的存储是连续的,数组名表示数组的第一个元素的地址。
文章标题:深度探讨C语言中指针对结构体类型转换的影响一、引言在C语言中,指针是一种非常重要的数据类型,它可以指向内存中的某个位置区域,并且可以通过指针来直接操作内存中的数据。
而结构体则是一种用户自定义的数据类型,可以用来存储多个不同类型的数据。
本文将深入探讨C语言中指针对结构体类型转换的影响,并分析其深度和广度。
二、指针和结构体的基本概念在C语言中,指针可以指向不同类型的数据,而结构体则是一种复合数据类型,它可以包含多个不同类型的成员变量。
当我们将指针与结构体相结合时,就会涉及到指针对结构体类型的转换。
三、指针对结构体类型的转换在C语言中,我们可以通过强制类型转换来实现指针对结构体类型的转换。
假设我们有一个指向结构体的指针:```cstruct Student {char name[20];int age;};struct Student *ptr;```如果我们需要将指针ptr转换为指向int类型的指针,可以使用下面的代码:```cint *int_ptr = (int *)ptr;```四、影响及注意事项指针对结构体类型的转换会对程序的正确性和稳定性产生一定影响,因此在进行转换时需要格外小心。
需要确保原始类型和目标类型之间的内存布局是兼容的,否则可能会造成数据的丢失或损坏。
需要避免指针访问越界,以防止意外发生。
要注意遵循C语言的内存访问规则,保证程序的健壮性和安全性。
五、个人观点和理解在我看来,指针对结构体类型的转换是一项非常强大的操作,它可以帮助我们更灵活地操作内存中的数据,提高程序的效率和性能。
但是在实际应用中,需要谨慎使用,并且需要对C语言的内存模型有深入的了解,以免出现意外情况。
六、总结通过本文的深度探讨,我们了解了C语言中指针对结构体类型转换的基本概念和操作方法,并分析了其深度和广度。
我们通过实际的例子和注意事项,指出了这一操作对程序的影响和注意事项,并共享了个人观点和理解。
希望本文能够帮助读者更好地理解并应用指针对结构体类型的转换。
c语言指针使用方法指针是C语言中非常重要的概念,它存储了一个变量的地址,允许你直接访问该地址上的数据。
以下是一些基本的C语言指针使用方法:1. 指针的声明和初始化int main() {int number = 42;// 声明一个整型指针int *ptr;// 将指针指向变量的地址ptr = &number;return 0;}2. 通过指针访问变量的值int main() {int number = 42;int *ptr = &number;// 通过指针访问变量的值printf("Value of number: %d\n", *ptr);return 0;}3. 指针的算术运算int main() {int numbers[] = {1, 2, 3, 4, 5};int *ptr = numbers; // 指向数组的第一个元素// 指针算术运算printf("Value at ptr: %d\n", *ptr); // 输出数组的第一个元素ptr++; // 移动指针到下一个元素printf("Value at ptr: %d\n", *ptr); // 输出数组的第二个元素return 0;}4. 指针作为函数参数// 通过指针修改变量的值void modifyValue(int *ptr) {*ptr = 100;}int main() {int number = 42;// 将变量的地址传递给函数modifyValue(&number);// 变量的值已被修改printf("Modified value: %d\n", number);return 0;}5. 动态内存分配int main() {// 动态分配整型变量的内存int *ptr = (int *)malloc(sizeof(int));if (ptr != NULL) {*ptr = 42;printf("Dynamic memory value: %d\n", *ptr);// 释放动态分配的内存free(ptr);}return 0;}这些例子展示了指针的一些基本用法。
概述在C语言中,结构体是一种自定义的数据类型,可以将多个不同类型的数据组合成一个整体。
结构体指针和结构体实例在C语言中是非常重要的概念,它们之间的转换涉及到指针和内存管理等知识。
本文将深入探讨C语言中结构体指针与结构体实例之间的转换,并共享个人观点和理解。
一、结构体和结构体指针的基本概念1. 结构体的定义在C语言中,结构体是一种自定义的数据类型,可以包含多个不同类型的数据成员。
结构体的定义格式为:```cstruct 结构体名称 {数据类型成员1;数据类型成员2;...};```2. 结构体实例结构体实例是根据结构体定义创建的具体对象。
可以通过以下方式定义和访问结构体实例:```cstruct 结构体名称变量名;变量名.成员 = 值;```3. 结构体指针结构体指针是指向结构体的指针变量。
可以通过以下方式定义和访问结构体指针:```cstruct 结构体名称 *指针变量;指针变量->成员 = 值;```二、结构体指针与结构体实例之间的转换1. 结构体指针转换为结构体实例当我们有一个指向结构体的指针时,可以通过以下方式将其转换为结构体实例:```cstruct 结构体名称 *指针变量;struct 结构体名称实例变量 = *指针变量;```2. 结构体实例转换为结构体指针反之,当我们有一个结构体实例时,可以通过以下方式将其转换为结构体指针:```cstruct 结构体名称实例变量;struct 结构体名称 *指针变量 = &实例变量;```三、深入理解结构体指针与结构体实例之间的转换1. 内存管理在C语言中,指针和内存管理是非常重要的概念。
结构体指针和结构体实例之间的转换涉及到内存中数据的存储和访问,需要对内存管理有深入的理解。
2. 灵活运用结构体指针和结构体实例之间的转换可以使程序更加灵活。
通过指针操作结构体实例,可以方便地对结构体成员进行访问和修改,从而实现复杂的数据操作和算法实现。
程序流程图到代码的自动生成算法程序流程图是一种可视化编程工具,它可以帮助程序员理解和设计算法。
然而,手动编写代码从程序流程图中可能是一项繁琐且容易出错的任务。
因此,人们开发了自动生成代码的算法,从程序流程图中生成代码,大大减少了程序员的工作量,提高了编程效率。
自动生成代码的算法通常基于程序流程图中的节点和边进行解析,将流程图转换成等效的代码语句。
以下是一个基本的算法步骤:读取程序流程图:算法需要读取流程图的每个节点和边。
节点和边通常代表了程序中的操作和流程控制结构。
解析节点:对于每个节点,算法需要确定其类型和参数。
例如,一个节点可能是赋值节点、条件判断节点或循环节点。
每个节点的类型和参数将决定生成的代码语句。
解析边:边用于连接节点,表示程序流程的方向。
算法需要解析边的连接关系,以确定代码语句的执行顺序。
生成代码语句:根据节点类型和参数,以及边的连接关系,算法开始生成代码语句。
常见的基本操作包括条件判断、循环控制和变量赋值。
输出代码:算法将生成的代码语句输出为可执行的程序代码。
值得注意的是,自动生成代码的算法并不是完美的,它可能存在一些限制和挑战。
例如,对于复杂的程序流程图,算法可能无法完全准确地生成代码;另外,生成的代码可能没有最优的性能或可读性。
因此,程序员仍然需要对生成的代码进行手动修改和优化,以确保程序的正确性和效率。
程序流程图到代码的自动生成算法是一种很有用的工具,它可以帮助程序员快速地生成程序代码。
然而,它并不是万能的,需要程序员手动修改和优化生成的代码以达到更好的性能和可读性。
在当今软件开发中,代码的自动化生成是提高生产力和减少错误的关键。
随着和机器学习的发展,流程图代码自动生成算法成为了研究热点。
本文旨在探讨流程图到代码自动生成算法的研究与实现。
流程图是一种可视化编程工具,通过图形符号表示程序的逻辑结构和执行过程。
相比传统文本代码,流程图具有直观、易理解的优点。
而代码自动生成则是将这种可视化逻辑自动转换为可执行的文本代码。
c语言指针函数的用法一、引言在C语言中,指针函数是一种特殊类型的函数,它接受一个指针作为参数,或者返回一个指针作为结果。
通过使用指针函数,我们可以更灵活地操作内存,实现对数据类型的深入理解和掌握。
本篇文章将详细介绍指针函数的定义、调用以及注意事项。
二、指针函数的定义1. 定义形式:类型 * 函数名(参数列表) { 函数体 }2. 说明:类型是指针所指向的数据类型;* 表示这是一个指针函数,即该函数接收一个指针作为参数或者返回一个指针;函数名是自定义的名称,需要符合C语言命名规范;参数列表表示函数的输入参数,可以有多个;函数体包含了函数的功能实现。
三、指针函数的调用1. 形式:指针变量 = 函数名(参数列表);2. 说明:首先需要声明一个合适的指针变量,然后将该变量传递给指针函数,函数执行完毕后,指针变量的值会发生改变。
【示例代码】假设有一个整数数组arr[],我们要找到其中最大的元素并返回其索引。
可以定义一个指向函数的指针变量fp,并将它传递给一个指针函数max_index来找到最大元素的索引。
代码如下:int *fp;int max_index(int *arr, int n) {int *max = arr; // 假设第一个元素是最大值for (int i = 1; i < n; i++) {if (*(arr + i) > *max) { // 比较当前元素与最大值的大小max = arr + i; // 更新最大值}}return max; // 返回最大值的地址}fp = max_index; // 将max_index函数的地址赋值给fpprintf("最大元素的索引为:%d\n", fp); // 调用fp即可输出最大元素的索引四、注意事项1. 指针函数不能没有返回值,否则会编译错误。
如果需要返回一个指针,则需要确保返回值指向的空间足够大。
2. 传递给指针函数的参数必须是合适的指针类型,否则会编译错误。
c语言中指针的用法在C语言中,指针是一种非常重要的概念,它提供了一种间接访问内存地址的方式。
指针可以用于多种用途,如动态内存分配、参数传递、数组操作等。
首先,指针的创建需要声明变量的类型,并在变量名前加上星号(*)。
例如,int *ptr; 就创建了一个名为ptr的指向整型数据的指针。
指针的一种常见用法是动态内存分配。
通过使用malloc或calloc函数,可以在程序运行时分配内存。
例如,int *ptr = (int*) malloc(sizeof(int)); 就创建了一个指向整型数据的指针,并分配了一个整型变量所需的内存空间。
这种方式可以在需要时动态地分配内存,提高程序的灵活性。
指针还可以用于参数传递。
在函数调用时,可以通过指针将一个变量的地址传递给函数,从而可以在函数内部修改原始变量的值。
这种方式称为通过指针进行函数调用。
例如,void changeValue(int *ptr) { *ptr = 10; } 就是一个通过指针修改变量值的函数。
在函数内部,使用解引用操作符(*)来获取指针指向的变量,并对其进行修改。
另外,指针也可以用于数组操作。
在C语言中,数组名本身就是一个指向数组首元素的指针。
通过使用指针算术运算,可以遍历数组中的元素。
例如,int arr[5] = {1, 2, 3, 4, 5}; int *ptr = arr; 就将数组arr的首地址赋给了指针ptr。
然后,可以使用指针进行遍历,如*ptr,*(ptr+1),等等。
指针还可以用于实现数据结构,如链表、树等。
通过指针的相互连接,可以灵活地操作数据结构中的元素。
需要注意的是,指针的使用需要谨慎,因为指针操作容易引发一些错误,如空指针引用、指针越界等。
在使用指针时,应该保证指针指向有效的内存地址,并且在不再使用指针之后,及时释放相关的内存空间。
总而言之,指针是C语言中非常重要的概念,它提供了一种灵活的方式来操作内存地址。
通过正确地使用指针,可以有效地提高程序的效率和灵活性。
c语言指针用法详解一、什么是指针?在学习C语言时,指针是一个非常重要且常见的概念。
所谓指针,就是指向内存位置区域的变量,它能够提供内存位置区域的直接访问。
在C语言中,使用指针可以对内存中的数据进行直接的访问和操作,因此掌握指针的用法对于编程非常重要。
二、指针的声明和初始化在C语言中,指针的声明和初始化非常简单,通常的格式为:数据类型 *指针变量名;例如:int *p;这样就声明了一个指向整型数据的指针变量p。
指针变量的初始化可以通过取位置区域操作符,将某个变量的位置区域赋值给指针变量;例如:int a = 10;int *p = a;这样p就指向了变量a的位置区域。
三、指针的应用1. 通过指针访问变量通过指针可以直接访问变量的数值,即通过指针来操作变量。
例如:int a = 10;int *p = a;*p = 20;这样就通过指针p修改了变量a 的数值为20。
2. 指针和数组在C语言中,数组名本身就是一个常量指针,它指向数组的首位置区域。
通过指针可以对数组进行遍历和操作,实现对数组元素的访问和修改。
3. 指针和函数指针和函数结合使用可以实现函数间的数据传递和数据共享。
通过指针可以将变量的位置区域传递给函数,由函数直接对变量进行操作,从而实现数据的共享和修改。
四、指针的优势和注意事项1. 优势:指针能够直接访问内存位置区域,可以对数据进行直接的操作,提高了程序的灵活性和效率。
2. 注意事项:由于指针直接操作内存,因此在使用指针时需要特别小心,避免出现空指针、野指针等问题,以免引起程序的崩溃和错误。
五、总结回顾通过本文的介绍,我们对C语言指针的用法有了更深入的了解。
指针作为C语言中非常重要的概念,掌握其用法对于编程至关重要。
通过本文的学习,我们可以更加灵活地应用指针来操作变量、数组和函数,提高程序的效率和灵活性。
六、个人观点和理解对我而言,指针是C语言中最重要的概念之一。
通过学习和使用指针,我能够更加灵活地操作内存中的数据,同时也要特别小心避免指针操作中可能出现的问题。
c语言指针通俗易懂讲解摘要:1.引言:指针的概念和作用2.指针的基本操作:声明、赋值、取值、运算3.指针与数组:指向数组元素的操作4.指针与函数:参数传递、返回值5.指针与字符串:指针操作字符串的方法6.指针数组和多级指针:理解与使用7.指针与内存管理:动态内存分配与释放8.指针在C语言编程中的应用实例9.指针使用注意事项与避免错误10.总结:指针在C语言中的重要性正文:一、引言:指针的概念和作用在C语言中,指针是一种特殊的变量,它的值是另一个变量的内存地址。
指针可以用于访问和操作内存中的数据,它在C语言编程中具有广泛的应用。
掌握指针的使用对于深入学习和应用C语言至关重要。
二、指针的基本操作:声明、赋值、取值、运算1.声明:声明指针变量时,需要指定指针指向的类型,如int *p;2.赋值:给指针变量赋值,即指定它指向的内存地址,如p = &a;3.取值:通过指针访问它指向的变量值,如*p = a;4.运算:指针之间可以进行加减运算,如p += 10;三、指针与数组:指向数组元素的操作1.声明:声明指针变量时,可以指定数组名作为指针的值,如int arr[]和int *p = arr;2.访问数组元素:通过指针访问数组元素,如*p = arr[0];3.遍历数组:使用指针遍历数组,如for (p = arr; p < arr + n; p++);四、指针与函数:参数传递、返回值1.参数传递:使用指针作为函数参数,实现数据在函数间的传递,如函数间传递数组;2.返回值:使用指针作为函数返回值,如返回指向数组的指针。
五、指针与字符串:指针操作字符串的方法1.声明字符串指针:char *str;2.取字符串长度:使用指针计算字符串长度,如int len = strlen(str);3.字符串拷贝:使用指针实现字符串拷贝,如char *new_str =strdup(str);六、指针数组和多级指针:理解与使用1.指针数组:一个数组元素是另一个数组的指针,如int arr[2]和int*p[2];2.多级指针:一个指针指向另一个指针,如指针p1指向指针p2,p2指向变量a。
c 一级指针强制转换二级指针的方法首先,我们需要了解一级指针和二级指针的概念。
一级指针是一个指向内存地址的变量,而二级指针则是一个指向一级指针的指针。
在C语言中,一级指针强制转换为二级指针的方法可以通过使用取址和指针类型转换来实现。
下面我们将一步步回答这个问题。
步骤1:了解指针类型首先,我们需要明确一级指针和二级指针的类型。
在C语言中,指针类型的定义是通过在指针变量前添加一个"*"符号来实现的。
例如,int *p1; 表示p1是一个一级指向int类型变量的指针,而int p2; 表示p2是一个二级指向int类型变量的指针。
步骤2:为一级指针和二级指针变量分配内存在进行强制转换之前,我们需要首先创建一级指针和二级指针变量,并为它们分配内存空间。
这可以通过使用malloc()或者calloc()函数来完成。
下面是一个示例代码:cint main() {int *p1;int p2;为一级指针变量分配内存p1 = (int *)malloc(sizeof(int));为二级指针变量分配内存p2 = (int )malloc(sizeof(int *));... 程序的其他部分return 0;}步骤3:进行指针类型的强制转换一旦我们为一级指针和二级指针变量分配了内存空间,我们就可以进行一级指针到二级指针的强制转换。
这可以通过对一级指针进行取址操作(&),然后进行指针类型的转换实现。
下面是一个示例代码:cint main() {int *p1;int p2;为一级指针变量分配内存p1 = (int *)malloc(sizeof(int));为二级指针变量分配内存p2 = (int )malloc(sizeof(int *));将一级指针强制转换为二级指针*p2 = (int *)p1;... 程序的其他部分return 0;}在这个示例代码中,我们首先将一级指针变量p1强制转换为int类型的指针。
C to Java自动自动转换转换转换系统系统系统中中C指针的实现 严忠林 (上海师范大学信息与机电工程学院,上海 200234) 摘 要:C指针的处理是C to Java代码自动转换系统中一个重要而困难的问题。已有的方法大多不能处理含有技巧的指针代码,转换生成的代码难以理解,往往无法正确执行。基于此,提出一种可用Java实现C指针所有功能的方案,该方案在类型转换后不改变原程序结构,并保持尽可能高的运行效率。示例分析表明,运用该方法可使各种类型的C指针运用都能自动转换为执行正确、结构清晰、修改方便、运行快捷的Java代码。 关键关键词词:程序语言转换;C指针;Java引用;数据布局模型;类型转换
Realization of C Pointer in C to Java Automatic Transformation System
YAN Zhong-lin (College of Information, Mechanical and Electrical Engineering, Shanghai Normal University, Shanghai 200234, China) 【Abstract】How to deal with C pointers is an important and difficult issue in C to Java automatic program transformation System. The existing methods are powerless for ingenious C codes. It is difficult to understand codes generated by some transformation system. These codes are not always correct. This paper presents a set of methods. They implements all the functions of C pointer by Java. This transformation keeps original program structure, and runs as fast as possible. Using it can automatically convert various C pointer applications into correct, clear, changeable and efficient Java code. 【Key words】program language transformation; C pointer; Java reference; data layout model; type conversion
DOI: 10.3969/j.issn.1000-3428.2011.16.021
计 算 机 工 程 Computer Engineering 第37卷 第16期
Vol.37 No.16 2011年8月
August 2011
·软件技术与数据库软件技术与数据库·· 文章编号文章编号::1000—3428(2011)16—0062—03 文献标识码文献标识码::A 中图分类号中图分类号::TP311
1 概述 Java是现代许多应用系统开发的首选平台。C语言长久以来已积累了大量优异代码,在Java开发中如能妥善利用,将非常有益于降低成本、提高效率和保证质量。通过程序语言转换系统完成C to Java代码的自动转换,是利用这些资源最直接、有效的方法,由此获得的代码既可直接运行,也可作进一步开发的基础。实现这种转换的最大障碍是对C程序中指针的处理。Java仅提供简单的引用操作。而指针却是C语言中最灵活的数据类型,在程序中用法巧妙、多样。追求高效、灵活的代码一般都离不开指针,它们往往是最有价值、项目开发时最期望获得的部分。但要将各种巧妙的指针运用通过软件自动转换为等效的Java代码,却是一件相当困难的任务[1]。为此,本文提出一种用Java实现C指针所有功能的方案,该方案在类型转换后不改变原程序结构,并能保证运行高效。
2 C指针指针的的特性 每个C指针都有地址和类型双重属性。除了用于确定内存单元,地址还表示数据间的位置关系,可作加减、比较等运算。类型则决定了所访问单元的字节数和对其中二进制位的解释方法。需要时类型可强制转换,甚至能化作整数。这些特性意味着在程序中C指针实际上可指向任何单元,按任意类型模式处理其中的二进制位。这种超强能力结合程序员对数据在内存中排列的准确掌控,能衍生出许多精妙的指针运用。此外,C语言还提供了极灵巧的指向函数的指针。 示例1是一段取自于实际系统的代码,struct Obj是由多
个嵌套成员构造的结构体,组成一个三维数组coll。由于经常要对其中部分数据进行求和、求极值等运算,因此开发一个通用且高效的函数iter()。利用它,语句(1)对从coll[i][j][0]开始的N个对象的x求极值,语句(2)对数组中所有对象的y求总和。代码只有4行,实现非常简练,但要转换为等效的Java,显然不太容易。 示例1
struct Obj {… double y,z; struct Attr {… double w, x; } attr; } coll[L][M][N]; double sum(double x, double y){return x+y;} double max(double x, double y){return x>y?x:y;} double iter(int n, double *d, double (*f)(double, double)){ double r=*d; struct Obj *t=(struct Obj *)d; while (--n>0) r=f(*(double *)(++t), r); return r; } a=iter(N, &coll[i][j][0].attr.x, max); (1) a=iter(L*M*N, &coll[0][0][0].y, sum); (2)
基金项目基金项目::上海市教委基金资助项目(05DZ14) 作者简介作者简介::严忠林(1964-),男,讲师、硕士,主研方向:Java应用,软件转换技术 收稿日期收稿日期::2011-01-15 E-mail:yan-zl@shnu.edu.cn 第37卷 第16期 63 严忠林:C to Java自动转换系统中C指针的实现 已有的代码自动转换系统,如c2j、C To Java Converter、Jazillian[2]等,在指针处理上大多仅作一些简单变换。如将*p转换成p,用p.x替换p->x;有时也用数组引用a加下标i来代替指针p,这样p++就变成了i++,*p可改写为a[i]。很明显,这些方法仅能应付最基本的指针运用,对稍有技巧的代码无能为力。也曾出现过一些复杂方案,如把所有变量都分配在一个Object[]中,或专门定义一些能包容各类型数据,描述它们嵌套关系的数据块类来支持指针运算[3]。它们能转换更多的代码,但会破坏原程序的数据表示,给理解、修改代码带来困难。而且依然存在着无法处理的C指针应用。 本文提出的转换方案支持C指针的所有功能,并尽可能保持原程序的数据表示。数组用相同结构的Java数组代替;struct/union型变量在定义相应的类后,用类实例表示;基本类型变量保持不变,但需要通过指针访问的基本型变量,转换为自定义的包装类的类实例;只有指针型变量要用到新的数据类型,要为它引入反映位置关系的地址概念,并提供进行数据访问、加减比较、类型转换等各种操作的能力。 3 变量位置变量位置关系的关系的关系的表示表示 指针的地址属性反映了程序运行时各数据在内存中的分布。对复合数据,C语言根据类型有不同的排列规则。数组元素按下标顺序,无空隙地“连续”排列,用指针可方便地遍历。struct元素按定义的次序“顺序”排列,各元素距起始位置有固定偏移量。union最特殊,每个元素“重合”排列,访问不同成员实际处理的是同一个二进制串。C语言还规定指向数组、struct的指针指向它们首元素所在的位置,运行时可转换为首元素类型的指针。许多指针代码的编写都依赖于这些C语言特有的数据布局模型[4]。 为在Java中表示这些位置关系,专门定义了类Location。它采用“顶层数据块引用(Object base)+距顶层块起始位置的偏移量(int offset)”来表示变量地址。顶层块可嵌套包含其他构造块,各成员的位置关系用offset表示。它按C规则确定,数组内元素由其下标推算,struct中成员按定义次序确定,union的各成员总是与其首元素相同。在与struct对应的类定义中还有描述其全部成员组成的类变量,帮助实现成员和offset间的映射。对于Java中没有对应结构的union,通过定义包含各成员的类来实现,并在对象中设置专门变量,记录当前有效数据的对应情况。存取时参照该信息,如不一致,就作必要的转换,确保总能获得正确的数据。 有时,要知道不属于同一顶层块的各变量间的位置关系,或者要将一指针转化为整数,这都要求确定顶层数据块base的起始地址。在与实现无关的程序中,该数值的实际大小是无关紧要的,只需保证运行时不变,以后反转过来仍可得到原对象即可。因此,在Java中为有如此需求的base任意指定一整数区间作为其存储空间,该整数可以是除0以外的任何值,但不和已分配的区间冲突。用一个键/值对记录这种对应关系,为防止妨碍Java自动回收无用对象,要使用弱引用(Weak Reference)来连接base。再用一容器保存所有的键/值对,需要时既可从中获得base对应的地址,也可作逆转换,由地址求得对应的base +offset。在这里,整数0仍然表示空指针。这样,用base+offset可完整地表示C指针的位置信息,Java运行时可据此访问需要处理的数据。 4 强制强制类型转换类型转换类型转换的处理的处理 C指针允许强制类型转换,它不改变指针所指向的位置,但会导致+、-等运算处理的改变,其中最关键的是由*操作符引起的存取操作。例如,任意指针转换为浮点数指针,就是要按照浮点数的阶码+尾数格式处理它所指向的字节块,而不管它本来的意义。因此,强制类型转换可以基于字节块实现,将原本任意类型的数据当作字节块,再转为需要的类型。 这种处理用Java实现是低效的,但C程序一般不会做毫无道理的转换。例如,程序中如要将指向结构体的指针转换为整数指针,该结构体的首元素通常就是一整数。这种转换不需特别处理,利用原有的位置信息就能得到希望的数据。因此,基于字节块的转换应尽量延迟。 如确有必要作这种转换,由base+offset可获得相应数据,进而得到需要的字节,问题的关键是能按照不同类型对其进行正确的访问处理。对于基本数据类型指针,使用JavaAPI就可直接实现。对于各种struct/union型指针,要为每个类型定义一接口,其中包含成员存取、整体复制等C程序对该型变量所有可能的操作。然后用Java的Proxy创建实现该接口的动态代理类。它对任一字节块,根据类型结构信息,用相应位置的字节数据来实现这些方法。通过这一接口,任何数据块,都可当作该struct/union型变量使用,指向任意字节块的指针当然也都可转换为该类型的指针。类似地,对记录位置信息的Location类,也定义一接口,参照整数和base+offset间的关系作相似处理,这样,任意数据都可强制转换为指针,多级指针的处理也就实现了。指向数组的指针比较特别,使用*运算符,获得的是指向其下一维元素的指针,这本身就是一次指针类型转换。因此,对数组型指针不需特别处理,只要等到使用时再转换为需要的类型即可。综上所述,各种类型指针的强制转换都是可以实现的。