为什么代码运行没有错误?
#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 *'答案 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)上,这可能会出现问题,原因有两个:
int i = "string";
可能会丢失信息,如果64位指针不能适合32位整数。printf
期望传入指针,但获取较小的整数。它最终将一些垃圾读入完整指针,并可能导致代码崩溃(或更糟)。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";
具有依赖于实现的结果,但您无法合法地执行此操作。
在任何情况下,编译器为上述初始化发出的警告已经足以构成此违规的诊断消息。