(int) 转换如何作用于 char 数组和 char *?

How does (int) casting work on char arrays and char *?

好吧,我相信我搜索得够多了,我找不到任何解释。

当您将 char 转换为 int 时,这是显而易见的。

char foo = 'a';
int bar = (int)foo;
printf("%i",bar); //Outputs 97 as expected.

但是当您尝试将 cast 一个 char *char 数组转换为 int 时,编译器只会给您一个警告:

warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]

对于 char * 你得到一个常量 int 值 - 我相信这与指针或内存有关 - 然后对于 char 数组你总是得到一些变量 int值。

char* foo = "baz";
int bar = (int)foo;
printf("%i",bar);

char qux[]="something";
int bar2 = (int)qux;
printf("%i",bar2);

这听起来像是一个不必要的问题,但我想知道原因。

当您将 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 不够宽,无法存储整个内存地址。

c 标准接受指针和整数之间的转换,但它们可能很容易导致您的程序 undefined behavior

如果您遇到指针和整数之间的转换很有用的情况,并且存在这种情况1。那么你应该使用 appropriate types,

  • intptr_t
  • uintptr_t

你可能应该阅读这些

此外,字符常量的实际类型是int.


1例如在 jni 插件中传递一个 handle 到 java,然后从 java 到你的程序。

尝试将指针转换为某些 整数 类型可能会导致未定义的行为 (UB)。

Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined.* ... C11dr §6.3.2.3 6

(int)foo 可能会生成类似 "warning: cast from pointer to integer of different size" 的警告,因为存在潜在的 UB。

char* foo = "baz";
int bar = (int)foo;  // potential UB.

为避免这种 UB,在将 对象指针 转换为整数时(不是 函数指针 ),使用可选类型 uintptr_tintptr_t.

The following type designates an unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer:

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);

for a char array you always get some variable int value.

那是因为数组的转换,先转换为第一个元素的指针,再转换为整数。 int bar2 = (int)qux; 正在尝试获取数组所在位置的值,而不是其元素值。

将对象指针 p 转换为整数类型的正确方法是 (uintptr_t)(void*)p,或者如果出于某种原因您需要有符号类型,则 (intptr_t)(void*)p。在 64 位目标上,intlong 通常为 32 位宽,但 <stdint.h> 中定义的 uintptr_t 始终是容纳指针的正确大小。从技术上讲,该标准仅表示与 void* 之间的转换是安全的,因此是中间转换。

这为您提供了字符串地址的表示。如果您真正想要的是读取 ASCII 格式的数字,您需要诸如 atoi()sscanf().

之类的内容