是的,局部变量的生命周期在创建它的作用域( {
, )内。}
局部变量具有自动或本地存储。自动,因为一旦创建它们的范围结束,它们就会自动销毁。
但是,您在这里拥有的是一个字符串文字,它是在实现定义的只读内存中分配的。字符串文字与局部变量不同,它们在整个程序生命周期中保持活动状态。它们具有静态持续时间 [Ref 1]寿命。
一个警告!
但是,请注意,任何修改字符串文字内容的尝试都是未定义行为(UB)。不允许用户程序修改字符串文字的内容。
因此,总是鼓励使用const
while 声明字符串文字。
const char*p = "string";
代替,
char*p = "string";
事实上,在 C++ 中,不推荐在没有const
尽管 C 中声明的情况下声明字符串文字。但是,使用 a 声明字符串文字const
给您带来的好处是,如果您尝试修改字符串文字,编译器通常会给您一个警告第二种情况。
示例程序:
#include<string.h>
int main()
{
char *str1 = "string Literal";
const char *str2 = "string Literal";
char source[]="Sample string";
strcpy(str1,source); // No warning or error just Uundefined Behavior
strcpy(str2,source); // Compiler issues a warning
return 0;
}
输出:
cc1:警告被视为错误
prog.c:在函数'main'中:
prog.c:9:错误:传递'strcpy'的参数1会丢弃指针目标类型的限定符
请注意,编译器会警告第二种情况,但不会警告第一种情况。
在这里回答几个用户提出的问题:
与整数文字有什么关系?
换句话说,以下代码是否有效?
int *foo()
{
return &(2);
}
答案是,不,此代码无效。它格式不正确,会产生编译器错误。
就像是:
prog.c:3: error: lvalue required as unary ‘&’ operand
字符串文字是左值,即:您可以获取字符串文字的地址,但不能更改其内容。
但是,任何其他文字(int
、float
、char
等)都是 r 值(C 标准使用术语“表达式的值”来表示这些文字)并且根本无法获取它们的地址。
[参考 1] C99 标准 6.4.5/5“字符串文字 - 语义”:
在翻译阶段 7 中,将一个字节或值为零的代码附加到由一个或多个字符串文字产生的每个多字节字符序列。然后使用多字节字符序列来初始化一个静态存储持续时间和长度刚好足以包含该序列的数组。对于字符串字面量,数组元素的类型为 char,并使用多字节字符序列的各个字节进行初始化;对于宽字符串文字,数组元素的类型为 wchar_t,并使用宽字符序列进行初始化...
如果它们的元素具有适当的值,则未指定这些数组是否不同。如果程序试图修改这样的数组,则行为是 undefined。