11.10 周末晚上 拷贝数组的两种方法、指针的加减法运算

发布于 10 天前  13 次阅读


第一个方法,当然是用循环遍历

现在说的是,定义一个函数,用函数+循环来实现这一操作

#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 语言中,数组名(如 sourcedestination)在大多数上下文中会被自动转换为指向数组第一个元素的指针。当你调用 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(指针类型)。这意味着,如果 ptr1ptr2 是指向同一数组的指针,结果将是它们之间的元素数量

所以不必再纠结为什么是某某某,到底是减的自己不算还是被减的不算?没有加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必须要求数组的类型相同

届ける言葉を今は育ててる
最后更新于 2024-11-16