Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
类型将char指针转换为整数指针_C_Pointers_Casting_Endianness - Fatal编程技术网

类型将char指针转换为整数指针

类型将char指针转换为整数指针,c,pointers,casting,endianness,C,Pointers,Casting,Endianness,因此,我看到了一些关于如何找到架构的持久性的例子。假设我们有一个指向int数据类型的整数指针。假设int值是0x010A0B12。在小端结构中,最低有效字节,即12,将存储在最低内存地址中,对吗?因此,4字节整数中的最低字节将是12 现在,开始检查。如果我们声明一个char指针p,并将整型指针强制转换为char*并将其存储在p中,然后打印p的解引用值,我们将获得关于体系结构的endianness的线索。如果是12,我们就是小恩迪安;01表示大端。这听起来真不错 int a = 0x010A0B1

因此,我看到了一些关于如何找到架构的持久性的例子。假设我们有一个指向int数据类型的整数指针。假设int值是0x010A0B12。在小端结构中,最低有效字节,即12,将存储在最低内存地址中,对吗?因此,4字节整数中的最低字节将是12

现在,开始检查。如果我们声明一个char指针p,并将整型指针强制转换为char*并将其存储在p中,然后打印p的解引用值,我们将获得关于体系结构的endianness的线索。如果是12,我们就是小恩迪安;01表示大端。这听起来真不错

int a = 0x010A0B12;
int *i = &a;
char *p = (char*)i; 
printf("%d",*p); // prints the decimal equivalent of 12h!
这里有几个问题,真的。既然指针是强类型的,字符指针不应该严格地指向char数据类型吗?用%d打印有什么用?我们不应该用%c打印字符吗

既然指针是强类型的,字符指针不应该严格地指向char数据类型吗

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

我们不是应该用
%c
打印字符吗

这里还有一件事:printf的可变长度参数列表。当您将
char
传递给
printf
的非类型化参数时,将应用默认转换:
char
转换为
int
。这就是为什么
%d
格式可以很好地获取数字,并按预期打印出来

您也可以使用
%c
。处理
%c
说明符的代码将参数读取为
int
,然后将其转换为
char
<但是,code>0x12是一个特殊字符,因此您不会看到它的统一打印输出

既然指针是强类型的,字符指针不应该严格地指向char数据类型吗

这是一种未定义的行为——但大多数理智的实现都会按照您的意思执行。所以大多数人都会同意

用%d打印有什么用


格式%d需要int类型的参数,而char类型的实际参数由常用的C规则提升为int。所以这又没问题了。您可能不想使用%c,因为p所指字节的内容可能是任何字节,但并不总是有效的文本字符。

我正在取消对它的引用,所以很明显%p不是我想要的,对吗?@nirvanaswap:是的,对不起,我编辑了这个。dasblinkenlight:存在未定义的行为,假设内存中的任何字节都可以单独寻址和访问。通常这是正确的,但假设OP试图访问(比如)32位硬件寄存器中的中间字节,该寄存器只能作为整个32位读取,并且只能在对齐地址处读取。这将导致运行时异常。这是完全错误的。通过
char*
寻址对象内存总是有效的;最基本的memcpy实现就是这样做的。是的,如果编译器对此满意,C程序寻址任何指针都是有效的。但是硬件有权启动并抛出异常。不过,谢谢,你说的“printf的非类型参数”是什么?@nirvanaswap三点
print
签名的末尾,即
int printf(const char*format,…)
指定可以传递任何类型的附加参数。相关: