int可以在C中存储字符串的基址吗?

时间:2014-08-14 20:36:02

标签: c pointers

为什么代码运行没有错误?

#include <stdio.h>
    int main() {
    int i="string"; //the base of string can be stored in a character pointer 
    printf("%s\n",i);
    printf("%d",i);
    return 0;
}

//在ideone.com语言c上编译

输出:

string

134513984 //一些垃圾(地址为&#34;字符串&#34;)

请解释c中指针是否有一定的灵活性。我为c ++尝试了它,它给出了错误:在初始化

中无法将'const char *'转换为'int *'

5 个答案:

答案 0 :(得分:6)

不,你不能一般地假设这一点。在某种程度上,这是因为int可能与char *的大小不同(实际上,在许多64位编译器上,它 的大小不同)。 / p>

如果要将指针存储为整数,则要使用的相应类型intptr_t来自<stdint.h>。这是一个保证能够保存指针值的整数。

然而,实际上你想要这样做的情况有点罕见,当你这样做时,你还应该包括一个明确的演员:

intptr_t i=(intptr_t)"string"; //the base of string can be stored in a character pointer 

这也使打印它的价值变得复杂,你需要使用宏来便携:

printf("%"PRIiPTR,i);

要打印原始字符串,您还应该强制转换:

printf("%s", (char *)i);

答案 1 :(得分:2)

通常,不:C标准规定从指针到整数的转换是实现定义的。此外,在sizeof(char *)sizeof(int)不同的系统(即x86-64)上,这可能会出现问题,原因有两个:

  1. int i = "string";可能会丢失信息,如果64位指针不能适合32位整数。
  2. printf期望传入指针,但获取较小的整数。它最终将一些垃圾读入完整指针,并可能导致代码崩溃(或更糟)。
  3. 然而,很多时候,编译器是“聪明的”和#34;足以#34;修复&#34; printf的参数。此外,您似乎在指针和整数 大小相同的平台上运行,因此您很幸运。

答案 2 :(得分:1)

如果您编写了带有警告的程序(您应该这样做),您将收到以下投诉:

main.c:3:9: warning: incompatible pointer to integer conversion initializing 'int' with an expression of type 'char [7]' [-Wint-conversion]
    int i="string"; //the base of string can be stored in a character pointer 
        ^ ~~~~~~~~
main.c:4:19: warning: format specifies type 'char *' but the argument has type 'int' [-Wformat]
    printf("%s\n",i);
            ~~    ^
            %d
2 warnings generated.

警告通常意味着您正在做一些可能导致意外结果的事情。

答案 3 :(得分:1)

大多数C编译器都会允许你这样做,但这并不是一个好主意。这里,字符数组"string"的地址存储在i中。 printf选项决定了整数的解释方式(作为地址或整数)。当char*int的大小不同时(例如,在大多数64位计算机上),这可能会出现问题。

C ++编译器更挑剔,不会让你编译这样的代码。 C编译器更愿意,尽管它们通常会产生警告,让程序员知道这是一个坏主意。

答案 4 :(得分:1)

您的代码在C和C ++中都是错误的。

是违法的
int i = "string";

两种语言。在两种语言中,从指针转换为整数都需要显式转换。

C编译器接受它的唯一原因是它默认配置为相当松散的错误检查。 (C编译器的一个相当典型的情况。)收紧C编译器设置,它应该为上面的初始化发出错误。即你可以使用显式转换

int i = (int) "string";

具有依赖于实现的结果,但您无法合法地执行此操作。

在任何情况下,编译器为上述初始化发出的警告已经足以构成此违规的诊断消息。