@Azoros,
您的代码适用于整数,因为您将指针类型定义为整数。当您将指针类型定义为双精度时,处理器将尝试将每个元素作为双精度数据类型处理。内部整数和双精度数使用不同的格式存储。这就是为什么当您尝试从双精度数据类型中检索整数值时它不起作用的原因。
所以,如果我正确理解了您的问题,您希望将一个数组的零元素定义为一个包含数组长度的整数。其余元素需要保存可能与第一个元素不同的数据类型的数据值。
我会通过将数组指针定义为字节数组 (void *) 来解决这个问题。然后在访问元素时,我会告诉处理器它正在处理什么数据类型。
这是在实践中的做法:
将指针定义改为字节指针。
void* array;
将数组分配到包含数组长度元素和数据元素的大小。
array = calloc(1, INT_SIZ + (noe * soe));
将大小值移动到数组的第一个位置。请注意,在 Windows x86 机器上,这将复制 4 个字节的数据。
memcpy(array, (void*)&noe, INT_SIZ);
返回第一个元素大小的内存地址偏移量。在 x86 机器上,这将偏移 4 个字节
return (void*)(((int*)(array)) + 1);
这里是使用修改后的 createArray 例程的完整代码。
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# define INT_SIZ sizeof(int)
# define GetSize( pt ) ((int *)pt)[-1]
# define GetElement( pt, etype, idx ) ((etype *)pt)[idx]
# define InsertElement( pt, etype, idx, val ) \
{ \
etype temp = val; \
memcpy ( (void *) &((etype *)pt)[idx], &temp, sizeof(etype) ); \
}
void * createArray(int noe, /* Number of elements */
int soe) /* Size of element */
{
void *array;
/* Allocate the array */
array = calloc(1, INT_SIZ + (noe * soe));
if ( array == NULL ) return NULL;
/* Copy the integer value representing the number of elements to the first
element in the array */
memcpy ( array, (void *) &noe, INT_SIZ );
/* Return the pointer value offset by the size of an int */
return (void *) (((int *)(array))+1);
}
int main(void)
{
void *array;
int i=0;
array = createArray(10, sizeof(int));
InsertElement ( array, int, 0, 65534 );
printf("%d\n", *(int *)( ((int *)(array)) - 1) ); /* pointer syntax */
printf("%d\n", ((int *)array)[-1] ); /* array syntax */
printf("%d\n", GetSize(array) );
printf ( "Element #%d: %d\n", 0, GetElement ( array, int, 0 ) );
puts ( "\nDemonstrating Array of Doubles --------------------------------");
array = createArray(10, sizeof(double));
InsertElement ( array, double, 0, 3.0 );
InsertElement ( array, double, 1, 3.1 );
InsertElement ( array, double, 2, 3.2 );
printf("Array size: %d\n", GetSize(array) );
for ( i=0; i<3; i++ )
printf ( "Element #%d: %lf\n", i, GetElement ( array, double, i ) );
free ( ((int *)(array))-1 );
}
这是输出:
10
10
10
Element #0: 65534
Demonstrating Array of Doubles --------------------------------
Array size: 10
Element #0: 3.000000
Element #1: 3.100000
Element #2: 3.200000
关于代码的注意事项
- 该数组被视为零基数组,就像任何其他 C
数组。
- 虽然在例程中,我添加了一个检查内存是否
已分配,则 createArray 的任何调用者都应进行类似的检查
例行公事。
- 添加了宏定义以使代码更具可读性。