So sánh truyền giá trị và truyền địa chỉ

So sánh truyền giá trị và truyền địa chỉ trong c++

14

Truyền giá trị và truyền địa chỉ trong C++

Trong C++, khi truyền dữ liệu vào hàm, có hai cách quan trọng cần hiểu là truyền giá trịtruyền địa chỉ.

1. Truyền giá trị – Pass by Value

Ví dụ:

void xl(int a)
{
    a = 10;
}
int main()
{
    int a = 2;
    xl(a);
    cout << a;
}

Kết quả:

2

Khi gọi:

xl(a);

C++ sẽ sao chép giá trị của biến a vào biến a bên trong hàm.

main()                 xl()

a = 2  ---- copy ---->  a = 2
                         |
                         ↓
                       a = 10

Hai biến này nằm ở hai vùng nhớ khác nhau.

Vì vậy:

  • a trong hàm có giá trị 10.
  • a trong main() vẫn có giá trị 2.

2. Truyền địa chỉ – Pass by Address

Truyền địa chỉ thường sử dụng con trỏ.

Ví dụ:

void xl(int *a)
{
    *a = 10;
}
int main()
{
    int a = 2;
    xl(&a);
    cout << a;
}

Kết quả:

10

Khi gọi:

xl(&a);

Ta truyền địa chỉ của biến a vào hàm.

main()                 xl()

a = 2
địa chỉ 1000
   |
   |-----------------> a = 1000
                          |
                          ↓
                        *a = 10
                          |
                          ↓
                     ô nhớ 1000 = 10

Do a trong hàm đang trỏ đến chính ô nhớ của biến a trong main(), nên giá trị của biến gốc bị thay đổi.

3. Truyền tham chiếu – Pass by Reference

Ngoài truyền giá trị và truyền địa chỉ, C++ còn có truyền tham chiếu.

void xl(int &a)
{
    a = 10;
}

int main()
{
    int a = 2;
    xl(a);
    cout << a;
}

Kết quả:

10

Có thể hiểu a trong hàm là một tên khác (bí danh) của biến a trong main().

4. So sánh ba cách truyền tham số

Cách truyền Khai báo hàm Cách gọi Có sửa biến gốc?
Truyền giá trị void xl(int a) xl(a) Không
Truyền địa chỉ void xl(int *a) xl(&a)
Truyền tham chiếu void xl(int &a) xl(a)

5. Cách nhớ đơn giản

  • Truyền giá trị: đưa cho hàm một bản sao.
  • Truyền địa chỉ: đưa cho hàm địa chỉ của biến.
  • Truyền tham chiếu: cho hàm một tên khác để truy cập biến gốc.

6. Mối liên hệ với mảng

Ví dụ:

void xl(int a[])
{
    a[0] = 11;
    a[1] = 22;
}

int main()
{
    int a[] = {1, 2};

    xl(a);

    cout << a[0] << endl;
    cout << a[1] << endl;
}

Kết quả:

11
22

Khi truyền mảng vào hàm bằng dạng int a[], C++ xử lý tham số này về bản chất gần giống như một con trỏ đến phần tử đầu tiên của mảng.

Vì vậy, khi hàm thực hiện:

a[0] = 11;
a[1] = 22;

thì các phần tử của mảng gốc cũng bị thay đổi.

7. Kết luận

Có thể ghi nhớ:

int a       → Truyền giá trị → Có bản sao → Không sửa biến gốc

int *a      → Truyền địa chỉ → Truy cập biến gốc → Có thể sửa

int &a      → Truyền tham chiếu → Bí danh biến gốc → Có thể sửa

int a[]     → Mảng → Truyền vào hàm dưới dạng địa chỉ → Có thể sửa phần tử

So sánh truyền giá trị và truyền địa chỉ trong c++