首先说一下怎么理解拷贝这个概念,从最简单的开始,以整型变量为例:
#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'是否会拷贝过去:会。
因为先进行指针赋值操作,再进行判断。
网友评论