🌱 Khác nhau giữa char s[] và char *s ?
Trong C có 2 cách mà chúng ta hay sử dụng để khai báo một chuỗi, đó là:
- Khai báo một mảng các ký tự: char s[]
- Khai báo kiểu con trỏ: char *s
Để dễ so sánh chúng ta sẽ nhìn vào 2 cách khai báo sau:
char a[] = "String"; // Array
char *p = "String"; // Pointer
Dễ thấy 2 cách khai báo trên khác nhau ở chỗ a là một mảng - array, trong khi p là một con trỏ - pointer. Để truy xuất đến phần tử trong cả 2 chuỗi , chúng ta có thể truy xuất bằng index. Ví dụ:
a[0] = p[0] = 'S'
👉 Khác nhau về Storage (Lưu trữ trong bộ nhớ)
Các bạn có thể xem hình sau để biết vị trí bộ nhớ khác nhau khi khai báo 2 kiểu này:
Dễ thấy kiểu mảng - array a được cấp phát một vùng nhớ (7 ô nhớ cho chuỗi "String") trên stack (RAM) khi khai báo.
Trong khi đó kiểu pointer p cũng được cấp phát một ô nhớ trên stack (RAM), tuy nhiên, chuỗi "String" trong trường hợp này sẽ được cấp phát một vùng nhớ trên read only section (FLASH).
⇨ Chính vì vị trí cấp phát trên, chúng ta có thể rút ra một điểm quan trọng:
- char *p sẽ chiếm vùng nhớ trên FLASH, và giá trị của chuỗi này sẽ KHÔNG THỂ THAY ĐỔI khi run.
- char a[] sẽ chiếm vùng nhớ trên RAM, nên giá trị của chuỗi CÓ THỂ THAY ĐỔI khi run.
👉 Khác nhau về kích thước
Đối với kiểu Array, kích thước của a phụ thuộc vào độ dài của chuỗi, với chuỗi "String" thì sizeof (a) = 7 (Nó sẽ tính cả ký tự kết thúc chuỗi \0).
Đối với kiểu Pointer, kích thước của p sẽ phụ thuộc vào kiến trúc của Vi xử lý, và sẽ không thay đổi theo độ dài chuỗi. Ví dụ máy tính mình là kiến trúc 64-bit, sizeof (p) = 8 (luôn cố định).
Trong khi chạy với Vi điều khiển STM32, kiến trúc 32-bit, sizeof (p) = 4.