C 为什么我可以在字符的内存地址中存储字符串?
我开始理解指针以及如何去引用它们等等。我一直在练习C 为什么我可以在字符的内存地址中存储字符串?,c,string,pointers,char,memory-address,C,String,Pointers,Char,Memory Address,我开始理解指针以及如何去引用它们等等。我一直在练习ints,但我认为char也会有类似的行为。使用*解除引用,使用&访问内存地址 但在我下面的示例中,相同的语法用于设置char的地址,并将字符串保存到相同的变量。这是怎么回事?我想我只是普遍感到困惑,也许我想得太多了 int main() { char *myCharPointer; char charMemoryHolder = 'G'; myCharPointer = &charMemoryHolder;
int
s,但我认为char
也会有类似的行为。使用*
解除引用,使用&
访问内存地址
但在我下面的示例中,相同的语法用于设置char
的地址,并将字符串保存到相同的变量。这是怎么回事?我想我只是普遍感到困惑,也许我想得太多了
int main()
{
char *myCharPointer;
char charMemoryHolder = 'G';
myCharPointer = &charMemoryHolder;
printf("%s\n", myCharPointer);
myCharPointer = "This is a string.";
printf("%s\n", myCharPointer);
return 0;
}
几点意见
97980
的内存块。(97为“a”,98为“b”,0为空终止。)myCharPointer=&charMemoryHolder
后跟printf(“%s\n”,myCharPointer)
不安全。printf应该被传递一个以null结尾的字符串,并且不能保证内存中的值0紧跟在字符charMemoryHolder之后首先,您需要了解“字符串”在C中是如何工作的 “字符串”作为字符数组存储在内存中。由于无法确定字符串的长度,因此在字符串后面追加一个NUL字符,
'\0'
,以便我们知道它的结尾
例如,如果您有一个字符串“foo”,它在内存中可能如下所示:
--------------------------------------------
| 'f' | 'o' | 'o' | '\0' | 'k' | 'b' | 'x' | ...
--------------------------------------------
'\0'
后面的内容恰好是放在字符串后面的内容,可以初始化,也可以不初始化
当您将一个“字符串”分配给类型为char*
的变量时,所发生的情况是该变量将指向字符串的开头,因此在上面的示例中,它将指向'f'
。(换句话说,如果您有一个字符串str
,那么str==&str[0]
总是正确的。)当您将字符串分配给char*
类型的变量时,实际上是将字符串的第0个字符的地址分配给变量。
将此变量传递到printf()
时,它从指定的地址开始,然后逐个遍历每个字符,直到看到'\0'
并停止。例如,如果我们有:
char *str = "foo";
然后将其传递到printf()
,它将执行以下操作:
str
(它给出了'f'
)(str+1)
(它给出了'o'
)(str+2)
(这会给出另一个'o'
)(str+3)
(这会给出“\0”
,因此进程停止)char charMemoryHolder = 'G';
myCharPointer = &charMemoryHolder;
printf("%s\n", myCharPointer);
当
printf()
看到%s
说明符时,它会转到myCharPointer
指向的地址,在这种情况下,它包含'G'
。然后,它将尝试获取'G'
之后的下一个字符,这是未定义的行为。它可能会时不时地为您提供正确的结果(如果下一个内存位置恰好包含'\0'
),但一般来说,您不应该这样做。在C中,字符串文字将计算为指向只读字符数组的指针(用于初始化字符数组时除外)。这是C语言中的一个特例,不能推广到其他指针类型。char*
变量可以保存单个char
变量的地址或字符数组的起始地址。在这种情况下,数组是存储在静态内存区域中的字符串。charMemoryHolder
是一个在内存中有地址的变量
“这是一个字符串。”
是一个存储在内存中的字符串常量,并且还有一个地址
这两个地址都可以存储在myCharPointer
中,并取消引用以访问第一个字符
如果是printf(“%s\n”,myCharPointer)
,指针将被取消引用并显示字符,然后指针将递增。它会重复此操作,直到找到空(值为零)字符并停止
希望您现在想知道当您指向单个'G'
字符时会发生什么,该字符不像字符串常量那样以null结尾。答案是“undefined behavior”(未定义行为),它很可能会打印随机垃圾,直到在内存中找到零值为止,但可以打印正确的值,因此是“undefined behavior”(未定义行为)。使用%c
打印单个字符