Phép toán 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 9 trên 63.
Bạn đã học cách truy cập các phần tử trong mảng bằng ký hiệu con trỏ như *(array + i). Giờ đây, bạn sẽ khám phá một kỹ thuật mạnh mẽ hơn nữa: phép toán số học trên con trỏ (pointer arithmetic), cho phép bạn di chuyển con trỏ trong bộ nhớ bằng các phép tăng và giảm đơn giản.
Khi tăng con trỏ bằng ++ hoặc giảm con trỏ bằng --, con trỏ không chỉ di chuyển một byte. Thay vào đó, nó di chuyển một khoảng bằng kích thước của kiểu dữ liệu mà nó trỏ đến. Với con trỏ số nguyên, ptr++ di chuyển tiến lên sizeof(int) byte, đến đúng vị trí của số nguyên tiếp theo trong bộ nhớ.
int numbers[5] = {10, 20, 30, 40, 50};
int *ptr = numbers; // Trỏ đến phần tử đầu tiên (10)
ptr++; // Giờ trỏ đến phần tử thứ hai (20)
ptr++; // Giờ trỏ đến phần tử thứ ba (30)Chính phép tính kích thước tự động này giúp số học con trỏ trở nên mạnh mẽ và tiện lợi. Bạn không cần lo lắng về việc tính số byte, C sẽ xử lý việc định địa chỉ bộ nhớ dựa trên kiểu dữ liệu của con trỏ.
Phép toán con trỏ đặc biệt hữu ích khi duyệt mảng bằng vòng lặp. Thay vì dùng chỉ số mảng, bạn có thể tăng con trỏ để lần lượt đi qua từng phần tử, nhờ đó thường tạo ra code hiệu quả hơn.
Thử thách
DễViết chương trình C minh họa phép toán con trỏ bằng cách dùng thao tác tăng con trỏ để duyệt và xử lý một mảng. Chương trình cần:
- Khai báo một mảng số nguyên tên
datagồm 5 phần tử và khởi tạo mảng bằng các giá trị {12, 24, 36, 48, 60} - Khai báo một con trỏ đến số nguyên tên
ptrvà khởi tạo con trỏ để trỏ đến phần tử đầu tiên của mảng - Dùng vòng lặp for chạy 5 lần để duyệt toàn bộ mảng chỉ bằng phép toán con trỏ
- Bên trong vòng lặp:
- In ra giá trị hiện tại mà
ptrtrỏ đến bằng toán tử giải tham chiếu - In ra địa chỉ bộ nhớ được lưu trong
ptrbằng chỉ định định dạng%p - Tăng con trỏ bằng
ptr++để chuyển đến phần tử tiếp theo
- In ra giá trị hiện tại mà
- Sau vòng lặp, đặt lại
ptrđể trỏ về phần tử đầu tiên của mảng - Dùng phép toán con trỏ để truy cập trực tiếp và in ra phần tử thứ ba (chỉ số 2) bằng
*(ptr + 2) - Dùng phép toán con trỏ để truy cập trực tiếp và in ra phần tử cuối cùng (chỉ số 4) bằng
*(ptr + 4)
Đầu ra của bạn cần hiển thị kết quả theo định dạng sau:
Value: 12, Address: [address]
Value: 24, Address: [address]
Value: 36, Address: [address]
Value: 48, Address: [address]
Value: 60, Address: [address]
Third element: 36
Last element: 60Thử thách này kiểm tra hiểu biết của bạn về cách thao tác tăng con trỏ tự động di chuyển theo kích thước của kiểu dữ liệu và cách dùng phép toán con trỏ để truy cập các phần tử mảng tại những độ lệch cụ thể so với vị trí con trỏ cơ sở.
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) 'data' với các giá trị {12, 24, 36, 48, 60}
// Khai báo con trỏ 'ptr' và khởi tạo để nó trỏ đến phần tử đầu tiên
// Dùng vòng lặp for và phép toán con trỏ để duyệt mảng
// In ra từng giá trị và địa chỉ, rồi tăng con trỏ
// Đặt lại con trỏ và dùng phép toán con trỏ để truy cập các phần tử cụ thể
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