函数中设置的数组值仅适用于一种数据类型 [英] Array values set in function only work properly for one data type

查看:47
本文介绍了函数中设置的数组值仅适用于一种数据类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这段代码中,我试图通过指针运算和数组变得更好.我有一个函数,它根据用户输入的内容创建一个数组类型(因此我使用 void * 作为函数类型),然后在数组 [-1] 点中隐藏"函数的大小,所以它总是可以被索引并在那里有大小.最后,我将其转换为 void 并返回数组.

In this bit of code, I'm trying to get better with pointer arithmetic and arrays. I have a function that creates an array type based on what the user inputs (hence why I went with void * as the function type), and then "hides" the size of the function in the array[-1] spot, so it can always be indexed and have the size right there. Lastly, I cast it as void and return the array.

它适用于整数,但不适用于其他数据类型.

It works perfectly fine with integers, but no other data types.

#include <stdio.h>
#include <stdlib.h>

void * createArray(int size, int soa)
{
int *array;
array = malloc(sizeof(int)+size*soa);
array[0] = size; array++;
return (void*)array;
}

int main(void)
{
int *array;
array = createArray(10, sizeof(int));
double *array2;
array2 = createArray(5, sizeof(double));
printf("%d\n", *(array-1));
printf("%f", *(array2-1));
}

我的输出是:100.000000

因此,它为整数正确隐藏了它,但是所有其他数据类型都出现了问题,我很难过.任何帮助将不胜感激!!!

So, it's hiding it correctly for the integer, but something is going wrong for all other data types and I'm stumped. Any help would be greatly appreciated!!!

推荐答案

@Azoros,

您的代码适用于整数,因为您将指针类型定义为整数.当您将指针类型定义为 double 时,处理器将尝试将每个元素作为 double 数据类型进行处理.内部整数和双精度数使用不同的格式存储.这就是为什么当您尝试从 double 数据类型检索整数值时它不起作用的原因.

Your code works for integers because you define the pointer type as integers. When you define the pointer type as double, the processor will try to process each element as a double data type. Internally integers and doubles are stored using different formats. That is why when you try to retrieve the integer value from a double data type it does not work.

因此,如果我正确理解您的问题,您希望将一个零元素定义为一个整数的数组来保存数组的长度.其余元素需要保存数据值,这些数据值可能与第一个元素的数据类型不同.

So, if I understand your problem correctly, you want to have an array with its zero element define as an integer that holds the length of the array. The rest of the elements need to hold data values which could be a different data type then the first element.

我会通过将数组指针定义为字节数组 (void *) 来解决这个问题.然后在访问元素时,我会告诉处理器它正在处理什么数据类型.

I would approach this problem by defining the array pointer as a byte array (void *). Then when accessing elements, I would just tell the processor what data type it is dealing with.

实际操作如下:

将指针定义更改为字节指针.

Change the pointer definition to a byte pointer.

void* array;

将数组分配到包含数组长度元素和数据元素的大小.

Allocate the array to a size that includes both the array length element along with the data elements.

array = calloc(1, INT_SIZ + (noe * soe));

将大小值移动到数组的第一个位置.请注意,在 Windows x86 机器上,这将复制 4 个字节的数据.

Move the size value into the first position of the array. Note on a Windows x86 machine this will copy 4 bytes of data.

memcpy(array, (void*)&noe, INT_SIZ);

返回按第一个元素的大小偏移的内存地址.在 x86 机器上,这将偏移 4 个字节

Return the memory address offset by the size of the first element. On a x86 machine, this will be offset by 4 bytes

return (void*)(((int*)(array)) + 1);

这里是使用修改后的 createArray 例程的完整代码.

Here the full code that utilize the modified createArray routine.

# 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

代码注意事项

  1. 该数组被视为零基数组,就像任何其他 C 语言一样数组.
  2. 虽然在例程中,我添加了一个检查,看看内存已分配,createArray 的任何调用者都应进行类似的检查例行公事.
  3. 添加了宏定义以使代码更具可读性.

这篇关于函数中设置的数组值仅适用于一种数据类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆