2016-02-19 162 views
5

所以我看到了一些关于如何找到一个架构的字节顺序的例子。假设我们有一个指向int数据类型的整型指针。假设int值是0x010A0B12。在一个小端结构中,最低有效字节,即12,将被存储在最低存储器地址中,对吧?因此,一个4字节整数中的最低字节将为12.类型铸造字符指针指向整数指针

现在,开始检查。如果我们声明一个char指针p,然后将整型指针转换为一个char *并将其存储在p中,并打印p的解除引用值,那么我们将得到关于该体系结构字节顺序的线索。如果它是12,我们是小端的; 01表示大端。这听起来真的很整齐...

int a = 0x010A0B12; 
int *i = &a; 
char *p = (char*)i; 
printf("%d",*p); // prints the decimal equivalent of 12h! 

几个问题在这里,真的。由于指针是强类型的,不应该将字符指针严格指向char数据类型?和%d打印有什么关系?我们不应该用%c打印字符吗?

+0

相关:http://stackoverflow.com/questions/34826036/confused-about-pointer-dereferencing?noredirect = 1&lq = 1 –

回答

6

由于指针是强类型的,不应该将字符指针严格指向char数据类型吗?

C有一条规则,任何指针可以安全地转换为char*void*。因此,将int*转换为char*是允许的,并且它也是可移植的。指针将指向你的int的内部表示的起始字节。

难道我们不应该用%c打印字符吗?

另一件事是在这里玩:变长参数列表printf。当您将char传递给printf的无类型参数时,将应用默认转换:char转换为int。这就是为什么%d格式的数字很好,并按预期打印出来。您也可以使用%c。处理%c说明符的代码将参数读取为int,然后将其转换为char0x12是一个特殊字符,所以你不会看到一个统一的打印输出。

+0

谢谢,虽然,你在谈论什么是“printf的无类型参数”? – nirvanaswap

+0

@nirvanaswap在'print'的签名末尾有三个'...',即'int printf(const char * format,...)'指定你可以传递任何类型的附加参数。 – dasblinkenlight

-2

由于指针是强类型的,不应该严格指向字符数据类型的char数据类型吗?

这是一种未定义的行为 - 但这样大多数理智的实现将做你的意思。所以大多数人都会说。

用%d打印怎么样?

格式%d期望类型为int的参数,而实际的char类型参数通过通常的C规则提升为int。所以这又好了。您可能不想使用%c,因为p指向的字节内容可能是任何字节,而不总是有效的文本字符。

+1

我正在取消引用它,很清楚%p不是我正在寻找的权利? – nirvanaswap

+2

OP代码中没有未定义的行为。 – dasblinkenlight

+0

@nirvanaswap:是的,对不起,我编辑了这个。为了dasblinkenlight:存在未定义的行为,它假设内存中的任何字节都可以被单独寻址和访问。通常这是事实,但想象一下,OP试图访问(比方说)32位硬件寄存器中的一个中间字节,该寄存器只能读取整个32位和只读的对齐地址。它会导致运行时异常。 – ddbug