简体   繁体   English

理解字符串和数组

[英]Understanding strings and arrays

Consider this code. 考虑这段代码。

int main()
{
    char *s, *t;

    s = malloc(4 * sizeof(char));
    strcpy(s, "foo");
    t = s;
    printf("%s %s\n", s, t);         // Output --> foo foo
    strcpy(s, "bar"); // s = "bar"
    printf("%s %s\n", s, t);         // Output --> bar bar
}

There are 2 strings s and t . 有两个字符串st First I set s to "foo" and then make t point to s . 首先我将s设置为"foo" ,然后将t指向s When I print the strings, I get foo foo . 当我打印字符串时,我得到了foo foo

Then, copy "bar" to s and print again, I get bar bar . 然后,将"bar"复制到s并再次打印,我得到bar bar

Why does value of t changes in this case? 在这种情况下,为什么t值会发生变化? (I copied "bar" to s why did t change). (我复制"bar" ,以s为什么t改变)。


Now when I change strcpy(s, "bar") to s = "bar" - 现在,当我将strcpy(s, "bar")更改为s = "bar" -

int main()
{
    char *s, *t;

    s = malloc(4 * sizeof(char));
    strcpy(s, "foo");
    t = s;
    printf("%s %s\n", s, t); // Output --> foo foo
    s = "bar"
    printf("%s %s\n", s, t); // Output --> bar foo
}

This code gives me foo foo and bar foo . 这段代码给了我foo foobar foo

Why didn't it change in this case? 在这种情况下为什么不改变?

This is undefined behaviour , which means anything can happen: 这是未定义的行为 ,这意味着任何事情都可能发生:

char *s, *t;
strcpy(s, "foo");

as strcpy() is writing to a random location in memory because s is an uninitialised pointer. 因为strcpy()正在写入内存中的随机位置,因为s是未初始化的指针。


( after edit that corrected undefined behaviour ) 编辑后修正了未定义的行为

Question 1 - Why does value of t changes in this case? 问题1 - 为什么在这种情况下t的值会发生变化? (I copied "bar" to s why did t change). (我复制了“bar”为什么没有改变)。

This is a pointer assignment: 这是一个指针赋值:

t = s;

and results in both t and s pointing to the same memory that was malloc() and assigned to s earlier. 并导致ts指向malloc()并分配给s的同一内存。 Any change to that memory is visible via both t and s . 通过ts可以看到对该内存的任何更改。

Question 2 - Why isn't t changing in the second case? 问题2 - 为什么在第二种情况下不改变?

This assigns the address of the string literal "bar" to s : 这将字符串文字"bar"的地址分配给s

s = "bar";

so now t and s do not point to the same memory location. 所以现在ts没有指向相同的内存位置。 t points to the memory that was earlier malloc() and assigned to s (because of the t = s; pointer assignment). t指向早期malloc()并分配给s的内存(因为t = s;指针赋值)。

strcpy() and = are very different: strcpy()= 非常不同:

  • strcpy() copies characters to the memory address specified by its first argument strcpy()字符复制到其第一个参数指定的内存地址
  • assignment, = , changes the address which a pointer holds assignment, = ,更改指针所包含的地址
strcpy(s, "foo");

Copies foo to memory location pointed to by s t = s; foo复制到s t = s指向的内存位置; Now, t and s both point to same location Hence, same output 现在, ts都指向相同的位置因此,相同的输出

Now, you copy bar to s . 现在,您将bar复制到s Since both t and s point to same location. 由于ts指向相同的位置。 Hence, same output again. 因此,同样的输出。


Upto this line everything is same 到这一行,一切都是一样的

s = "bar"

You create a string constant bar . 您创建一个字符串常量bar And assign its address to s . 并将其地址分配给s Its a pointer it can point to any memory location. 它是一个可以指向任何内存位置的pointer not necessarily the original one. 不一定是原来的。

Now, 现在,

s points to bar and t still to the earlier location it pointed to in the beginning and hence the output s点, bart仍然在较前位置它在开始时指出,因此输出

a simplistic way to understand could be as follows :- 一种简单的理解方式如下: -

      s = malloc(4 * sizeof(char));    // this will be interpreted as follows 
      s = 123 ------------>|   |   |   |   | //some garbage values at these location
                           123  124 125 126   // some random address chosen.

      strcpy(s, "foo") ; // it copies at the address provided by s i.e.
                             |'f'|'o'|'o'|'\0'|
                              123 124 125  126 

      t = s;      this statement means t it pointing to address = 123

      strcpy(s, "bar"); // this statement copies at given address it means it will   override previous value .   i.e
                            |'b'|'a'|'r'|'\0'|
                             123 124 125 126

now t still pointing to address 123 that is why t, s both prints bar . 现在仍然指向地址123,这就是为什么t,s都打印条形码。

       s = "bar"  // this will  assign a new address to s which is base address of "bar" string . i.e .          
                           |'b'|'a'|'r'|'\0'|
                            321 322 323 324     

now s will contain address 321 while t has value 123 that is why s and t are giving different values . 现在s将包含地址321而t具有值123,这就是s和t给出不同值的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM