为什么我可以将字符串存储在char的内存地址中?

时间:2015-11-22 07:11:58

标签: c string pointers char memory-address

我开始理解指针以及如何取消引用它们等等。我一直在练习int,但我认为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;
}

4 个答案:

答案 0 :(得分:6)

首先,您需要了解“字符串”在C中的工作原理。

“Strings”作为字符数组存储在内存中。由于无法确定字符串的长度,因此在字符串后面附加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(),它将执行以下操作:

  1. 取消引用str(提供'f'
  2. 取消引用(str+1)(提供'o'
  3. 解除引用(str+2)(提供另一个'o'
  4. 取消引用(str+3)(提供'\0'以便流程停止)。
  5. 这也可以得出结论,你目前所做的事实上是错误的。在您的代码中,您有:

    char charMemoryHolder = 'G';
    myCharPointer = &charMemoryHolder;
    printf("%s\n", myCharPointer);
    

    printf()看到%s说明符时,它会转到myCharPointer指向的地址,在这种情况下它包含'G'。然后它将尝试在'G'之后获取下一个字符,这是未定义的行为。它可能偶尔给你正确的结果(如果下一个内存位置碰巧包含'\0'),但一般情况下你永远不应该这样做。

答案 1 :(得分:2)

几条评论

  1. c中的静态字符串被视为(char *)到null终止 字符数组。例如。 “ab”本质上是97 98 0的内存块的char *。 (97是'a',98是'b',0是空终止。)
  2. 您的代码myCharPointer = &charMemoryHolder;后跟printf("%s\n", myCharPointer) 安全。 printf应该传递一个以null结尾的字符串,并且不能保证内存中包含值0,紧跟在你的字符charMemoryHolder之后。

答案 2 :(得分:0)

在C中,字符串文字计算为指向只读的字符数组的指针(用于初始化char数组时除外)。这是C语言中的特殊情况,不会推广到其他指针类型。 char *变量可以保存单个char变量的地址或字符数组的起始地址。在这种情况下,数组是一串字符,存储在内存的静态区域中。

答案 3 :(得分:0)

charMemoryHolder是一个在内存中有地址的变量。

"This is a string."是一个字符串常量,存储在内存中并且还有一个地址。

这两个地址都可以存储在myCharPointer中并取消引用以访问第一个字符。

printf("%s\n", myCharPointer)的情况下,指针将被取消引用并显示字符,然后指针递增。它重复此操作直到找到null(值为零)字符并停止。

希望您现在想知道当您指向单个'G'字符时会发生什么,该字符不像字符串常量那样以空值终止。答案是"未定义的行为"并且很可能会打印随机垃圾,直到它在内存中找到零值,但可以打印出正确的值,因此"未定义的行为"。使用%c打印单个字符。