C++ 如何将数组的地址放入变量中
如何将数组的地址放入变量中C++ 如何将数组的地址放入变量中,c++,C++,如何将数组的地址放入变量中 char * str1 = "Hello"; int add = 0; 现在我想把数组的地址放入add。 我知道我可以通过以下方式打印出阵列的地址: printf("Address = %p", str1); 但是,我想在变量中存储地址。如果要在变量中存储内存地址,正确的方法是将变量键入std::intptr\u t或std::uintpr\u t。这是因为这些类型保证足够大以容纳任何内存地址: char * str1 = "Hello"; uintptr_t p
char * str1 = "Hello";
int add = 0;
现在我想把数组的地址放入add
。
我知道我可以通过以下方式打印出阵列的地址:
printf("Address = %p", str1);
但是,我想在变量中存储地址。如果要在变量中存储内存地址,正确的方法是将变量键入
std::intptr\u t
或std::uintpr\u t
。这是因为这些类型保证足够大以容纳任何内存地址:
char * str1 = "Hello";
uintptr_t p = (uintptr_t)str1;
除此之外,请注意
str1
的值已经是一个内存地址(它指向H
),尽管它与&str1
(它指向str1
)的值不同。如果要在变量中存储内存地址,正确的方法是将变量键入std::intptr\u t
或std::uintpr\u t
。这是因为这些类型保证足够大以容纳任何内存地址:
char * str1 = "Hello";
uintptr_t p = (uintptr_t)str1;
除此之外,请注意
str1
的值已经是一个内存地址(它指向H
),尽管它与&str1
(它指向str1
)的值不同。将指针转换为数字需要重新解释:
add = reinterpret_cast<int>(str1);
add=reinterpret\u cast(str1);
但这种方法存在各种各样的问题:
- 如果sizeof(int)
- 由于出现意外的别名,某些优化可能会使代码无效
如果您需要一个可以保存指针或整数的变量,最好使用并集。将指针转换为数字需要重新解释:
add = reinterpret_cast<int>(str1);
add=reinterpret\u cast(str1);
但这种方法存在各种各样的问题:
- 如果sizeof(int)
- 由于出现意外的别名,某些优化可能会使代码无效
如果您需要一个可以保存指针或整数的变量,最好使用并集。使用
重新解释转换(参见5.2.10/p4):
4指针可以显式转换为任何足以容纳它的整数类型。映射函数是
实现定义。[注:对于那些了解寻址结构的人来说,这并不奇怪
基础机器的名称。-结束注释]
static_断言(sizeof(unsigned int)>=sizeof(&str1[0]),“警告:使用更宽的类型!”);
unsigned int add=reinterpret_cast(&str1[0]);
使用重新解释铸件(见5.2.10/p4):
4指针可以显式转换为任何足以容纳它的整数类型。映射函数是
实现定义。[注:对于那些了解寻址结构的人来说,这并不奇怪
基础机器的名称。-结束注释]
static_断言(sizeof(unsigned int)>=sizeof(&str1[0]),“警告:使用更宽的类型!”);
unsigned int add=reinterpret_cast(&str1[0]);
根据您对Jon的公认答案的评论:
char str1[] = "Hello";
char* str2 = &str1[0];
uintptr_t p = (uintptr_t)str2;
std::cout << std::hex << p << std::endl;
p = (uintptr_t)&str1[1];
std::cout << std::hex << p << std::endl;
p = (uintptr_t)&str1[0];
std::cout << std::hex << p << std::endl;
char str1[]=“你好”;
char*str2=&str1[0];
uintptr_t p=(uintptr_t)str2;
std::cout从您对Jon被接受的答案的评论来看:
char str1[] = "Hello";
char* str2 = &str1[0];
uintptr_t p = (uintptr_t)str2;
std::cout << std::hex << p << std::endl;
p = (uintptr_t)&str1[1];
std::cout << std::hex << p << std::endl;
p = (uintptr_t)&str1[0];
std::cout << std::hex << p << std::endl;
char str1[]=“你好”;
char*str2=&str1[0];
uintptr_t p=(uintptr_t)str2;
std::cout str1实际上是一个地址如果你在64位平台上,一个普通的int
就不够了,因为它只有32位,而指针(技术上是地址)是64位。当你真的想把地址转换成整数时,一定要使用size\u t
。但是,不建议这样做。如果您的算法需要将地址(指针)转换为整数,则这表明存在设计问题。@Walter:即使是size\t
也不能保证足够大(尽管实际上是这样)uintpttr_t
具有必需的属性,但不保证存在(尽管在实践中确实存在,但在C++03上,您可能需要获得适合您平台的第三方stdint.h
)。这有点乱。@史蒂夫:你说得对,在C++11中应该使用uintpttr\t
。但我敢打赌,如果size\t
无法保存地址,许多代码都会被破坏……str1实际上是一个地址如果你在64位平台上,一个普通的int
就不够了,因为它只有32位和一个指针(从技术上讲是一个地址)是64位。如果确实要将地址转换为整数,请始终使用size\t
。但是,不建议这样做。如果您的算法需要将地址(指针)转换为整数,则这表明存在设计问题。@Walter:即使是size\t
也不能保证足够大(尽管实际上是这样)uintpttr_t
具有必需的属性,但不保证存在(尽管在实践中确实存在,但在C++03上,您可能需要获得适合您平台的第三方stdint.h
)。这有点乱。@史蒂夫:你说得对,在C++11中应该使用uintpttr\t
。但我敢打赌,如果size\t
无法保存地址,许多代码都会被破坏……如果我可以问一下,别名有什么问题吗?不保证这符合标准,但我的理解是这样的:假设您将int传递给一个函数,该函数将int转换回char*并更改字符串的内容。编译器可能会在调用之前将字符串的一个字符存储到寄存器中,并在调用返回后使用该缓存版本,从而丢失修改。优化器希望只向函数传递int永远不会影响局部变量的内容。哦,我明白了,你是对的。然而,我不确定这是否正确