在 C 中转换泛型指针

Casting generic pointers in c

我在一本书中找到这段代码,试图解释通用指针如何使用它来将一个矩阵复制到另一个矩阵。

#include <stdio.h>

#define FILAS 2
#define COLS 3

void copiarMatrices(void *, void *, int);

int main(){

    int m1[FILAS][COLS] = {24, 30, 15, 45, 34, 7};
    int m2[FILAS][COLS];

    copiarMatrices(m2, m1, sizeof(m1));

    for (int i = 0; i < FILAS; i++){
        for (int j = 0; j < COLS; j++) printf("%d ", m2[i][j]);
        printf("\n");
    }
}

void copiarMatrices(void *dest, void *orig, int n){
    char *destino = (char *)dest;
    char *origen = (char *)orig;

    for (int i = 0; i < n; i++) {
        destino[i] = origen[i];
    }
}

书上说我们唯一可以转换 void 指针的数据类型是 char,因为字节大小不允许其他数据类型。

我不明白这一点,而且如果我在 void 指针上使用 int 或 double 数据类型执行程序,程序会卡住几秒钟然后顺利完成。

书上说的是“sizeof”运算符的结果是表达式参数的大小(以字节为单位)。相反,如果您要指定“sizeof(m1) / sizeof(int)”,那么您需要将参数转换为“int *”而不是“char *”,因为您将传递要复制的整数数量而不是字节数。

函数copiarMatrices复制任意大小的缓冲区。假设缓冲区 orig 是 5 个字节。如果您在 copiarMatrices 内转换为 int * 并且 int 是 4 个字节,我想将所有 5 个字节从 orig 复制到 dest 而不是 n不会是整数(如果 n=1 则复制 4 个字节,如果 n=2 则复制 8 个字节但我需要复制 5 个字节)。因此,我们可以同意按字节进行复制,n 表示将被复制的字节数。一般来说,你必须打电话给 copiarMatrices(m2, m1, FILAS * COLS * sizeof(int));

您不需要任何特殊功能。你的函数 copiarMatrices 可以简化为 memcpy(m2, m1, sizeof(m1));

一些评论。

  1. 请勿使用 int 作为尺码。请改用正确的 size_t 类型。
  2. 努力const正确。
  3. Return 对目标对象的引用,它将允许在表达式中使用该函数。

你的函数原型应该是:void *copiarMatrices(void *, const void *, const size_t);。如果你想让编译器的生活更轻松,你可以:void *copiarMatrices(void restrict *, const void * restrict, const size_t);