【问题标题】:Pointer C Language [closed]指针 C 语言
【发布时间】:2020-10-30 19:13:04
【问题描述】:

我从 deitel 的书中举了这个例子。你能解释一下string1是如何存储整个字符串的吗?

#include <stdio.h>
#define SIZE 80

void mystery1(char *s1, const char *s2); // prototype

int main(void)
{
   char string1[SIZE]; // create char array
   char string2[SIZE]; // create char array

   puts("Enter two strings: ");
   scanf("%79s%79s" , string1, string2);
   mystery1(string1, string2);
   printf("%s", string2);
} 

// What does this function do?
void mystery1(char *s1, const char *s2)
{
   while (*s1 != '\0') {
      ++s1;
   } 

   for (; *s1 = *s2; ++s1, ++s2) {
      ; // empty statement
   } 
}

【问题讨论】:

  • *s1 = *s2 将第二个字符串连接到第一个字符串上,测试'\0' nul 终止符作为循环条件。但这是缓冲区溢出的秘诀。
  • 它是 strcat。但是限制是错误的,string1 应该有 159 个字节
  • 其实this就是strcat。
  • 奥秘是程序打印string2而不是string1的原因。这是为了展示未定义的行为吗?
  • @RobertHarvey:不,实际上this 是strcat!

标签: c pointers


【解决方案1】:

这个函数有什么作用?

它连接两个字符串,即它与标准 strcat 函数的作用相同。见https://man7.org/linux/man-pages/man3/strcat.3.html

假设输入是“Hello World”。

当函数被调用时,它在内存中的某个地方看起来像:

String1: Hello\0
         ^
         |
         s1

String2: World\0
         ^
         |
         s2

现在这部分

while (*s1 != '\0') {
  ++s1;
} 

将指针@​​987654325@ 移动到String1 的末尾。所以你有

String1: Hello\0
               ^
               |
               s1

String2: World\0
         ^
         |
         s2

然后这部分

for (; *s1 = *s2; ++s1, ++s2) {
  ; // empty statement
} 

将字符从String2(使用s2)复制到String1 的末尾(使用s1)。

一个循环后,您将拥有:

String1: HelloWorldW
                    ^
                    |
                    s1

String2: World\0
          ^
          |
          s2

再循环一次后,您将拥有:

String1: HelloWorldWo
                     ^
                     |
                     s1

String2: World\0
           ^
           |
           s2

等等。

最终你会拥有

String1: HelloWorld\0
                     ^
                     |
                     s1

String2: World\0
                ^
                |
                s2

净结果:String2 连接到 String1

多说几句for (; *s1 = *s2; ++s1, ++s2) {

The ; says: no initialization needed

The *s1 = *s2; says: Copy the char that s2 points to to the memory that s1 points to. 
Further, it serves as "end-of-loop" condition, i.e. the loop will end when a \0 has 
been copied

The ++s1, ++s2 says: Increment both pointers

这样String2中的字符会被一一复制到String1的末尾

顺便说一句:请注意main 函数是不安全的,因为为String1 保留的内存太少

【讨论】:

  • 感谢您的帮助!
猜你喜欢
  • 2021-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-09
  • 2019-03-19
  • 2016-02-14
相关资源
最近更新 更多