San*_*ace 0 c string pointers char memory-address
我开始理解指针以及如何取消引用它们等等.我一直在用ints 练习,但我认为它char会表现得相似.使用*取消引用,使用&访问内存地址.
但在下面的示例中,使用相同的语法来设置a的地址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;
}
Run Code Online (Sandbox Code Playgroud)
首先,您需要了解"字符串"如何在C中工作.
"字符串"存储为内存中的字符数组.由于无法确定字符串的长度,'\0'因此在字符串后面附加NUL字符,以便我们知道字符串的结束位置.
因此,例如,如果你有一个字符串"foo",它可能在内存中看起来像这样:
--------------------------------------------
| 'f' | 'o' | 'o' | '\0' | 'k' | 'b' | 'x' | ...
--------------------------------------------
Run Code Online (Sandbox Code Playgroud)
之后的事情'\0'只是恰好放在字符串之后的东西,可能会也可能不会被初始化.
当您为类型变量分配"字符串"时char *,会发生变量将指向字符串的开头,因此在上面的示例中它将指向'f'.(换句话说,如果你有一个字符串str,那么str == &str[0]总是如此.)当你将一个字符串赋给一个类型的变量时char *,你实际上是将该字符串的第0个字符的地址赋给变量.
当您将此变量传递给printf()它时,它从指向的地址开始,然后逐个遍历每个字符,直到它看到'\0'并停止.例如,如果我们有:
char *str = "foo";
Run Code Online (Sandbox Code Playgroud)
你传递给它printf(),它会做以下事情:
str(给出'f')(str+1)(给出'o')(str+2)(给另一个'o')(str+3)(这使得'\0'流程停止).这也可以得出结论,你目前所做的事实上是错误的.在您的代码中,您有:
char charMemoryHolder = 'G';
myCharPointer = &charMemoryHolder;
printf("%s\n", myCharPointer);
Run Code Online (Sandbox Code Playgroud)
当printf()看到说明%s符时,它会转到指向的地址myCharPointer,在这种情况下它包含'G'.然后它会尝试获取下一个字符'G',这是未定义的行为.它可能会偶尔给你正确的结果(如果下一个内存位置碰巧包含'\0'),但一般情况下你永远不应该这样做.