【问题标题】:C: Trouble understanding pointers in the while loop of this codeC: 无法理解这段代码的 while 循环中的指针
【发布时间】:2018-06-03 09:59:28
【问题描述】:

我正在使用调试器来阅读这段代码,我对while ((*d++ = *s2++)); 有点困惑 - 在调试器变量中,d 似乎在每次循环后都会缩短(从 'Hello hello' 变为 'ello hello's1 更改为 'cello hello')。循环通过的while循环是什么(不应该是while(condition); do(something))吗?

为什么d和s1的变量值不一样(不是d是指向s1的指针)?而当他们返回主函数时,是curdst=dst的指针吗?

/*    
  Input: char pointers for source (s2) and destination (s1)

  Output: returns the pointer to the destination (s1)
*/

char *my_strcpy(char * , const char * );

int main()
{

  char src[] = "cs23!";
  char dst[]="Hello hello";
  char *curdst;
  int len=0;

  while(src[len++]);

  // do the copy

  curdst= my_strcpy(dst, src);

  // check to see if the NULL char is copied too.

  printf("dst array %s and last element %d\n", dst, atoi(&dst[len]));

  return 0;

}

char *my_strcpy(char *s1, const char *s2) {

  register char *d = s1;

  // print the pointer variables address and their contents, and first char

  printf("s2 address %p, its contents is a pointer %p to first char %c \n", (void *)&s2, (void *)s2, *s2);
  printf("s1 address %p, its contents is a pointer %p to first char %c \n", (void *)&s1, (void *)s1, *s1);

  while ((*d++ = *s2++));
  return(s1);

}

【问题讨论】:

  • 请注意,*d++ = *s2++*d++ == *s2++ 非常不同。在这里,您将使用来自*s2 的值覆盖*d 中的值,直到到达s2 中的空终止符。
  • 这里的条件是*s2不是零(字符串空终止符)。
  • 查看this answer 了解类似情况的详细信息。

标签: c pointers


【解决方案1】:

这是strcpy() 的一个相当典型的教学实现。它的工作原理是这样的:

  • my_strcpy() 接受两个参数。第一个参数是指向目标字符数组的第一个元素的指针。第二个参数是指向源字符串的第一个元素的指针,即以NUL(又名\0)字符结尾的字符数组。该函数将源字符串中的字符复制到目标缓冲区,包括NUL 终止符,并返回一个指向目标缓冲区第一个元素的指针。

    char *my_strcpy(char *s1, const char *s2) {
    
  • 首先,复制第一个参数,因为我们需要在复制完成后返回它。

    char *d = s1;
    
  • 然后,复制字符;这是在一个紧密的循环中完成的,工作方式如下:

    • 将当前字符* s2复制到d指向的地方,如同执行* d = * s2;那么
    • 递增d 指向目标缓冲区中的下一个位置,就像执行d++ 一样,递增s2 指向要复制的下一个字符,就像执行s2++ 一样;和
    • 如果复制的最后一个字符是NUL,则退出循环。

    这写得很简洁:

    while (* d++ = * s2++);
    

    * s2++ 表示“取s2 指向的字符,然后递增s2”。同样,* d++ 作为左侧值意味着“使用d 指向的变量,然后递增d”。运算符的优先顺序有助于省略括号,因为++ 的优先级高于** 的优先级高于=。赋值的值就是被赋值的值,所以当赋值字符的值为0时循环结束。

  • 最后返回s1,函数没有改变。

    return s1;
    }
    

【讨论】:

  • 谢谢!!正在更改*d 更改s1 以便当您返回s1 时,您已将s2 复制到s1?
  • @helloworld:您已将s2指向的字符串复制到s1指向的缓冲区中。
猜你喜欢
  • 2012-10-24
  • 2020-07-06
  • 2021-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-04
  • 2021-09-18
  • 2018-02-21
相关资源
最近更新 更多