字符串的拷贝与strcpy()的实现

2019-07-30  本文已影响0人  mark_x

首先说一下怎么理解拷贝这个概念,从最简单的开始,以整型变量为例:

#include <stdio.h>

int main()
{
    int a = 1;
    int b;
    
    b = a;
    printf("a = %d, b = %d\n", a, b);
    
    a = 2;
    printf("a = %d, b = %d\n", a, b);   
        
    return 0;
}

// 输出结果:
// a = 1, b = 1
// a = 2, b = 1

从以上例子可以看出,把变量a的值赋给变量b后,再对a进行操作,不影响变量b的值。因此对于整型变量、字符变量而言,赋值过程就相当于拷贝。

但是对于数组而言,情况就不同了,数组不允许直接赋值,比如

int a[] = {1, 2, 3, 4, 5};
int b[5];

b = a;

这样写是错误的。因为a 和 b 是数组名,而数组名表示的是数组“第一个元素”的“起始地址”。即 a 和 b 表示的是地址,是一个常数,不能将一个常数赋给另一个常数。这种错误就类似于将 3 赋给 2,所以是错误的。

正确的写法是用 for 循环,将数组 a 中的元素一个一个赋给数组b的元素,下面采用指针完成拷贝操作。

#include <stdio.h>

#define MAX 1024

int main()
{
        char str1[MAX];
        char str2[MAX];

        char *target1 = str1;  // 定义指针指向数组名,也是数组第一个元素的地址
        char *target2 = str2;

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

        printf("开始拷贝 str1 的内容到 str2 中...\n");
        while ((*target2++ = *target1++) != '\0')
        {
            ;  // 循环体内为空语句
        }

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

        return 0;
}

重点解释while循环的判断语句(*target2++ = *target1++) != '\0'
括号的优先级最高,先看括号内的语句,由于自增运算符在后面,也可以先不看,就变成了*target2 = *target1,用*target1取出数组str1第一个元素,赋给str2的第一个元素;然后指针位置都加一,括号的运算结果为数组第一个元素(注意不是第二个,取值运算是在自增运算符使指针位置加一之前),不等于'\0',满足条件。

分析'\0'是否会拷贝过去:会。
因为先进行指针赋值操作,再进行判断。

上一篇下一篇

猜你喜欢

热点阅读