Phần tử mảng và con trỏ
Thuộc phần Logic và luồng điều khiển trong hành trình C của Coddy. Bài học 8 trên 63.
Giờ đây, khi đã hiểu tên mảng hoạt động như con trỏ thế nào, bạn có thể dùng kiến thức này để truy cập các phần tử trong mảng theo một cách hoàn toàn khác. Thay vì dùng ký hiệu ngoặc vuông quen thuộc như array[i], bạn có thể dùng ký hiệu con trỏ để đạt được kết quả tương tự.
Điểm mấu chốt là array[i] hoàn toàn tương đương với *(array + i). Khi viết array + i, bạn đang yêu cầu C di chuyển về phía trước i vị trí tính từ đầu mảng. Sau đó, toán tử giải tham chiếu * lấy giá trị tại vị trí đó.
int numbers[5] = {10, 20, 30, 40, 50};
// Hai dòng này có tác dụng giống hệt nhau:
printf("%d", numbers[2]); // In ra 30
printf("%d", *(numbers + 2)); // Cũng in ra 30Ký hiệu con trỏ này hoạt động vì C tự động tính địa chỉ bộ nhớ chính xác dựa trên kích thước kiểu dữ liệu. Khi bạn cộng 2 vào con trỏ mảng số nguyên, C tiến thêm 2 × sizeof(int) byte và đến đúng phần tử thứ ba.
Hiểu được sự tương đương này giúp bạn linh hoạt hơn khi làm việc với mảng và chuẩn bị cho bạn các kỹ thuật con trỏ nâng cao hơn mà bạn sẽ gặp khi tiếp tục học C.
Thử thách
DễViết chương trình C minh họa cách truy cập các phần tử mảng bằng ký pháp con trỏ thay vì cách đánh chỉ số mảng thông thường. Chương trình cần:
- Khai báo một mảng số nguyên tên là
valuescó 6 phần tử và khởi tạo mảng với các giá trị {5, 15, 25, 35, 45, 55} - Dùng vòng lặp for để duyệt qua tất cả phần tử của mảng
- Bên trong vòng lặp, dùng ký pháp con trỏ
*(values + i)để truy cập từng phần tử (không dùng ký pháp ngoặc vuông nhưvalues[i]) - In ra từng phần tử bằng cách truy cập qua ký pháp con trỏ
- Sau vòng lặp, minh họa tính tương đương bằng cách in ra phần tử thứ ba (chỉ số 2) theo cả hai cách:
- Trước tiên, dùng ký pháp con trỏ:
*(values + 2) - Sau đó, dùng ký pháp mảng thông thường:
values[2]
- Trước tiên, dùng ký pháp con trỏ:
Đầu ra của bạn cần hiển thị kết quả theo định dạng sau:
Element 0: 5
Element 1: 15
Element 2: 25
Element 3: 35
Element 4: 45
Element 5: 55
Third element via pointer: 25
Third element via array: 25Thử thách này kiểm tra mức độ hiểu của bạn về tính tương đương giữa array[i] và *(array + i), đồng thời minh họa cách số học con trỏ cho phép bạn truy cập các phần tử mảng bằng cách tính toán địa chỉ bộ nhớ thay vì dùng cách đánh chỉ số thông thường.
Tự làm thử
#include <stdio.h>
int main() {
// TODO: Viết code của bạn vào đây
// Khai báo và khởi tạo mảng (array) 'values' gồm 6 phần tử (element)
// Dùng vòng lặp for để in ra từng phần tử bằng ký hiệu con trỏ *(values + i)
// Sau vòng lặp, in ra phần tử thứ ba bằng cả ký hiệu con trỏ và ký hiệu mảng
return 0;
}Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Logic và luồng điều khiển
1Nền tảng về con trỏ
Con trỏ là gì?Khai báo con trỏToán tử lấy địa chỉ (&)Toán tử giải tham chiếu (*)Con trỏ NULLÔn tập: kiến thức cơ bản về con trỏ4Dự án: Công cụ xử lý văn bản đơn giản
Tổng quan dự ánĐếm ký tự2Con trỏ và mảng
Tên mảng dưới dạng con trỏPhần tử mảng và con trỏPhép toán con trỏSo sánh con trỏÔn tập: duyệt mảng bằng con trỏ5Con trỏ và hàm
Truyền theo giá trịTruyền con trỏ vào hàmSửa đổi biến qua con trỏVí dụ kinh điển: hoán đổiTruyền mảng vào hàmÔn tập: đối số con trỏ hàm3Mảng ký tự và chuỗi
Chuỗi dưới dạng mảng charKý tự kết thúc nullNhập chuỗi bằng scanfDùng strlen()Dùng strcpy()Dùng strcat()Dùng strcmp()Ôn tập: các hàm xử lý chuỗi cơ bản6Quản lý bộ nhớ
Bộ nhớ ngăn xếp và bộ nhớ heapCấp phát động với malloc()Dùng sizeof() để cấp phátKiểm tra lỗi cấp phátGiải phóng bộ nhớ với free()Cấp phát với calloc()Ôn tập: Mảng động9Dự án: Nhập thông tin liên hệ đơn giản
Định nghĩa struct ContactHàm tạo liên hệTự luyện tập: Trình biên dịch C online