嗯,我相信我已经搜索得足够多了,我找不到任何解释。
当您将char
投射到int
时,这是可以而且显而易见的。
char foo = 'a';
int bar = (int)foo;
printf("%i",bar); //Outputs 97 as expected.
但是当您尝试cast
char *
或char
数组到int
时,编译器会给您一个警告:
警告:从指针强制转换为不同大小的整数[-Wpointer-to-int-cast]
对于char *
,你得到一个常量int
值 - 我相信它与指针或内存有关 - 然后对于char
数组,你总是得到一些变量{{1价值。
int
这听起来像是一个不必要的问题,但我想知道原因。
答案 0 :(得分:5)
尝试将指针转换为某种整数类型可能会导致未定义的行为(UB)。
任何指针类型都可以转换为整数类型。除了之前指定的以外,结果是实现定义的。 如果结果无法以整数类型表示,则行为未定义。* ...C11dr§6.3.2.36
由于UB潜力,(int)foo
可以生成类似“警告:从指针转换为不同大小的整数”的警告。 @4386427
char* foo = "baz";
int bar = (int)foo; // potential UB.
要避免该UB,将对象指针转换为整数(不是函数指针)时,请使用可选类型uintptr_t
或intptr_t
以下类型指定一个无符号整数类型,其属性是指向
void
的任何有效指针都可以转换为此类型,然后转换回指向void的指针,结果将等于原始指针:
uintptr_t
7.20.1.4 1
实施例
#include <inttypes.h>
some_object* foo = ...;
uintptr_t bar = (uintptr_t)(void*)foo; // no UB
printf("0x%" PRIXPTR "\n", bar);
对于char数组,你总是得到一些变量int值。
这是因为数组的转换,首先转换为指向第一个元素的指针,然后转换为整数。 int bar2 = (int)qux;
试图获取数组存在的值,而不是元素值。
答案 1 :(得分:2)
将对象指针p
转换为整数类型的正确方法是(uintptr_t)(void*)p
,如果由于某种原因您需要签名类型,则为(intptr_t)(void*)p
。 {64}目标上的int
或long
通常为32位宽,但uintptr_t
中定义的<stdint.h>
始终是保持指针的正确大小。从技术上讲,标准只说明void*
之间的转换是安全的,因此是中间演员。
这可以让您表示字符串的地址。如果你真正想要的是读取ASCII格式的数字,你需要atoi()
或sscanf()
之类的东西。
答案 2 :(得分:1)
c标准接受指针和整数之间的转换,但它们可能很容易将您的程序引导至undefined behavior。
如果您遇到指针和整数之间的转换很有用的情况,并且存在 1 的情况。然后你应该使用appropriate types,
intptr_t
uintptr_t
你应该阅读这些
此外,字符常量的实际类型为 int
。
1 例如在 jni 插件中将句柄传递给java,从java传递给您的程序。
答案 3 :(得分:0)
当你将char *
转换为int
时,你得到char数组中第一个元素的内存地址。
char* foo = "baz";
int bar = (int)foo;
printf("0x%X", (unsigned)bar); //It will print memory of first char element.
但是,此代码存在重大问题,可能无法打印出确切的结果。内存地址可以将MSB位设置为1,您将在int中获得负值,或者在某些情况下int
不足以存储整个内存地址。