2015-11-22 93 views
0

我开始明白指针,以及如何解除引用他们等我一直在练习与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; 
} 

回答

6

首先,你需要了解如何“串”工作C.

“字符串”存储为字符的内存中的数组。由于没有办法确定字符串的长度,所以在字符串后面追加NUL字符'\0',以便我们知道它的结束位置。

因此,举例来说,如果你有一个字符串“foo”,它可能看起来像这样的记忆:

-------------------------------------------- 
| 'f' | 'o' | 'o' | '\0' | 'k' | 'b' | 'x' | ... 
-------------------------------------------- 

'\0'后的东西只是东西,恰好被放置在字符串之后,这可能是可能不会被初始化。

当你给一个类型为char *的变量赋值一个“字符串”时,会发生什么变量会指向字符串的开始,所以在上面的例子中它会指向'f'。 (换句话说,如果你有一个字符串str,那么str == &str[0]总是如此。)当你给一个char *类型的变量赋值一个字符串时,实际上是将该字符串的第零个字符的地址赋值给该变量。

当您将此变量传递给printf()时,它将从指向地址开始,然后逐个遍历每个字符,直到看到'\0'并停止。例如,如果我们有:

char *str = "foo"; 

,你把它传递给printf(),它将执行以下操作:

  1. 提领str(这给'f'
  2. 提领(str+1)(这给'o'
  3. Dereference (str+2)(它给出了另一个'o'
  4. 解除引用(str+3)(它给出'\0',这样过程停止)。

这也得出结论,你目前的行为实际上是错误的。在你的代码有:

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

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

2

几点意见

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

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

0

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

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

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

printf("%s\n", myCharPointer)的情况下,指针将被解除引用并显示字符,然后指针递增。它重复这个直到找到一个空(零值)字符并停止。

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

相关问题