在 C 语言中传递数组到函数时,需要特别注意 数组退化(Array Decay) 的特性。以下是不同场景下的实现方法及示例:


一维数组的传递

1. 通过指针传递(推荐)

// 函数声明
void process_array(int *arr, int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
}

// 调用示例
int main() {
    int arr[] = {1, 2, 3, 4, 5};
    process_array(arr, 5);  // 直接传递数组名
    return 0;
}

2. 通过数组语法(编译器自动转换为指针)

void process_array(int arr[], int size) {  // 等价于 int *arr
    // 相同实现
}

二维数组的传递

1. 固定列数(适用于静态数组)

// 函数声明(必须指定列数)
void process_matrix(int mat[][3], int rows) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d ", mat[i][j]);
        }
    }
}

// 调用示例
int main() {
    int mat[2][3] = {{1, 2, 3}, {4, 5, 6}};
    process_matrix(mat, 2);  // 直接传递数组名
    return 0;
}

2. 动态二维数组(指针形式)

// 函数声明
void process_dynamic_matrix(int **mat, int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf("%d ", mat[i][j]);
        }
    }
}

// 调用示例(动态分配)
int main() {
    int rows = 2, cols = 3;
    int **mat = malloc(rows * sizeof(int*));
    for (int i = 0; i < rows; i++) {
        mat[i] = malloc(cols * sizeof(int));
    }
    process_dynamic_matrix(mat, rows, cols);
    // 记得释放内存
    return 0;
}

动态一维数组的传递

// 函数声明(与静态数组一致)
void process_dynamic_array(int *arr, int size) {
    // 相同实现
}

// 调用示例
int main() {
    int size = 5;
    int *arr = malloc(size * sizeof(int));  // 动态分配
    process_dynamic_array(arr, size);
    free(arr);  // 释放内存
    return 0;
}

结构体包含数组的传递

1. 直接传递结构体

typedef struct {
    int data[5];
    int size;
} MyArray;

void process_struct_array(MyArray arr) {
    for (int i = 0; i < arr.size; i++) {
        printf("%d ", arr.data[i]);
    }
}

// 调用示例
int main() {
    MyArray arr = {{1, 2, 3, 4, 5}, 5};
    process_struct_array(arr);
    return 0;
}

2. 传递结构体指针(避免拷贝大结构体)

void process_struct_ptr(const MyArray *arr) {
    for (int i = 0; i < arr->size; i++) {
        printf("%d ", arr->data[i]);
    }
}

// 调用示例
process_struct_ptr(&arr);

关键注意事项

  1. 数组退化
    数组作为参数传递时,会退化为指针(丢失长度信息),因此通常需要额外传递数组大小(如 int size)。

  2. 动态内存管理
    动态分配的数组(如通过 malloc)需手动释放内存,避免内存泄漏。

  3. 多维数组的列数
    静态二维数组的函数参数必须指定列数(如 int mat[][3])。

  4. 类型一致性
    确保数组类型(如 float*)与函数参数声明一致。


错误示例分析

假设有以下错误代码:

void wrong_func(int *arr[5]) {  // 错误:实际是 int **arr
    // 操作
}

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    wrong_func(arr);  // 报错:int* 无法赋值给 int**
    return 0;
}

修复方法:

// 正确声明
void correct_func(int *arr, int size) {
    // 操作
}

// 调用
correct_func(arr, 5);

通过遵循上述方法,可以确保数组在函数间正确传递和操作。如果有具体代码或错误信息,可进一步分析优化。