【问题标题】:I don´t understand this C program made with pointers我不明白这个用指针编写的 C 程序
【发布时间】:2020-01-12 01:27:51
【问题描述】:

我看到这个 C 程序使用指针将第一个字符串复制到第二个字符串。

void copy(char const *s1, char *s2)
{ 
    for(;(*s2=*s1);++s1,++s2){};
}

我不明白停止 for 循环的条件,因为我可以写 (*s2=*s1)!='\0' 并且它可以工作,但如果我不写 !='\0' 它也可以工作。 for 循环如何知道何时停止?

【问题讨论】:

  • for 循环在条件表达式为 false 或 0 时停止。(*s2 = *s1) 有一个值。如果该值为 0,那么它被认为是错误的。如果不为0,则认为是真的。
  • “我明白为什么会这样,但我看不出 for 循环如何知道何时停止”——这似乎是一个自相矛盾的陈述。
  • 该函数用于复制zero-terminated(C风格)字符串。
  • @JohnColeman 我认为 OP 意味着他们知道它如何复制字符,但不知道它是如何知道它何时到达字符串末尾的。
  • while (*s2++ = *s1++) {;} Kernighan-copy.

标签: c loops for-loop pointers


【解决方案1】:

括号表示测试标准是分配给s1(左操作数)指向的位置的结果。换句话说,循环一直运行到*s2 的值为假。

(*s2=*s1)!='\0'相当于(*s2=*s1)!=0,相当于(*s2=*s1);或(*s2=*s1)==true,如果您愿意。显然一个非零值被评估为真,所以循环一直运行直到第二个字符串有一个 nul 终止符。

【讨论】:

  • 这是一种在语义上表明正在执行测试的编程风格。喜欢if( ... )while( ... )
  • ifwhile 中的括号不是样式。它们是语法要求的。
  • “喜欢”是“让读者想到”,而不是“等同于”。
  • 答案的第二部分是Ok。但是,for() 内的 *s2=*s1 周围的括号实际上什么都不做,并且不表示测试标准。虽然ifwhile 需要@EricPostpischil 提到的括号,但? 表达式不需要它并且通常不在那里使用。
【解决方案2】:

单引号之间的字符是字符。 char \0 的值为 0 因此

char a = '\0`;

等于

char a = 0;

因此if (x != '\0') 等于if (x != 0),这等于if (x)for 的条件类似。

【讨论】:

  • '\0'int
  • 没错,但 OP 使用的是char *s。
【解决方案3】:

这是 C 如何区分真假的核心。

True 是任何非零值(整数中的任何位)。虽然像 ==> 这样的条件测试会产生 1 的值,但任何非零值都适用于 true。

False 是零值(整数中的所有位都关闭),其中包括指针中的NULL

'\0' 的值当然是二进制零,因此for 的条件部分中的(*s2++=*s1++) 对非零进行了隐式测试,因此这可以正常工作,直到\0 为复制。 \0 返回 false 并退出循环。添加您自己的!='\0' 就是为其添加显式测试。

注意: 如果您只是使用了不正确的 *s1++ = *s2++ != '\0' 而没有括号,它将被视为非常错误的 *s1++ = (*s2++ != '\0'),它会将一系列 1 分配给 *s1,然后是 @987654333 @ 终止“字符串”。哎呀。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    • 2014-12-01
    相关资源
    最近更新 更多