Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Truyền mảng theo giá trị (Pass by value) trong C

Lưu ý quan trọng: C không hỗ trợ truyền mảng theo giá trị thực sự. Khi truyền mảng vào hàm, nó decay thành con trỏ trỏ đến phần tử đầu tiên. Hàm nhận con trỏ, không phải bản sao mảng.

Ví dụ minh họa (Thực tế là pass-by-pointer)

#include <stdio.h>

// Tham số thực tế là float* a, KHÔNG phải float a[]
float avg(float a[]) {
    int i;
    float sum = 0.0f;
    for (i = 0; i < 6; ++i) {
        sum += a[i];
    }
    return sum / 6;
}

int main() {
    float a[] = {63, 21, 34.4, 12.5, 3, 2.2};
    float avg1 = avg(a); // a decay thành &a[0]
    printf("Trung bình: %f\n", avg1);
    return 0;
}

Kết quả

Trung bình: 22.683332

Chứng minh mảng decay thành con trỏ

void func(int arr[]) {
    printf("Size trong hàm: %zu\n", sizeof(arr)); // Size của con trỏ (4 hoặc 8)
}

int main() {
    int arr[10];
    printf("Size trong main: %zu\n", sizeof(arr)); // 40 (10 * 4)
    func(arr);
    return 0;
}

Kết quả

Size trong main: 40
Size trong hàm: 8  (trên 64-bit)

Cách truyền mảng THEO GIÁ TRỊ thực sự (C++)

C++ cho phép truyền mảng theo giá trị qua std::array hoặc struct wrapper:

C++11: std::array (Khuyến nghị)

#include <array>
#include <iostream>

void process(std::array arr) { // Copy toàn bộ mảng
    arr[0] = 999; // Chỉ ảnh hưởng bản copy
}

int main() {
    std::array a = {1,2,3,4,5};
    process(a);
    std::cout << a[0]; // Vẫn là 1
}

C: Struct wrapper (Manual)

struct ArrayWrapper {
    int data[100];
    size_t size;
};

void func(struct ArrayWrapper arr) { // Copy struct (bao gồm mảng)
    // ...
}

C: Truyền con trỏ + size (Cách chuẩn C)

void func(int* arr, size_t n) { // Truyền con trỏ + kích thước
    for (size_t i = 0; i < n; ++i) { ... }
}

int main() {
    int a[10] = {0};
    func(a, 10); // a decay thành int*
}

Tóm tắt

Kết luận: Trong C, "pass array by value" là sai thuật ngữ. Thực tế là pass pointer. Muốn copy mảng → dùng struct wrapper hoặc memcpy thủ công. C++: dùng std::array.

Ngôn ngữTruyền mảng rawTruyền theo giá trị thật
CDecay thành pointer (pass by reference giả)Wrap trong struct
C++Decay thành pointerstd::array<T, N> (copy toàn bộ)