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::arrayarr) { // 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
| Ngôn ngữ | Truyền mảng raw | Truyền theo giá trị thật |
|---|---|---|
| C | Decay thành pointer (pass by reference giả) | Wrap trong struct |
| C++ | Decay thành pointer | std::array<T, N> (copy toàn bộ) |