线
char *const name_ptr = "Test";
很好;您正在使用字符串字面量的地址初始化指针,该地址"Test"
是一个存储数组char
,其内存在程序启动时分配并保持到程序终止。
关于const
预选赛的快速题外话:
在 C 中,声明形式
const T foo = expr;
或者
T const foo = expr;
表示foo
可能无法写入;它在创建时被分配了expr的值,并且该值在1)foo
的剩余生命周期内可能不会更改。使用指针变量,它变得有点复杂:
const T *p = expr;
T const *p = expr;
两者都声明p
为指向const数据的非 const指针;IOW,您可以更改(可以指向不同的对象) 的值,但不能更改 ( 您不能更改指向的值) 的值。p
p
*p
p
T * const p = expr;
声明p
为指向非 const数据的const指针;您可以更改指向 ( ) 的值,但不能更改为指向不同的对象。 p
*p = ...
p
const T * const p = expr;
T const * const p = expr;
两者都声明p
为指向const数据的const指针;您无法更改的值或指向的内容。 p
p
在 C 中,字符串文字如"Test"
存储为 的数组char
,但尝试修改字符串文字的内容是未定义的行为(取决于平台,您可能会遇到访问冲突)。为了安全起见,通常最好将指向字符串文字的指针声明为const char *
or char const *
,而不是char * const
像上面的示例中那样。
据,直到...为止
void BadPointer() {
int* p; // allocate the pointer, but not the pointee
*p = 42; // this dereference is a serious runtime error
}
是p
一个auto
变量,它没有被初始化为任何特定的值;它将包含一个随机位串,该位串可能对应也可能不对应于可写地址。正因为如此,语句的行为*p = 42;
是未定义的——你可能会遇到访问冲突,你可能会覆盖一些重要的东西并使程序处于错误状态,或者它可能看起来“工作”没有问题(写给一些可访问且不重要的随机内存区域)。
通常,仅从指针值2)无法判断给定指针值是有效还是无效。一个例外是特殊的指针值 NULL,它是一个定义明确的“无处”,可以保证与任何有效的指针值进行比较不相等。在文件范围(在任何函数之外)或使用static
限定符声明的指针变量被隐式初始化为 NULL。非静态的块范围指针变量应始终使用 NULL 或有效地址显式初始化。这样,您可以轻松检查指针是否已分配有效值:
int *p = NULL;
...
if (p != NULL) // or simply if (p)
{
*p = 42;
}
else
{
// p was not assigned a valid memory location
}
1) 请注意,在 C 中,foo
不是编译时常量;它是一个常规的运行时变量,你不能写入它。您不能在需要编译时常量的上下文中使用它。
2) 如果您非常熟悉您的平台的内存模型,您可以做出一些有根据的猜测,但即使这样也不能保证。