(int)如何在char数组和char *上进行转换?

时间:2018-01-31 21:12:23

标签: c arrays string string-literals

嗯,我相信我已经搜索得足够多了,我找不到任何解释。

当您将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

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

4 个答案:

答案 0 :(得分:5)

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

  

任何指针类型都可以转换为整数类型。除了之前指定的以外,结果是实现定义的。 如果结果无法以整数类型表示,则行为未定义。* ...C11dr§6.3.2.36

由于UB潜力,(int)foo可以生成类似“警告:从指针转换为不同大小的整数”的警告。 @4386427

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

要避免该UB,将对象指针转换为整数(不是函数指针)时,请使用可选类型uintptr_tintptr_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}目标上的intlong通常为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不足以存储整个内存地址。