关于C中指针类型转换的问题 [英] A question about pointer typecasting in C

查看:110
本文介绍了关于C中指针类型转换的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我一直在尝试使用C语言中的指针,我遇到的情况是,在分配的内存中以字节为单位,而我需要提取32位来自该缓冲区的数据类型。 (不,这不是功课!)。在汇编程序中,它就像mov dword eax,[memory_buf + offset]一样简单。

我尝试以下程序:

  #include   <   stdio.h  >  
#include < stdint.h >
#include < stdlib.h >
int main( int argc, const < span class =code-keyword> char * argv [])
{
uint8_t * cast1;
cast1 =(uint8_t *)malloc( 50 );
cast1 [ 5 ] = 1 ;
cast1 [ 6 ] = 2 ;
cast1 [ 7 ] = 3 ;
cast1 [ 8 ] = 4 ;
uint32_t x =(uint32_t)cast1 [ 5 ];
printf( %d \ n,x);
return 0 ;

}



这个程序的输出是:

 1 



由于sizeof(uint32_t)= 4,整数不应该将整个'1234'作为一个整数吗?为什么这样?

解决方案

没有。一切都是正确的。事情就是这样:你不是在抛出指针;你是在输入字节。如果我们将其分解为更小的步骤,会发生以下情况:

  //   cast1的类型是uint8_t *  
// 因此,cast1的类型[5]是uint8_t,所以:
uint8_t someByte = cast1 [ 5 ];
uint32_t x =(uint32_t)someByte;





上面显示的演员是重新解释演员表(用C ++术语)。这实际上是从较小的整数类型转换为较大的类型,这与两种类型中的语义(数学)值相同的方式完成(通过将较大的类型转换为较小的类型并不总是可能的,但总是可能的如果你做相反的事情,就像在这种情况下)。在无符号类型中(甚至在更复杂的两个补码数的情况下),它取零值并填充源对象中的最低有效字节( someByte )。



-SA


仔细看看这一行

 uint32_t x =(uint32_t)cast1 [5]; 





字面意思是得到cast1的值[5]然后把它升级到32位......显然这不是你想要的,因为它会使得一个32位的结果恢复1 ...这正是你得到的。



你想要的是32位值,它启动一个cast1 [5]所以你需要一个指向该语句的32指针看起来像这样

(uint32_t)& cast1 [5] 



好​​的,现在你不想指针你想要的值,所以你必须取消引用它

 *((uint32_t)& cast1 [5])



所以最终结果看起来像

 uint32_t x = *((uint32_t)& cast1 [ 5]); 



这一切都非常难看,但它做了你想要的并向你展示了文字



通常更简单的方法和更易读的方法是使用32位临时指针

 uint32_t * dummyptr =(uint32_t *)& cast1 [5]; //创建32位虚拟指针
uint32_t x = * dummyptr; //在指针处获取值



任何优化编译器都会立即识别出它可以删除虚拟指针,因此它不需要任何费用,只会使代码更具人性化。


Hi,
I've been experimenting with pointers in C, and I've come across a situation where in the memory allocated is seen in bytes, while I need to extract a 32-bit Data type from that buffer. (No this isn't homework!). In assembler it was as simple as a "mov dword eax, [memory_buf+offset]" :)
I try the following program:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
int main(int argc, const char* argv[])
{
	uint8_t* cast1;
	cast1 = (uint8_t*)malloc(50);
	cast1[5] = 1;
	cast1[6] = 2;
	cast1[7] = 3;
	cast1[8] = 4;
	uint32_t x = (uint32_t)cast1[5];
	printf("%d\n", x);
        return 0;

}


The output of this program is:

1


Since sizeof(uint32_t) = 4, shouldn't the integer take the entire '1234' as one? Why so?

解决方案

No. Everything is correct. Here is the thing: you are not type-casting a pointer; you are type-casting the byte. Here is what happens, if we break it into smaller steps:

// type of cast1 is uint8_t*
// therefore, type of cast1[5] is uint8_t, so:
uint8_t someByte = cast1[5];
uint32_t x = (uint32_t)someByte;



The cast shown above is not reinterpret cast (in C++ terms). This is actually the conversion from smaller integer type to a bigger type, which is done the way the "semantic" (mathematical) values in both types would be the same (which is not always possible by converting bigger type to smaller, but always possible if you do the opposite, as in this case). In unsigned types (and even in more complex case of two's complement numbers) it takes zero value and fills in the least significant byte(s) from the source object (someByte).

—SA


Look carefully at this line

uint32_t x = (uint32_t)cast1[5];



It literally says get the value at cast1[5] and upcast it to 32 bits ... clearly that is not what you wanted as that returns 1 lifted back as a 32 bit result ... which is exactly what you got.

What you wanted was the 32 bit value that starts a cast1[5] so you need a 32 pointer to that statement looks like this

(uint32_t)&cast1[5]


Okay now you don't want the pointer your want the value so you have to dereference it back

*((uint32_t)&cast1[5])


so the final result looks like

uint32_t x = *((uint32_t)&cast1[5]);


That is all very ugly but it did what you wanted and showed you the literal

The normal easier way and more readable way is to use a 32 bit temp pointer

uint32_t* dummyptr = (uint32_t*)&cast1[5]; // Create 32 bit dummy pointer
uint32_t x = *dummyptr;                    // Get value at pointer


Any optimizing compiler will immediately recognize it can remove the dummy pointer so it cost you nothing it just makes the code more human readable.


这篇关于关于C中指针类型转换的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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