const char* 从哪里获取指向内存地址的指针?
Where does const char* get the pointer to a memory address?
这可能是一个简单的问题,但为什么 const char* 不需要指向内存地址?
示例:
const char* a = "Anthony";
而不是:
const char *a = // Address to const char
像其他类型一样吗?
why does a const char don't need a memory address to point to?*
确实如此。
像
这样的 C 字符串文字
"Anthony"
被衰减到其第 1st 个字符的地址。顺便说一句; C 中的任何数组都可以。
你可以想象这个声明
const char* a = "Anthony";
以下方式
const char string_literal[] = "Anthony";
const char *a = string_literal;
即编译器创建一个字符数组,其静态存储持续时间存储字符串"Anthony"
和数组第一个字符的地址(由于数组指示符隐式转换为指针它们的第一个字符)被分配给指针 a
.
这是一个演示程序,显示字符串文字是字符数组。
#include <iostream>
#include <type_traits>
decltype( auto ) f()
{
return ( "Anthony" );
}
template <size_t N>
void g( const char ( &s )[N] )
{
std::cout << s << '\n';
}
int main()
{
decltype( auto ) r = f();
std::cout << "The size of the referenced array is "
<< std::extent<std::remove_reference<decltype( r )>::type>::value
<< '\n';
g( r );
return 0;
}
程序输出为
The size of the referenced array is 8
Anthony
字符串文字(存储字符串文字的数组)的大小等于 8
,因为字符串还包括终止零字符 '[=19=]'
.
演示程序中的表达式
std::extent<std::remove_reference<decltype( r )>::type>::value
可以仅替换表达式
sizeof( r )
"Why does const char*
don't need a pointer to a memory address?"
事实上,它确实需要一个内存地址来指向。
const char* a
表示 a
是指向字符串文字或字符常量的指针。
指针总是需要一个地址来指向,因为指针的本质是指向内存中的特定对象。因此,a
和任何其他指向 const char
的指针也是如此。
像 "Hi My Name is Alfred!"
这样的字符串文字,通过这样的赋值:
const char* a;
a = "Hi My Name is Alfred!";
衰减为指向字符串文字第一个元素地址的指针。
反过来,a
由字符串文字 "Hi My Name is Alfred!"
的第一个元素的地址分配,它可以存储在内存中的任何位置,具体取决于执行环境。
字符串文字的准确存储位置不在程序员的能力范围内。您的任务只是适当地分配和处理相应的指针。
它确实需要一个内存地址,而且它有一个内存地址。在您的示例中,它只是字符串开头的内存地址。它与在编译时初始化的任何其他数组变量相同,例如 "int array [] = {0, 1, 2, 3};".
如果您使用二进制编辑器查看可执行文件,您会在其中看到字符串 "Anthony"。如果你把行 "printf ("a 放在 %p\n", (void *)a);"在你的程序中,然后编译 & 运行 它,你会看到地址。
这可能是一个简单的问题,但为什么 const char* 不需要指向内存地址?
示例:
const char* a = "Anthony";
而不是:
const char *a = // Address to const char
像其他类型一样吗?
why does a const char don't need a memory address to point to?*
确实如此。
像
这样的 C 字符串文字"Anthony"
被衰减到其第 1st 个字符的地址。顺便说一句; C 中的任何数组都可以。
你可以想象这个声明
const char* a = "Anthony";
以下方式
const char string_literal[] = "Anthony";
const char *a = string_literal;
即编译器创建一个字符数组,其静态存储持续时间存储字符串"Anthony"
和数组第一个字符的地址(由于数组指示符隐式转换为指针它们的第一个字符)被分配给指针 a
.
这是一个演示程序,显示字符串文字是字符数组。
#include <iostream>
#include <type_traits>
decltype( auto ) f()
{
return ( "Anthony" );
}
template <size_t N>
void g( const char ( &s )[N] )
{
std::cout << s << '\n';
}
int main()
{
decltype( auto ) r = f();
std::cout << "The size of the referenced array is "
<< std::extent<std::remove_reference<decltype( r )>::type>::value
<< '\n';
g( r );
return 0;
}
程序输出为
The size of the referenced array is 8
Anthony
字符串文字(存储字符串文字的数组)的大小等于 8
,因为字符串还包括终止零字符 '[=19=]'
.
演示程序中的表达式
std::extent<std::remove_reference<decltype( r )>::type>::value
可以仅替换表达式
sizeof( r )
"Why does
const char*
don't need a pointer to a memory address?"
事实上,它确实需要一个内存地址来指向。
const char* a
表示 a
是指向字符串文字或字符常量的指针。
指针总是需要一个地址来指向,因为指针的本质是指向内存中的特定对象。因此,a
和任何其他指向 const char
的指针也是如此。
像 "Hi My Name is Alfred!"
这样的字符串文字,通过这样的赋值:
const char* a;
a = "Hi My Name is Alfred!";
衰减为指向字符串文字第一个元素地址的指针。
反过来,a
由字符串文字 "Hi My Name is Alfred!"
的第一个元素的地址分配,它可以存储在内存中的任何位置,具体取决于执行环境。
字符串文字的准确存储位置不在程序员的能力范围内。您的任务只是适当地分配和处理相应的指针。
它确实需要一个内存地址,而且它有一个内存地址。在您的示例中,它只是字符串开头的内存地址。它与在编译时初始化的任何其他数组变量相同,例如 "int array [] = {0, 1, 2, 3};".
如果您使用二进制编辑器查看可执行文件,您会在其中看到字符串 "Anthony"。如果你把行 "printf ("a 放在 %p\n", (void *)a);"在你的程序中,然后编译 & 运行 它,你会看到地址。