字符指针初始化与非指针初始化相比?发生了什么
char pointer initialization compared to non pointer? What happens
我知道用普通字符无法做到这一点。
char line1 = "hello";
但是你可以用一个指向字符类型的指针来完成
char* line2 = "hello";
我想知道为什么会这样,在第二行代码中会发生什么?为什么第二次初始化是可能的?第2行是否指向hello的第一个索引?它是否创建了某种数组并用hello填充?我在一个编程类的c字符串类中使用了这个,但我仍然对第二行代码中发生的事情感到困惑。
编译器确保您指定的以null结尾的字符串"hello"存在于内存中的某个位置,并初始化指针以指向该字符串的开头。
当您编写时
char *line1 = "something";
line1
被创建为堆栈上的指针(如果在自动作用域中(,并被初始化为指向文字字符串"something"
(带有null终止符(。确切地说,"something"
字符串具有包括空终止符的类型char[10]
,并且数组衰减到指向该特定实例中的第一个元素的指针。
存储该字符串的数据是已编译的可执行文件的数据部分,并且它是只读的(即写入它可能会触发访问冲突(。
在C和C++中,当您制作字符串文字时,会隐式创建一个类型为char[]
的变量,该变量具有静态存储持续时间。字符串将以null结尾,这与C风格一致。
线路
char* line2 = "hello";
大致相当于
static char __string_literal_line2[] = "hello";
// At top of program or something
...
char * line2 = __string_literal_line2;
因此,当你这样做时,char[]
隐式地衰减为char*
。
这方面的一个问题是,数组在某种意义上确实是"const",尝试修改它是未定义的行为,但C标准明确允许您无论如何将其分配给char *
,因此不正确的遗留代码仍将编译,并且兼容C++也允许这样做。
如果您在进行编译时编程以利用字符串文字的"真实形式",有时会非常方便。例如,在这个代码示例中:
在周围传递constexpr对象
class str_const {
const char * const p_;
const std::size_t sz_;
public:
template <std::size_t N>
constexpr str_const( const char( & a )[ N ] )
: p_( a ), sz_( N - 1 ) {}
...
};
str_const
对象现在可以在编译时根据字符串文字构造为constexpr,它将知道字符串文字的大小,即使通常需要迭代或使用C库函数来确定。这是因为它接收的字符串文字是char[]
,而不是char *
,并且它可以绑定到数组的长度,作为模板推导的一部分。因此,这些表达式是合法的,并且str_const
对象在编译时知道字符串的长度:
str_const("foo");
str_const("foobar");
str_const("foobarbaz");
char test[] = "Hello" // adds H e l l o in the stack
当你做一些像f("你好"(这样的事情时,它会保留内存来存储H e l l O\0当你做
char *test = "Hello";
它也将Hello存储在某个地方,并将测试初始化为存储"H"的内存情况。
指针基本上是4字节的整数。你应该尝试一个程序询问密码并像这样验证:
if(password == "mypassword")
您的工作是在生成的二进制文件中查找"mypassword"。
- 如何使用数据对象上的常量指针初始化类
- 使用指针初始化 char 数组或字符串 C++
- 使用无效指针初始化指针声明符的行为是否未定义?
- 指针:初始化与声明
- 启动线程会导致指针初始化时出现分段错误
- 使用函数声明进行函数指针初始化 - 是否可能
- 类初始化中的指针初始化
- 结构数组的指针初始化
- 如何从其抽象母类上的指针初始化子类?
- C 用结构指针初始化结构
- 如何用无效指针初始化unique_ptr的向量
- PCL中的这些增强指针初始化是不同的
- 通过指针初始化结构
- 从函数指针初始化成员函数
- 使用作用域内生成的指针初始化静态成员
- 使用"this"指针初始化 std::array
- C++缺乏指针初始化和使用逻辑
- constexpr 使用指针初始化
- C 指针初始化的不良初始化可能是什么后果
- 指针初始化无效?如果不是,那是什么