第一个方法,当然是用循环遍历
现在说的是,定义一个函数,用函数+循环来实现这一操作
#include <stdio.h>
void copyArray(int *source, int *destination, int size) {
// 使用指针遍历源数组并拷贝到目标数组
for (int i = 0; i < size; i++) {
*(destination + i) = *(source + i);
}
}
int main() {
int source[] = {1, 2, 3, 4, 5}; // 源数组
int size = sizeof(source) / sizeof(source[0]); // 计算数组大小
int destination[size]; // 目标数组
// 调用拷贝函数
copyArray(source, destination, size);
// 打印拷贝后的数组
printf("拷贝后的数组: ");
for (int i = 0; i < size; i++) {
printf("%d ", destination[i]);
}
printf("\n");
return 0;
}
为什么是 copyArray(source, destination, size);而不是 copyArray(&source, &destination, size);?
在 C 语言中,数组名(如 source
和 destination
)在大多数上下文中会被自动转换为指向数组第一个元素的指针。当你调用 copyArray(source, destination, size);
时,就已经是传入的地址
所以,void函数返回类型,但是只要你将形参定义成(对应的)指针类型,就能直接在地址层次实现对实参的修改(具体的内容在下一章)
//你得记住,那这样函数里面都得加上解引用符号*
*(destination + i) = *(source + i);
这串代码涉及到了指针的加减运算,利用好循环来逐渐增加i的值,就能实现拷贝这一操作
既然谈到了指针减法,那就系统说说指针的运算
指针+=一个整数
指针+-一个整数n,编译器并非是将相应地址(指针)直接加减这个整数,而是将指针的地址(这句话很奇怪)增加 n
乘以指针所指向类型(int这些,不是自身的4字节)的大小(以字节为单位)
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // ptr 指向 arr 的第一个元素
// ptr + 1 实际上是 ptr + sizeof(int) = ptr + 4 byte
printf("%d\n", *(ptr + 1)); // 输出 20
这样其实就是我们刚了解指针所提到的内容,增加的地址不是单纯地增加i,这却意味着 ptr + i
指向的是下一个 对应类型的 元素,这又与我们所开始以为的相同
指针减指针
当你执行 ptr1 - ptr2
时,等价于 (ptr1 的地址 - ptr2 的地址) / sizeof(指针类型)。这意味着,如果 ptr1
和 ptr2
是指向同一数组的指针,结果将是它们之间的元素数量
所以不必再纠结为什么是某某某,到底是减的自己不算还是被减的不算?没有加1就是舍弃其中一个!你学数学的
同时,指针减法只适用于指向同一数组的指针。如果两个指针不指向同一数组,结果是未定义的
指针减法的结果是一个整数,表示元素的数量,而不是字节数(毕竟有“/sizeof(指针类型)”这一步)
第二种方法,使用memcpy函数,它可以用来快速地拷贝数组而不需要使用循环。memcpy 的原型定义在 <string.h>
头文件中
//挺奇怪的,我还以为string.h里全是针对字符和字符数组的
int srcArray[] = {1, 2, 3, 4, 5};
int destArray[5]; // 目标数组
// 使用 memcpy 复制数组
memcpy(destArray, srcArray, sizeof(srcArray));
目标内存地址在第一个位置,数据将被复制到这里,同strcat、strcpy
n
:要复制的字节数(通常等同于第二个位置,即源数组的字节数)
这尤其要注意的是还要第三个位置,请确保传递给 memcpy
的字节数正确。通常可以使用 sizeof
运算符来计算数组的大小(对源内存地址无脑使用sizeof其实就可以了,我认为不能用strlen(如果是字符数组的话),因为sizeof才是源数组真实的字节数)
memcpy
是一个通用的内存复制函数,不会进行类型检查,因此在使用时要确保源和目标的类型兼容
//就是说和指针与指针之间的减法类似,用memcpy来copy必须要求数组的类型相同
Comments NOTHING