Đố vui: Vì sao các lập trình viên lại thích bắt đầu phép đếm từ 0 chứ không phải là 1?

    Liam,  

    Đi 0 bước, đi 1 bước, đi 2 bước...

    Nếu là coder có quan tâm đến meme thì bạn chắc hẳn đã ít nhất một lần gặp những mẩu chuyện vui vui nói về "start at 1" là... sai. Những mẩu comic này khẳng định một điều rất đúng, rằng nếu bạn là lập trình viên thì cách đếm của bạn luôn bắt đầu từ 0 chứ không phải là từ con số 1.

    Nhưng lý do là tại sao? Có một số lý do trực quan có thể nghĩ đến, trong đó câu trả lời trong thread thắc mắc trên diễn đàn Reddit ví von cách đánh thứ tự trong lập trình giống với cách con người đếm tuổi: từ 0 tuổi rồi mới đến 1, 2, 3, 4 tuổi v...v... 

    Một câu trả lời hay, nhưng vẫn chưa đúng.

    Đố vui: Vì sao các lập trình viên lại thích bắt đầu phép đếm từ 0 chứ không phải là 1? - Ảnh 1.

    "Ngày sinh nhật đầu tiên thật ra là ngày sinh nhật thứ 2 ấy chứ"?

    Đầu tiên, ai cũng biết rằng nhiều ngôn ngữ sử dụng số 0 để chỉ biến số đầu tiên trong một array (mảng, nôm na là một chuỗi các biến số, các giá trị hoặc các "vật thể" số). Cách đánh số này được rất nhiều ngôn ngữ hiện đại thừa hưởng từ C, và trước đó được C thừa hưởng từ B và BCPL.

    Trong thời đại của các ngôn ngữ cũ kỹ này, bộ nhớ rất có hạn, và lập trình viên cũng phải can thiệp rất nhiều đến cơ chế quản lý. Để khai báo một mảng, bạn phải "đăng ký" một vài ô nhớ liền nhau để lưu trữ toàn bộ các biến số trong array. Ví dụ, nếu array của bạn có 5 biến số thì trên RAM, chúng được lưu vào 5 "ô nhớ" tuần tự nhau.

    Hãy giả sử rằng 5 ô nhớ của chúng ta bắt đầu từ địa chỉ số 1001 chẳng hạn. Trong các ngôn ngữ hướng đối tượng, một biến array sẽ trỏ tới địa chỉ bắt đầu các ô nhớ của mình.

    Đố vui: Vì sao các lập trình viên lại thích bắt đầu phép đếm từ 0 chứ không phải là 1? - Ảnh 2.

    Câu chuyện đùa thường nhật của các lập trình viên: Khi đếm, phải bắt đầu từ 0.

    Đây chính là điểm mấu chốt của vấn đề: để tìm đến biến số đầu tiên lưu trong array, hệ thống cũng sẽ tìm đến địa chỉ đã được khai báo. Tức là 1001. Để tìm đến biến số thứ hai lưu trong, hệ thống sẽ tìm đến ô nhớ ngay cận kề, tức là tìm đến địa chỉ 1001 1. Để tìm đến biến số thứ ba, địa chỉ là 1001 2.

    Con số 2 trong cách gọi "a[2]" thực chất là nói với hệ thống: từ địa chỉ bắt đầu, hãy đi 2 bước để tìm ra biến số thứ 3 trong array. "2 bước" ở đây là từ 1001 đi đến 1002, rồi từ 1002 đi đến 1003.

    Sau này, khi sức mạnh tính toán gia tăng và các ngôn ngữ cũng trở nên mềm dẻo hơn (để đỡ gây khó cho lập trình viên), array cũng ít được sử dụng hơn. Trong Java và C# chẳng hạn, sử dụng kiểu ArrayList cho phép mở rộng kích cỡ mảng bất cứ khi nào cần. Chúng không bị ràng buộc bởi vị trí của biến số trên thanh nhớ và thực chất là cũng không lưu biến theo kiểu "liền mạch" như array.

    Cũng có những ngôn ngữ đã chuyển sang dùng "1" làm điểm bắt đầu cho array. Nhưng trong phần lớn các trường hợp, hiện tại không thể thay đổi quá khứ. Cách đếm bắt đầu từ 0 của lập trình viên đã bắt nguồn từ những ngôn ngữ nhập môn, "thấm" vào những ngôn ngữ cực kỳ phổ biến như Java hay Python, và có lẽ sẽ mãi mãi áp dụng. Giờ đây, khi bắt đầu một ngôn ngữ mới, các nhà thiết kế vẫn thường sẽ chọn số 0 làm điểm khởi đầu.

    Tags:
    Tin cùng chuyên mục
    Xem theo ngày

    NỔI BẬT TRANG CHỦ