Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中的静态常量字符*与常量字符*_C_Memory_Static_String Literals - Fatal编程技术网

C中的静态常量字符*与常量字符*

C中的静态常量字符*与常量字符*,c,memory,static,string-literals,C,Memory,Static,String Literals,C中的const char*和static const char*有什么区别 我认为这个问题的答案是错误的 实际上,const char*元素被放入程序的.rodata部分,否则以下情况将导致segfault: const char* f() { const char* hello = "hello"; return hello; } int main() { const char* hello_after = f(); printf("%s\n", hello

C中的
const char*
static const char*
有什么区别

我认为这个问题的答案是错误的

实际上,
const char*
元素被放入程序的
.rodata
部分,否则以下情况将导致segfault:

const char* f() {
    const char* hello = "hello";
    return hello;
}

int main() {
    const char* hello_after = f();
    printf("%s\n", hello_after);
}
实际上,由于该代码可以工作,因此
f
返回的指针仍然指向活动数据,这表明该数据没有分配到堆栈上,而是存储在
.rodata

但是在我看来,
constchar*
staticconstchar*
对于GCC来说是一样的

但是,为什么
常量int*
静态常量int*
的行为不一样呢?在GCC中硬编码的例外情况是,只有类型
char
const
static const
应该相同吗


非常感谢你的帮助

在此函数声明中

const char* f() {
    const char* hello = "hello";
    return hello;
}
指针hello指向具有静态存储持续时间的字符串文字“hello”。也就是说,具有静态存储持续时间的不是指针,而是具有静态存储持续时间的指针文本。在函数的每次调用中,指针都会重新初始化

如果将函数声明为

const char* f( ) {
    static const char* hello = "hello";
    return hello;
}
在这种情况下,指针本身具有静态存储持续时间。它在程序获得控件之前初始化一次,并且在函数调用之间保留其值

例如,考虑这个演示程序。

#include <stdio.h>

const char* f( int i ) 
{
    static const char* hello = "hello";

    if ( i == 1 ) hello = "bye";
    else if ( i == -1 ) hello = "hello";

    return hello;
}

int main(void) 
{
    puts( f( 0 ) );
    puts( f( 1 ) );
    puts( f( 0 ) );

    return 0;
}
也就是说,最初指针hello是由字符串文本“hello”初始化的

那么由于这个电话,

    puts( f( 1 ) );
它的价值被改变了。现在它指向字符串文字“bye”

第三个电话呢

    puts( f( 0 ) );
指针保留上次调用函数时分配给它的值


这是由于指针具有静态存储持续时间的事实。

这与
常量字符*
关系不大,而与字符串文字(
“hello”
在本例中)关系更大。我认为您误解了链接的答案。他们讨论指针的存储位置,而不是字符串文本。指针的存储方式将因使用
static
而有所不同。如果使用
-fsanitize=address
编译,则会出现运行时错误()引号:“实际上,const char*元素放在程序的.rodata部分…”错误-字符串文字不是指针。谢谢,我理解您的答案!所以我想这里的独特之处在于,我们处理的是字符串文本?如果相反,我们有
const int hello[5]={1,2,3,4,5}.rodata
中。在该示例中,您有一个数组对象,而不是指针对象,这会改变一些情况。一个实现可以做任何能给出正确结果的事情,但是请注意,如果函数是递归输入的,那么必须有两个地址不同的
hello
数组。好的!我现在不知道C对数组的处理与指针不同。@CosmoSterin这个{1,2,3,4,5}不是“数组文字”。这是用于初始化数组元素的初始值设定项。这与您将在块范围char s[]=“hello”中写入的内容相同;用于初始化数组的字符串文字的字符。但是,如果在没有存储说明符static的情况下声明数组,则该数组本身不具有静态存储持续时间。
    puts( f( 0 ) );