我认为以下代码段的行为应该是未定义的,但我只是想确保我理解正确的事情。 假设我们有这个代码:
#include <iostream>
int main()
{
std::cout << "mamut" - 8 << std::endl;
return 0;
}
所以我认为这样做是(char *)((int)(const char *) - (int)),虽然这之后的输出很奇怪,但并不是说我希望它有任何真正的意义。所以我的问题是关于char *和int之间的转换 - 它是未定义的,还是背后有一些逻辑?
编辑: 我来补充一点:
#include <iostream>
int main ()
{
const char* a = "mamut";
int b = int(a);
std::cout << b << std::endl;
std::cout << &a <<std::endl;
// seems b!= &a
for( int i = 0; i<100;i++)
{
std::cout<<(const char*)((int)a - i)<<std::endl;
}
return 0;
}
我变得足够大后的输出给了我像_Jv_RegisterClasses等的东西。 仅供记录:
std::cout << a - i << std::endl;
产生的结果与:
相同std::cout<<(const char*)((int)a - i)<<std::endl;
答案 0 :(得分:5)
没有演员表,你只是告诉cout你想要在字符串文字的地址打印字符串&#34; mamut&#34;减去8个字节。你正在做指针运算。然后cout会打印出在该地址发生的任何事情,或者可能是崩溃和刻录,因为访问数组超出界限会导致未定义的行为。
修改强>
关于op的编辑:将地址转换为int
并不一定会产生与地址相同的正确数字。地址不一定适合int
,除此之外,int
是签名类型,并且在签名类型中存储地址没有任何意义。
为了保证从指针到整数的转换而不丢失,您需要使用stdint.h中的uintptr_t
。
引用C标准6.3.2.3(我相信C ++在这种情况下是相同的):
任何指针类型都可以转换为整数类型。除了 之前指定的,结果是实现定义的。如果 结果不能用整数类型表示,行为是 未定义。结果不必在任何值的范围内 整数类型。
答案 1 :(得分:1)
没有施法。 "mamut"
是指向字符的指针,- 8
将对其进行指针运算。你是对的,它是未定义的行为,所以即使语义行为是指针算术,运行时行为也可以是任何东西。
答案 2 :(得分:0)
您正在打印字符串,从“mamut”地址开始减去8个字节,直到空终止符,即总共8+5 = 13
个字符