So sánh con trỏ và mảng năm 2024

Trong bài học này, Lập trình không khó sẽ cùng các bạn đi tìm hiểu mối quan hệ giữa con trỏ và mảng trong ngôn ngữ lập trình C. Bạn sẽ học thêm về một số toán tử của con trỏ, sử dụng các toán tử đó để duyệt mảng. Do đó, bạn sẽ biết thêm 1 cách mới để lặp qua mảng sử dụng con trỏ. Tất nhiên, mục tiêu cao hơn hết là giúp bạn hiểu sâu hơn, biết thêm các kiến thức về con trỏ trong ngôn ngữ C.

Trước khi bạn bắt đầu bài học này, bạn cần chắc chắn mình nắm rõ các kiến thức dưới đây:

  • Mảng trong ngôn ngữ lập trình C
  • Con trỏ trong ngôn ngữ lập trình C

NỘI DUNG BÀI VIẾT

Các phần tử của mảng là các ô nhớ liên tiếp

Nhắc lại khái niệm về mảng: “Mảng là một tập hợp tuần tự các phần tử có cùng kiểu dữ liệu và các phần tử được lưu trữ trong một dãy các ô nhớ liên tục trên bộ nhớ“.

Các bạn đặc biệt lưu ý tới tính chất được lưu trên các ô nhớ liên tục, bây giờ chúng ta sẽ chứng minh tính đúng đắn của nó bằng ví dụ dưới đây:

include

int main(){

// Khai báo mảng có 5 phần tử  
int arr[] = {1, 2, 3, 4, 5};
printf("Dia chi cua mang arr = %d\n", &arr);  
printf("Gia chi cua mang arr = %d\n", arr);  
// Thử in địa chỉ của từng phần tử  
// sizeof (arr): Kích thước của mảng  
// sizeof (int): Kích thước của kiểu int  
for(int i = 0; i < sizeof (arr) / sizeof (int); i++){  
    printf("Dia chi cua arr[%d] = %d\n", i, &arr[i]);  
}
}

Kết quả chạy chương trình trên:

Dia chi cua mang arr = 6487552 Gia chi cua mang arr = 6487552 Dia chi cua arr[0] = 6487552 Dia chi cua arr[1] = 6487556 Dia chi cua arr[2] = 6487560 Dia chi cua arr[3] = 6487564 Dia chi cua arr[4] = 6487568

Nhận xét:

  • Các phần tử liên tiếp có địa chỉ cách nhau 4 giá trị, bởi vì 1 phần tử kiểu int có kích thước 4 bytes (máy tính x64). Nên ta chắc chắn các phần tử mảng được xếp cạnh nhau trong bộ nhớ.
  • Một điều đặc biệt nữa, như mình có nói là khi truyền mảng vào hàm thì mặc định là truyền theo tham chiếu. Và trong ví dụ này bạn thấy đó, địa chỉ của biến mảng chính là địa chỉ của phần tử đầu tiên của mảng. Và giá trị của biến mảng cũng chính là địa chỉ của phần tử đầu tiên của mảng.
  • Như vậy, Dia chi cua mang arr = 6487552 Gia chi cua mang arr = 6487552 Dia chi cua arr[0] = 6487552 Dia chi cua arr[1] = 6487556 Dia chi cua arr[2] = 6487560 Dia chi cua arr[3] = 6487564 Dia chi cua arr[4] = 6487568 0 tương đương Dia chi cua mang arr = 6487552 Gia chi cua mang arr = 6487552 Dia chi cua arr[0] = 6487552 Dia chi cua arr[1] = 6487556 Dia chi cua arr[2] = 6487560 Dia chi cua arr[3] = 6487564 Dia chi cua arr[4] = 6487568 1 và tương đương Dia chi cua mang arr = 6487552 Gia chi cua mang arr = 6487552 Dia chi cua arr[0] = 6487552 Dia chi cua arr[1] = 6487556 Dia chi cua arr[2] = 6487560 Dia chi cua arr[3] = 6487564 Dia chi cua arr[4] = 6487568 2. Điều đó có được là do biến Dia chi cua mang arr = 6487552 Gia chi cua mang arr = 6487552 Dia chi cua arr[0] = 6487552 Dia chi cua arr[1] = 6487556 Dia chi cua arr[2] = 6487560 Dia chi cua arr[3] = 6487564 Dia chi cua arr[4] = 6487568 2 trỏ tới phần tử đầu tiên của mảng.

Toán tử tăng và giảm của con trỏ

Giống như biến thông thường, con trỏ cũng có toán tử tăng và giảm. Nhưng cách toán tử tăng/ giảm trên con trỏ làm việc như nào.

include

int main() {

// Khai báo mảng có 5 phần tử  
int arr[] = {1, 2, 3, 4, 5};  
// Thử in địa chỉ của từng phần tử  
// sizeof (arr): Kích thước của mảng  
// sizeof (int): Kích thước của kiểu int  
for (int i = 0; i < sizeof(arr) / sizeof(int); i++)  
{  
    printf("Dia chi cua arr[%d] = %d\n", i, &arr[i]);  
}
printf("\n___________________________\n");
// Gán con trỏ p cho phần tử đầu tiên của mảng  
int *p = &arr[0];
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);
// Toán tử tăng trên con trỏ  
p++; // hoặc p = p + 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);
// Toán tử tăng trên con trỏ  
p += 2; // hoặc p = p + 2;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);
// Toán tử giảm trên con trỏ  
p--; // hoặc p = p - 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
}

Kết quả chạy:

Dia chi cua arr[0] = 6487536 Dia chi cua arr[1] = 6487540 Dia chi cua arr[2] = 6487544 Dia chi cua arr[3] = 6487548 Dia chi cua arr[4] = 6487552


Gia tri cua con tro p = 6487536 Gia tri cua dia chi ma p dang tro den = 1 Gia tri cua con tro p = 6487540 Gia tri cua dia chi ma p dang tro den = 2 Gia tri cua con tro p = 6487548 Gia tri cua dia chi ma p dang tro den = 4 Gia tri cua con tro p = 6487544 Gia tri cua dia chi ma p dang tro den = 3

Như bạn thấy:

  • Khi dùng toán tử tăng/ giảm trên biến con trỏ, nó sẽ nhảy sang ô nhớ liền kề chứ không phải tăng địa chỉ mà nó đang trỏ lên 1. Do con trỏ Dia chi cua mang arr = 6487552 Gia chi cua mang arr = 6487552 Dia chi cua arr[0] = 6487552 Dia chi cua arr[1] = 6487556 Dia chi cua arr[2] = 6487560 Dia chi cua arr[3] = 6487564 Dia chi cua arr[4] = 6487568 4 là kiểu int nên mỗi bước tăng, giá trị của Dia chi cua mang arr = 6487552 Gia chi cua mang arr = 6487552 Dia chi cua arr[0] = 6487552 Dia chi cua arr[1] = 6487556 Dia chi cua arr[2] = 6487560 Dia chi cua arr[3] = 6487564 Dia chi cua arr[4] = 6487568 4 tăng thêm 4 giá trị. (Lưu ý: giá trị của con trỏ là địa chỉ mà nó đang trỏ tới)
  • Nếu bạn muốn tăng giá trị của địa chỉ nơi con trỏ đang trỏ tới, hãy dùng cách dưới đây:

include

int main() {

// Khai báo mảng có 5 phần tử  
int arr[] = {1, 2, 3, 4, 5};
// Gán con trỏ p cho phần tử đầu tiên của mảng  
int *p = &arr[0];  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Tăng giá trị của địa chỉ mà `p` đang trỏ tới thông qua `p`.  
(*p)+= 5;   
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
} // Gia tri cua dia chi ma p dang tro den = 1 // Gia tri cua dia chi ma p dang tro den = 6

Mối quan hệ giữa con trỏ và mảng trong C

Tới đây chắc hẳn bạn đã hình dung được sự liên hệ giữa con trỏ và mảng, mình sẽ cùng các bạn đi tới các kết luận về con trỏ và mảng nhé.

So sánh con trỏ và mảng năm 2024
Mối quan hệ giữa con trỏ và mảng trong C

Với mảng trong ảnh phía trên, ta có:

  • Dia chi cua mang arr = 6487552 Gia chi cua mang arr = 6487552 Dia chi cua arr[0] = 6487552 Dia chi cua arr[1] = 6487556 Dia chi cua arr[2] = 6487560 Dia chi cua arr[3] = 6487564 Dia chi cua arr[4] = 6487568 7 và Dia chi cua mang arr = 6487552 Gia chi cua mang arr = 6487552 Dia chi cua arr[0] = 6487552 Dia chi cua arr[1] = 6487556 Dia chi cua arr[2] = 6487560 Dia chi cua arr[3] = 6487564 Dia chi cua arr[4] = 6487568 8 có cùng giá trị, và Dia chi cua mang arr = 6487552 Gia chi cua mang arr = 6487552 Dia chi cua arr[0] = 6487552 Dia chi cua arr[1] = 6487556 Dia chi cua arr[2] = 6487560 Dia chi cua arr[3] = 6487564 Dia chi cua arr[4] = 6487568 9 hay

include

int main() {

// Khai báo mảng có 5 phần tử  
int arr[] = {1, 2, 3, 4, 5};  
// Thử in địa chỉ của từng phần tử  
// sizeof (arr): Kích thước của mảng  
// sizeof (int): Kích thước của kiểu int  
for (int i = 0; i < sizeof(arr) / sizeof(int); i++)  
{  
    printf("Dia chi cua arr[%d] = %d\n", i, &arr[i]);  
}  
printf("\n___________________________\n");  
// Gán con trỏ p cho phần tử đầu tiên của mảng  
int *p = &arr[0];  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p++; // hoặc p = p + 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p += 2; // hoặc p = p + 2;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử giảm trên con trỏ  
p--; // hoặc p = p - 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
} 0 là tương đương nhau.

  • include

    int main() {
    // Khai báo mảng có 5 phần tử  
    int arr[] = {1, 2, 3, 4, 5};  
    // Thử in địa chỉ của từng phần tử  
    // sizeof (arr): Kích thước của mảng  
    // sizeof (int): Kích thước của kiểu int  
    for (int i = 0; i < sizeof(arr) / sizeof(int); i++)  
    {  
        printf("Dia chi cua arr[%d] = %d\n", i, &arr[i]);  
    }  
    printf("\n_\n");  
    // Gán con trỏ p cho phần tử đầu tiên của mảng  
    int *p = &arr[0];  
    // Lấy giá trị của con trỏ p  
    printf("Gia tri cua con tro p = %d\n", p);  
    // Lấy giá trị của địa chỉ mà p đang trỏ đến  
    printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
    // Toán tử tăng trên con trỏ  
    p++; // hoặc p = p + 1;  
    // Lấy giá trị của con trỏ p  
    printf("Gia tri cua con tro p = %d\n", p);  
    // Lấy giá trị của địa chỉ mà p đang trỏ đến  
    printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
    // Toán tử tăng trên con trỏ  
    p += 2; // hoặc p = p + 2;  
    // Lấy giá trị của con trỏ p  
    printf("Gia tri cua con tro p = %d\n", p);  
    // Lấy giá trị của địa chỉ mà p đang trỏ đến  
    printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
    // Toán tử giảm trên con trỏ  
    p--; // hoặc p = p - 1;  
    // Lấy giá trị của con trỏ p  
    printf("Gia tri cua con tro p = %d\n", p);  
    // Lấy giá trị của địa chỉ mà p đang trỏ đến  
    printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
    
    } 1 tương đương với

include

int main() {

// Khai báo mảng có 5 phần tử  
int arr[] = {1, 2, 3, 4, 5};  
// Thử in địa chỉ của từng phần tử  
// sizeof (arr): Kích thước của mảng  
// sizeof (int): Kích thước của kiểu int  
for (int i = 0; i < sizeof(arr) / sizeof(int); i++)  
{  
    printf("Dia chi cua arr[%d] = %d\n", i, &arr[i]);  
}  
printf("\n___________________________\n");  
// Gán con trỏ p cho phần tử đầu tiên của mảng  
int *p = &arr[0];  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p++; // hoặc p = p + 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p += 2; // hoặc p = p + 2;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử giảm trên con trỏ  
p--; // hoặc p = p - 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
} 2 và

include

int main() {

// Khai báo mảng có 5 phần tử  
int arr[] = {1, 2, 3, 4, 5};  
// Thử in địa chỉ của từng phần tử  
// sizeof (arr): Kích thước của mảng  
// sizeof (int): Kích thước của kiểu int  
for (int i = 0; i < sizeof(arr) / sizeof(int); i++)  
{  
    printf("Dia chi cua arr[%d] = %d\n", i, &arr[i]);  
}  
printf("\n___________________________\n");  
// Gán con trỏ p cho phần tử đầu tiên của mảng  
int *p = &arr[0];  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p++; // hoặc p = p + 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p += 2; // hoặc p = p + 2;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử giảm trên con trỏ  
p--; // hoặc p = p - 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
} 3 tương đương với

include

int main() {

// Khai báo mảng có 5 phần tử  
int arr[] = {1, 2, 3, 4, 5};  
// Thử in địa chỉ của từng phần tử  
// sizeof (arr): Kích thước của mảng  
// sizeof (int): Kích thước của kiểu int  
for (int i = 0; i < sizeof(arr) / sizeof(int); i++)  
{  
    printf("Dia chi cua arr[%d] = %d\n", i, &arr[i]);  
}  
printf("\n___________________________\n");  
// Gán con trỏ p cho phần tử đầu tiên của mảng  
int *p = &arr[0];  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p++; // hoặc p = p + 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p += 2; // hoặc p = p + 2;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử giảm trên con trỏ  
p--; // hoặc p = p - 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
} 4.

  • include

    int main() {
    // Khai báo mảng có 5 phần tử  
    int arr[] = {1, 2, 3, 4, 5};  
    // Thử in địa chỉ của từng phần tử  
    // sizeof (arr): Kích thước của mảng  
    // sizeof (int): Kích thước của kiểu int  
    for (int i = 0; i < sizeof(arr) / sizeof(int); i++)  
    {  
        printf("Dia chi cua arr[%d] = %d\n", i, &arr[i]);  
    }  
    printf("\n_\n");  
    // Gán con trỏ p cho phần tử đầu tiên của mảng  
    int *p = &arr[0];  
    // Lấy giá trị của con trỏ p  
    printf("Gia tri cua con tro p = %d\n", p);  
    // Lấy giá trị của địa chỉ mà p đang trỏ đến  
    printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
    // Toán tử tăng trên con trỏ  
    p++; // hoặc p = p + 1;  
    // Lấy giá trị của con trỏ p  
    printf("Gia tri cua con tro p = %d\n", p);  
    // Lấy giá trị của địa chỉ mà p đang trỏ đến  
    printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
    // Toán tử tăng trên con trỏ  
    p += 2; // hoặc p = p + 2;  
    // Lấy giá trị của con trỏ p  
    printf("Gia tri cua con tro p = %d\n", p);  
    // Lấy giá trị của địa chỉ mà p đang trỏ đến  
    printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
    // Toán tử giảm trên con trỏ  
    p--; // hoặc p = p - 1;  
    // Lấy giá trị của con trỏ p  
    printf("Gia tri cua con tro p = %d\n", p);  
    // Lấy giá trị của địa chỉ mà p đang trỏ đến  
    printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
    
    } 5 tương đương với

include

int main() {

// Khai báo mảng có 5 phần tử  
int arr[] = {1, 2, 3, 4, 5};  
// Thử in địa chỉ của từng phần tử  
// sizeof (arr): Kích thước của mảng  
// sizeof (int): Kích thước của kiểu int  
for (int i = 0; i < sizeof(arr) / sizeof(int); i++)  
{  
    printf("Dia chi cua arr[%d] = %d\n", i, &arr[i]);  
}  
printf("\n___________________________\n");  
// Gán con trỏ p cho phần tử đầu tiên của mảng  
int *p = &arr[0];  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p++; // hoặc p = p + 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p += 2; // hoặc p = p + 2;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử giảm trên con trỏ  
p--; // hoặc p = p - 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
} 6 và

include

int main() {

// Khai báo mảng có 5 phần tử  
int arr[] = {1, 2, 3, 4, 5};  
// Thử in địa chỉ của từng phần tử  
// sizeof (arr): Kích thước của mảng  
// sizeof (int): Kích thước của kiểu int  
for (int i = 0; i < sizeof(arr) / sizeof(int); i++)  
{  
    printf("Dia chi cua arr[%d] = %d\n", i, &arr[i]);  
}  
printf("\n___________________________\n");  
// Gán con trỏ p cho phần tử đầu tiên của mảng  
int *p = &arr[0];  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p++; // hoặc p = p + 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p += 2; // hoặc p = p + 2;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử giảm trên con trỏ  
p--; // hoặc p = p - 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
} 7 tương đương với

include

int main() {

// Khai báo mảng có 5 phần tử  
int arr[] = {1, 2, 3, 4, 5};  
// Thử in địa chỉ của từng phần tử  
// sizeof (arr): Kích thước của mảng  
// sizeof (int): Kích thước của kiểu int  
for (int i = 0; i < sizeof(arr) / sizeof(int); i++)  
{  
    printf("Dia chi cua arr[%d] = %d\n", i, &arr[i]);  
}  
printf("\n___________________________\n");  
// Gán con trỏ p cho phần tử đầu tiên của mảng  
int *p = &arr[0];  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p++; // hoặc p = p + 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p += 2; // hoặc p = p + 2;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử giảm trên con trỏ  
p--; // hoặc p = p - 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
} 8.

  • Tóm lại,

include

int main() {

// Khai báo mảng có 5 phần tử  
int arr[] = {1, 2, 3, 4, 5};  
// Thử in địa chỉ của từng phần tử  
// sizeof (arr): Kích thước của mảng  
// sizeof (int): Kích thước của kiểu int  
for (int i = 0; i < sizeof(arr) / sizeof(int); i++)  
{  
    printf("Dia chi cua arr[%d] = %d\n", i, &arr[i]);  
}  
printf("\n___________________________\n");  
// Gán con trỏ p cho phần tử đầu tiên của mảng  
int *p = &arr[0];  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p++; // hoặc p = p + 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử tăng trên con trỏ  
p += 2; // hoặc p = p + 2;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
// Toán tử giảm trên con trỏ  
p--; // hoặc p = p - 1;  
// Lấy giá trị của con trỏ p  
printf("Gia tri cua con tro p = %d\n", p);  
// Lấy giá trị của địa chỉ mà p đang trỏ đến  
printf("Gia tri cua dia chi ma p dang tro den = %d\n", *p);  
} 9 tương đương với Dia chi cua arr[0] = 6487536 Dia chi cua arr[1] = 6487540 Dia chi cua arr[2] = 6487544 Dia chi cua arr[3] = 6487548 Dia chi cua arr[4] = 6487552


Gia tri cua con tro p = 6487536 Gia tri cua dia chi ma p dang tro den = 1 Gia tri cua con tro p = 6487540 Gia tri cua dia chi ma p dang tro den = 2 Gia tri cua con tro p = 6487548 Gia tri cua dia chi ma p dang tro den = 4 Gia tri cua con tro p = 6487544 Gia tri cua dia chi ma p dang tro den = 3 0 và Dia chi cua arr[0] = 6487536 Dia chi cua arr[1] = 6487540 Dia chi cua arr[2] = 6487544 Dia chi cua arr[3] = 6487548 Dia chi cua arr[4] = 6487552


Gia tri cua con tro p = 6487536 Gia tri cua dia chi ma p dang tro den = 1 Gia tri cua con tro p = 6487540 Gia tri cua dia chi ma p dang tro den = 2 Gia tri cua con tro p = 6487548 Gia tri cua dia chi ma p dang tro den = 4 Gia tri cua con tro p = 6487544 Gia tri cua dia chi ma p dang tro den = 3 1 tương đương với Dia chi cua arr[0] = 6487536 Dia chi cua arr[1] = 6487540 Dia chi cua arr[2] = 6487544 Dia chi cua arr[3] = 6487548 Dia chi cua arr[4] = 6487552


Gia tri cua con tro p = 6487536 Gia tri cua dia chi ma p dang tro den = 1 Gia tri cua con tro p = 6487540 Gia tri cua dia chi ma p dang tro den = 2 Gia tri cua con tro p = 6487548 Gia tri cua dia chi ma p dang tro den = 4 Gia tri cua con tro p = 6487544 Gia tri cua dia chi ma p dang tro den = 3 2.

Hãy thử nhập xuất mảng theo cách mới nào:

// Ví dụ mối quan hệ giữa con trỏ và mảng - Lập Trình Không Khó

include

define MAX_SIZE 100

int main() {

int arr[MAX_SIZE];  
int n;  
do  
{  
    printf("Nhap so luong phan tu: ");  
    scanf("%d", &n);  
} while (n < 1);
// Nhập mảng  
for (int i = 0; i < n; i++)  
{  
    printf("Nhap a[%d] = ", i);  
    scanf("%d", (arr + i));  
}
// Xuất mảng  
for (int i = 0; i < n; i++)  
{  
    printf("\nGia tri a[%d] = %d", i, *(arr + i));  
}  
}

Kết quả chạy:

Nhap so luong phan tu: 5 Nhap a[0] = 1 Nhap a[1] = 2 Nhap a[2] = 3 Nhap a[3] = 4 Nhap a[4] = 5 Gia tri a[0] = 1 Gia tri a[1] = 2 Gia tri a[2] = 3 Gia tri a[3] = 4 Gia tri a[4] = 5

Lưu ý: Trong hầu hết trường hợp, tên biến mảng được chuyển đổi thành 1 con trỏ. Do đó, bạn có thể sử dụng con trỏ để truy cập các phần tử của mảng. Tuy nhiên, bạn cần lưu ý con trỏ và mảng không phải là một nhé. Có 1 số trường hợp ngoại lệ, bạn xem chi tiết tại: When does array name doesn’t decay into a pointer?

Ví dụ mối quan hệ giữa con trỏ và mảng

Bạn cũng có thể sử dụng một biến con trỏ khác để duyệt mảng, xem ví dụ bài tập tính tổng các phần tử trong mảng 1 chiều sử dụng con trỏ dưới đây:

// Ví dụ mối quan hệ giữa con trỏ và mảng - Lập Trình Không Khó

include

define MAX_SIZE 100

int main() {

int arr[MAX_SIZE];  
int n;  
do  
{  
    printf("Nhap so luong phan tu: ");  
    scanf("%d", &n);  
} while (n < 1);
int *p = &arr[0];  
// Nhập mảng  
for (int i = 0; i < n; i++)  
{  
    printf("Nhap a[%d] = ", i);  
    scanf("%d", (p + i));  
}
// Xuất mảng  
for (int i = 0; i < n; i++)  
{  
    printf("\nGia tri a[%d] = %d", i, *(p + i));  
}
// Tính tổng sử dụng biến lặp là con trỏ  
// Khởi tạo con trỏ i trỏ tới phần tử đầu tiên của mảng  
// Ta sẽ dừng nếu giá trị của i vượt quá địa chỉ của phần tử cuối cùng  
// i++: tăng i lên 1 đơn vị, tức là cho nó trỏ tới phần tử tiếp theo  
int sum = 0;  
for(int *i = &arr[0]; i <= &arr[n-1]; i++){  
    // Lấy giá trị của phần tử hiện tại bằng toán tử `*`  
    sum += *i;  
}  
printf("\nSum = %d", sum);  
}

Kết quả chạy chương trình:

Nhap so luong phan tu: 5 Nhap a[0] = 1 Nhap a[1] = 2 Nhap a[2] = 3 Nhap a[3] = 4 Nhap a[4] = 5 Gia tri a[0] = 1 Gia tri a[1] = 2 Gia tri a[2] = 3 Gia tri a[3] = 4 Gia tri a[4] = 5 Sum = 15

Bài viết này mình đã cùng bạn đi làm rõ mối liên hệ giữa con trỏ và mảng trong C. Giờ đây bạn có thêm 1 cách để duyệt mảng cực ngầu. Hơn hết, bạn hiểu nhiều hơn về mối quan hệ giữa con trỏ và mảng, ứng dụng của con trỏ trong mảng. Ở các bài sau chúng ta sẽ tiếp tục khám phá về con trỏ nhé.