4.1.1 Mảng con trỏ (1)

Phần tử của mảng hoàn toàn có thể là con trỏ. Hãy tưởng tượng nếu chúng ta cần một mảng động. Mảng đó là mảng hai chiều và chúng tôi không biết trước nó có bao nhiêu hàng, bao nhiêu cột.

Chúng ta chỉ biết rằng số cột được lưu trữ trong biến cols và số hàng trong biến rows.

Chúng ta không nên cấp phát mảng theo cách sau:

Nhìn qua thì có vẻ khá hợp lý, nhưng thực ra là sai, bởi vì trình biên dịch hiểu là chúng ta muốn cấp phát rows mảng, mỗi phần tử của mảng lại là một mảng có cols. Và nếu như thế thì cols phải là hằng số biết trước mà trong trường hợp này thì cols là biến chứ không phải hằng số, và kết quả là xảy ra lỗi biên dịch, và.

Vậy chúng ta nên làm gì nếu muốn mảng của chúng ta được cấp phát động và dễ dàng truy cập theo kiểu này ? :

ptrarr [r] [c]

Vâng, chúng ta phải làm như sau:

  • Chúng ta lưu trữ các con trỏ trỏ đầu của mỗi hàng một cách riêng biệt để chúng ta có thể truy cập từng hàng giống như truy cập phần tử bình thường của mảng. Chúng ta sẽ lưu các con trỏ đó vào một mảng và gọi nó là mảng các hàng, mỗi hàng sẽ có số phần từ bằng số cột
  • Mỗi phần tử trong mảng các hàng sẽ là một con trỏ tới một hàng riêng biệt
  • Chúng ta cần thêm một con trỏ trỏ tới mảng các hàng – chúng ta gọi nó là ptrarr

Ý tưởng trên được biểu diễn bằng hình ảnh như sau →

Vậy kiểu dữ liệu của biến ptrarr là gì ?

Chắc chắn nó không phải là một con trỏ đến kiểu int. Vì kết quả của việc dereferencing ptrarr không phải kiểu int mà là một con trỏ đến int. Điều này có nghĩa là kiểu của ptrarr là “một con trỏ tới một con trỏ tới int” tức là “int **”.

Chúng ta có thể viết một khai báo đầy đủ ngay bây giờ →