同一地址的不同指针类型

时间:2014-11-18 13:48:38

标签: c embedded 8051

我对编程比较陌生,所以如果我的问题是基本的,我会道歉。

情况:

我有几个浮点值和一个指向每个值的指针数组。例如:

float nr1=1.15;
float nr2=2.30; 
float nr3=23.34; 

....

float * my_address_array[3]; 

my_address_array[0] = &nr1;
my_address_array[1] = &nr2;
my_address_array[2] = &nr3;

要访问一个元素,我可以使用:

float temp_value; 
float ** ptr_value; 

...

ptr_value = &my_address_array[0];

temp_value = **( ptr_value+0); // copy nr1 to temp
temp_value = **( ptr_value+1); // copy nr2 to temp
temp_value = **( ptr_value+2); // copy nr3 to temp 

到目前为止一切顺利。在我的系统浮动占用32位(8051微控制器)。我需要取一个浮点数并将其分成四个8位变量。 nr2的示例:

我的尝试是:

unsigned char storage1; 
unsigned char storage2; 
unsigned char storage3; 
unsigned char storage4; 

...

storage1 =(unsigned char) ((**( ptr_value+1)) >> 24) ;
storage2 =(unsigned char) ((**( ptr_value+1)) >> 16) ;
storage3 =(unsigned char) ((**( ptr_value+1)) >> 8) ;
storage4 =(unsigned char) ((**( ptr_value+1)) & 0xff) ;

我的操作数类型不好。似乎我不能使用浮动数字的位移操作(至少谷歌sais)。我可以添加一个新指针,如:

char ** ptr_char_value; 

...

ptr_char_value = &my_address_array[0];   // generates warning

storage1 = (*(*( ptr_char_value+1)+0));
storage2 = (*(*( ptr_char_value+1)+1));
storage3 = (*(*( ptr_char_value+1)+2));
storage4 = (*(*( ptr_char_value+1)+3));

我确实得到一个警告(这是公平的)我正在使用char类型指针来表示浮点值。我也不确定这是多么可靠。任何人都可以建议更好的解决方案?

谢谢!

编辑:代码适用于8051微控制器。我想尽可能快速/最优。

4 个答案:

答案 0 :(得分:1)

有了这个,你得到指向值

的指针
ptr_char_value = &my_address_array[0];

我不明白这应该如何运作。


最好直接使用指针浮点数。将它转换为char数组并获得单独的字节。

char * ptr_char_value = (char *)(my_address_array[0]);
storage1 = ptr_char_value[0];
storage2 = ptr_char_value[1];
storage3 = ptr_char_value[2];
storage4 = ptr_char_value[3];

编辑: 如果你真的需要浮点指针数组也是一个问题。可以使用struct,将其转换为字节数组并直接使用这些字节。

struct my_data_type {
    float nr1;
    float nr2;
    float nr3;
}

struct my_data_type my_data;

my_data.nr1 = 1.15;
my_data.nr2 = 4.75;
my_data.nr3 = 8.95;

char * ptr_char_value = (char *)&my_data;

// nr1
storage1 = ptr_char_value[0];
...

// nr2
storage5 = ptr_char_value[4];
...

// nr3
storage9 = ptr_char_value[8];
...

答案 1 :(得分:0)

试试这个。您应该在转换数据之前键入cast。包括stdint.h

      storage1 = (uint8_t) ((((uint32_t)**( ptr_value+1))) >> 24) & 0xFF );

答案 2 :(得分:0)

让我们从标题开始:

  

同一地址的不同指针类型

那个代码闻起来。在C中,通过不兼容的指针类型别名对象会导致未定义的行为,除非不兼容的别名类型是(限定或非限定,有符号或无符号)字符类型。

更确切地说,只能通过指向限定或不合格T的指针来访问类型为cv-qualified或notqualified T的对象。此外,如果T是一个整数类型,则允许通过其(合格或不合格)签名或无签名对应方式进行访问。

这通俗地称为"严格别名规则"。

因此,你无法做到

float f;
*(int *)&f

即使sizeof(float) == sizeof(int)

可能的解决方案:

  1. 使用memcpy(),如下(首选):
  2. float f = 3.14;
    int i;
    memcpy(&i, &f, sizeof f);
    
    1. 使用联合(仅限C99 - 在C89中也是UB ...):
    2. union {
          float f;
          int i;
      } pun = { .f = 3.14 };
      printf("%d\n", pun.i);
      

答案 3 :(得分:-2)

为什么要将浮点数分成4个变量? 由于float在计算机中的表现方式,这没有任何意义。

float in c

第一位S为正数,0为正数1为负数。然后是8位指数,其余23位为尾数。 因此,8bit部件没有任何用处,因为它们本身毫无意义。