林江楠 发表于 2021-11-15 20:35:52

小甲鱼课后习题进阶版strncpy函数

本帖最后由 林江楠 于 2021-11-15 20:37 编辑

#include <stdio.h>

#define MAX 1024

int main()
{
      char str1;
      char str2;

      char *target1 = str1;
      char *target2 = str2;

      char ch;
      int n;

      printf("请输入一个字符串到 str1 中:");
      fgets(str1, MAX, stdin);

      printf("请输入需要拷贝的字符个数:");
      scanf("%d", &n);

      printf("开始拷贝 str1 的内容到 str2 中...\n");
      while (n--)
      {
               ch = *target2++ = *target1++;
               if (ch == '\0')
               {
                     break;
               }
               if ((int)ch < 0)
               {
                     *target2++ = *target1++;
                     *target2++ = *target1++;
               }
      }

      *target2 = '\0';

      printf("拷贝完毕!\n");
      printf("现在,str2 中的内容是:%s\n", str2);

      return 0;
}

为什么要写那麽多*target2++ = *target1++;
这串代码从while开始就不懂了


为社么能拷贝中英混合的字符串

看不懂

人造人 发表于 2021-11-15 21:36:57

#include <stdio.h>

#define MAX 1024

int main()
{
      char str1;
      char str2;

      char *target1 = str1;
      char *target2 = str2;

      char ch;
      int n;

      printf("请输入一个字符串到 str1 中:");
      fgets(str1, MAX, stdin);

      printf("请输入需要拷贝的字符个数:");
      scanf("%d", &n);

      printf("开始拷贝 str1 的内容到 str2 中...\n");
      while (n--)
      {
               //ch = *target2++ = *target1++;
               *target2 = *target1;
               ch = *target2;
               target1++;
               target2++;

               if (ch == '\0')
               {
                     break;
               }
               if ((int)ch < 0)
               {
                     //*target2++ = *target1++;
                     *target2 = *target1;
                     target1++;
                     target2++;

                     //*target2++ = *target1++;
                     *target2 = *target1;
                     target1++;
                     target2++;

               }
      }

      *target2 = '\0';

      printf("拷贝完毕!\n");
      printf("现在,str2 中的内容是:%s\n", str2);

      return 0;
}

wutianlong220 发表于 2021-11-15 22:06:13

本帖最后由 wutianlong220 于 2021-11-15 22:18 编辑

先贴上我自己写的答案,测试有效:
#include <stdio.h>
#define MAX 1024


int main(void) {
   
    char str1 = {'\0'};
    char str2 = {'\0'};
    int num;
    int start = 0;


    printf("请输入一个字符串到 str1 中:");


    fgets(str1, MAX, stdin);
   
    printf("请输入您需要拷贝的字符个数:");
    scanf("%d",&num);
   
    printf("您输入的字符是:%s\n",str1);
   
    printf("开始拷贝 str1 的内容到 str2 中...\n");

    char *str1_p = str1;
    char *str2_p = str2;


    while((start < num)&&*str1_p != '\0'   ) {
      int ch = (int)*str1_p;
      if (ch < 0) { //这里是专门对中文的处理,因为中文是4个字节,3个负数1个0,所以指针需要复制3次
            *str2_p++ = *str1_p++;
            *str2_p++ = *str1_p++;
            *str2_p++ = *str1_p++;
      } else {
            *str2_p++ = *str1_p++;
      }
      start++;
    }
   
    printf("拷贝完毕!\n");
    printf("现在,str2 中的内容是:%s\n",str2);


    return 0;
}


然后来给你解释一下
*target2++ = *target1++;

这句话到底是什么意思。

这句话的其实就是著名的代码:*p++
所谓的*p++,就是分成两个步骤:
第一,*p
第二,p++


因为p++,是先把p拿过来用,用完了以后再+1,所以整个*p++的意思就是:
p这个指针,先用*符号解引用,拿出里面的东西,然后指针p再向后面移动一位。
如果不太理解,可以点击这里:https://www.bilibili.com/video/BV1sJ411E7St?p=87
可以参考这个视频,从12分28秒开始看,相信你会有所领悟。

懂了之后
然后我们再来看
*target2++ = *target1++

这段代码的意思就是说:
先执行:
*target2 = *target1
也就是先把target1指针,指向的内容,赋值给target2指针指向的地方,
然后:
target2++;
target1++;
也就是两个指针,同时向后移动一位。

懂了吧?
放在这个题目里面就相当于:
str1 = str2
然后
str1 = str2
然后
str1 = str2
然后
str1 = str2
一直这样下去。

所以就是,str2和str1这个数组,两个同时向后,一个一个去遍历,遍历一个,str2把内容给str1,然后再遍历到下一个,str2再把内容给str1,然后从数组的最初,一直折腾到指定位置,这样就完成了复制。
所以,关键在于你要记住:
*p++
这个东西,一定要牢牢记住,这个非常重要。


林江楠 发表于 2021-11-17 08:33:48

wutianlong220 发表于 2021-11-15 22:06
先贴上我自己写的答案,测试有效:




自增运算符的优先级高于取值运算符

林江楠 发表于 2021-11-17 08:37:05

wutianlong220 发表于 2021-11-15 22:06
先贴上我自己写的答案,测试有效:




这个相当于*(target++)

林江楠 发表于 2021-11-17 08:41:01

人造人 发表于 2021-11-15 21:36


为什么小于0的时候需要两次target1++=target2++

wutianlong220 发表于 2021-11-17 11:21:45

因为小于0的时候,代表这个字符是中文啊,正常的英文字母只占1个位置,所以
target1++=target2++
只需要这样复制且移动一下就行。
但是一个中文,比一个英文多占用2个字节,所以指针还得多向后面移动2位,才能把一个中文完整复制过来,懂了吧?

wutianlong220 发表于 2021-11-17 11:23:32

林江楠 发表于 2021-11-17 08:37
这个相当于*(target++)

你这样括号括起来就错了,括号括起来代表括号必须先执行。
实际上是相当于:
*target++ //这个代码就等于下面的代码

*target;
target++;

人造人 发表于 2021-11-17 11:51:02

林江楠 发表于 2021-11-17 08:41
为什么小于0的时候需要两次target1++=target2++

因为这里假设一个中文字符是3个字节
你那边可能是2个字节也可能是3个字节
这个程序假设是3个字节
这个程序还假设中文字符的3个字节都是负数
所以,小于0就加2次

人造人 发表于 2021-11-17 11:55:31

wutianlong220 发表于 2021-11-17 11:23
你这样括号括起来就错了,括号括起来代表括号必须先执行。
实际上是相当于:

    int num = *p++;


这个相当于下面这样

      int *temp = p;
      p++;
      num = *temp;


完整的代码
#include <stdio.h>

int main(void) {
    int array = {1, 2, 3, 4, 5};
    int *p = array;
    int num = *p++;
    {
      int *temp = p;
      p++;
      num = *temp;
    }
    return 0;
}

tomok 发表于 2021-11-17 14:49:14

学习 来了

林江楠 发表于 2021-11-17 17:10:05

wutianlong220 发表于 2021-11-17 11:23
你这样括号括起来就错了,括号括起来代表括号必须先执行。
实际上是相当于:

不是吧

自增运算符的优先级高于取值运算符

先加在解引用

wutianlong220 发表于 2021-11-17 20:47:58

林江楠 发表于 2021-11-17 17:10
不是吧

自增运算符的优先级高于取值运算符


自增运算符的优先级高于取值运算符,这个是对的。但是q++这个自增,是先用完q之后再自增,跟++q的先加了数字再用,是不一样的。
页: [1]
查看完整版本: 小甲鱼课后习题进阶版strncpy函数