các thành phần cơ bản của ngôn ngữ lập trình

Giải mã các thành phần cơ bản của ngôn ngữ lập trình

Mục lục

Ngôn ngữ lập trình là kiến thức bắt buộc của mỗi người học lập trình phải nắm vững. Vậy ngôn ngữ lập trình là gì? Ngôn ngữ lập trình gồm mấy phần cơ bản? Bài viết này sẽ tập trung giải thích cho hai câu hỏi trên.

Lưu ý: Bài viết sẽ có kha khá thuật ngữ và kiến thức chuyên môn. Vì vậy bạn cần lên dây cốt để sẵn sàng đọc đôi dòng chia sẻ dưới đây nhé.

Ngôn ngữ lập trình là gì?

Tương tự các ngôn ngữ khác trên thế giới như ngôn ngữ Anh, ngôn ngữ Việt, ngôn ngữ Tây Ban Nha,…Ngôn ngữ được sinh ra để giao tiếp, trao đổi thông tin với nhau. Nếu các ngôn ngữ trên được dùng để loài người trao đổi để hiểu nhau. Thì để giúp con người và máy tính hiểu nhau thì cũng sẽ có riêng một loại ngôn ngữ. Người ta gọi chung đó là ngôn ngữ lập trình. 

Như trong xã hội loài người sẽ phân chia ra ngôn ngữ Việt, ngôn ngữ Trung, ngôn ngữ Hàn,..Trong ngôn ngữ lập trình cũng phân chia ra như ngôn ngữ lập trình Pascal, C, Java, Python,…

Hay có thể định nghĩa thuật ngữ này như sau. Ngôn ngữ lập trình là tập hợp các ký hiệu được chuẩn hóa theo quy tắc nhất định để viết các chương trình. Nó được dùng trong lập trình máy tính để thực hiện các thuật toán. Sao cho, cả con người và các thiết bị điện tử đều “hiểu” được chương trình làm việc mà lập trình viên mô tả trong phần mềm đó.

Các thành phần cơ bản của ngôn ngữ lập trình

Tương tự như các ngôn ngữ giao tiếp của con người. Ngôn ngữ lập trình cũng gồm một số thành phần tương tự như bảng chữ cái, cú pháp, ngữ pháp,…

 Bảng chữ cái

Bảng chữ cái là tập các kí tự được dùng để viết chương trình. Không được phép dùng bất kì kí tự nào ngoài các kí tự quy định trong bảng chữ cái. Trong ngôn ngữ lập trình Pascal bảng chữ cái bao gồm:

  • 26 chữ cái thường: a, b, c, …, z
  • 26 chữ cái in hoa: A, B, C, …, Z
  • 10 chữ số thập phân: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
  • Các kí tự đặc biệt…

Cú pháp

Giống như các ngôn ngữ thông thường, ngôn ngữ lập trình cũng có cú pháp. Trong đó, Cú pháp của ngôn ngữ (lập trình) là một tập hợp các quy tắc để viết chương trình. Cho ta biết cách viết một chương trình hợp lệ.

Cú pháp (gồm tập hợp các quy tắc) được thể hiện bằng cách sử dụng một ký hiệu chính thức.  Ký hiệu chính thức phổ biến nhất cho cú pháp là dạng Backus-Naur mở rộng (EBNF). Ví dụ: trong C, cú pháp của câu lệnh if được đưa ra bởi quy tắc: 

if-statement :: = if ( expression ) statement [else statement

tên in nghiêng đại diện cho các phạm trù cú pháp, trong khi tên và ký hiệu in đậm đại diện cho các ký tự thực tế phải xuất hiện trong chương trình. Mỗi quy tắc chứa ký hiệu “:: =” có nghĩa là “bao gồm”. Nhiều ký hiệu khác được sử dụng để làm cho các quy tắc ngắn gọn hơn: 

[] Tùy chọn {} Không hoặc nhiều lần lặp lại | Hoặc 

Vì vậy, mệnh đề else của một câu lệnh if là tùy chọn. Việc sử dụng dấu ngoặc nhọn được thể hiện bằng quy tắc (đơn giản hóa) cho việc khai báo danh sách các biến: 

biến-khai báo :: = định danh kiểu-đặc tả {, định danh}

Điều này được đọc: một khai báo biến bao gồm một mã định danh kiểu, theo sau là một mã định danh (tên biến), theo sau là một chuỗi các mã định danh trước dấu phẩy và kết thúc bằng dấu chấm phẩy. 

Các quy tắc cú pháp sẽ dễ học hơn nếu chúng được cung cấp dưới dạng sơ đồ cú pháp. Hình tròn hoặc hình bầu dục biểu thị các ký tự thực tế, trong khi hình chữ nhật biểu thị các danh mục cú pháp có sơ đồ riêng. Một chuỗi các ký hiệu được xây dựng bằng cách truy tìm một đường dẫn trong sơ đồ là một chương trình hợp lệ (về mặt cú pháp).

Trong khi nhiều lập trình viên có niềm đam mê với cú pháp của một ngôn ngữ cụ thể, khía cạnh này của một ngôn ngữ có lẽ là ít quan trọng nhất. Nó rất dễ học và phát triển sự quen thuộc với bất kỳ cú pháp hợp lý nào; hơn nữa, các lỗi về cú pháp được trình biên dịch bắt và hiếm khi gây ra sự cố với một chương trình đang làm việc. Chúng ta có thể hạn chế lưu ý một số lỗi có thể xảy ra với cú pháp gây ra lỗi thời gian chạy:

  • Hãy cẩn thận với các giới hạn về tầm quan trọng của độ dài của số nhận dạng. Nếu chỉ 10 ký tự đầu tiên là quan trọng, thì giá trị chiến thắng hiện tại và chiều rộng hiện tại sẽ đại diện cho cùng một số nhận dạng.
  • Nhiều ngôn ngữ không phân biệt chữ hoa chữ thường, nghĩa là, COUNT và count đại diện cho cùng một tên.

C phân biệt chữ hoa chữ thường, do đó các chuỗi biểu thị hai số nhận dạng riêng biệt. Trong các ngôn ngữ phân biệt chữ hoa chữ thường, một dự án nên thiết lập các quy ước rõ ràng về việc sử dụng trường hợp để các lỗi đánh máy vô tình không gây ra lỗi. Ví dụ, một quy ước trong C yêu cầu mọi thứ phải ở dạng chữ thường, ngoại trừ các tên hằng đã xác định, tất cả đều ở dạng chữ hoa.

  • Có hai dạng chú thích: chú thích Fortran, Ada và C++ bắt đầu bằng ký hiệu (C, – -, và //, tương ứng) và kéo dài đến cuối dòng. Trong khi chú thích C1 và Pascal đều bắt đầu – và các ký hiệu cuối: / *. . . * / trong C, và (*… *) hoặc f. . . g trong Pascal. 

Hình thức thứ hai thuận tiện cho việc “đưa ra bình luận” mã chưa sử dụng có thể đã được chèn vào để kiểm tra, nhưng có thể bỏ qua ký hiệu kết thúc khiến một chuỗi các câu lệnh bị bỏ qua:

/ *a = b + c;/ *. . . * /Nhận xét nên kết thúc tại đâyTuyên bố sẽ bị bỏ quaNhận xét kết thúc tại đâyC
  • Hãy cẩn thận với các ký hiệu tương tự nhưng khác biệt. Nếu bạn đã từng học toán, bạn sẽ ngạc nhiên khi ký hiệu quen thuộc “=” được sử dụng cho toán tử gán trong C và Fortran, trong khi các ký hiệu mới “==” trong C và “.eq”. trong Fortran được sử dụng cho toán tử bình đẳng quen thuộc. Xu hướng viết:

if (a = b) … C

phổ biến đến mức nhiều trình biên dịch sẽ đưa ra cảnh báo mặc dù câu lệnh có ý nghĩa hợp lệ.

  • Hầu hết các ngôn ngữ yêu cầu các từ trong chương trình phải được phân tách bằng một hoặc nhiều khoảng trắng (hoặc các ký tự khoảng trắng khác như tab). Trong khi ở Fortran, khoảng trắng sẽ bị bỏ qua. Lấy vị dụ câu lệnh sau, chỉ định “vòng lặp cho đến khi nhãn 10 là chỉ số tôi đếm từ 1 đến 100”:

do 10 i = 1, 100

Nếu dấu phẩy vô tình bị thay thế bằng dấu chấm, câu lệnh sẽ trở thành câu lệnh gán hợp lệ, gán 1.100 cho biến có tên có được bằng cách ghép tất cả các ký tự trước dấu “=”:

do10i = 1.100
Lỗi này được báo cáo là đã khiến tên lửa phát nổ khi phóng vào không gian!

Ngữ nghĩa

Ngữ nghĩa là ý nghĩa của một biểu thức chương trình trong một ngôn ngữ lập trình.

Trong khi cú pháp của các ngôn ngữ được hiểu rất rõ, thì ngữ nghĩa lại khó hơn nhiều. 

Ngữ nghĩa xác định ý nghĩa thao tác cần phải thực hiên , ứng với tổ hợp kí tự dựa vào ngữ cảnh của nó

  • Cú pháp cho biết cách viết một chương trình hợp lệ , còn ngữ nghĩa xác định ý nghĩa của các tổ hợp kí tự trong chương trình.
  • Lỗi cú pháp được chương trình dịch phát hiện và thông báo cho người lập chương trình biết , chỉ có các chương trình không còn lỗi cú pháp mới có thể được dịch sang ngôn ngữ máy.
  • Lỗi ngữ nghĩa chỉ được phát hiện khi thực hiện chương trình trên dữ liệu cụ thể

Ví dụ như khi lập trình giải phương trình bậc 2, chúng ta viết sai công thức tính toán, việc khai báo cũng thông báo tất cả các cú pháp đều đúng, chương trình được dịch và chạy tốt nhưng kết quả tính toán lại không chính xác, điều đó chứng tỏ đã có sự sai sót về mặt ngữ nghĩa. 

Lỗi ngữ nghĩa chỉ được phát hiện khi thực hiện trên dữ liệu cụ thể . 

Dữ liệu

Khi lần đầu tiên học một ngôn ngữ lập trình, người ta có xu hướng tập trung vào các hành động: câu lệnh hoặc lệnh. Chỉ khi các câu lệnh của ngôn ngữ đã được nghiên cứu và thực hiện, chúng ta mới chuyển sang nghiên cứu sự hỗ trợ mà ngôn ngữ đó cung cấp cho việc cấu trúc dữ liệu. 

Trong quan điểm hiện đại của lập trình như lập trình hướng đối tượng. Các câu lệnh được xem như thao tác với dữ liệu được sử dụng để biểu diễn một số đối tượng. Vì vậy, bạn nên nghiên cứu các khía cạnh cấu trúc dữ liệu của một ngôn ngữ trước hết.

Câu lệnh gán

Điều đáng ngạc nhiên là các ngôn ngữ lập trình thông thường chỉ có một câu lệnh thực sự làm được bất cứ điều gì: câu lệnh gán. Tất cả các câu lệnh khác như câu lệnh if và lệnh gọi thủ tục chỉ tồn tại để điều khiển trình tự thực hiện các câu lệnh gán. Thật không may, rất khó để cung cấp một ý nghĩa chính thức cho câu lệnh gán (trái ngược với việc mô tả những gì nó làm khi được thực thi); trong thực tế, bạn chưa bao giờ gặp bất cứ điều gì tương tự khi bạn học toán ở trường trung học và đại học. Những gì bạn đã nghiên cứu là các phương trình:

ax2 + bx + c = 0 Z sinxdx = ¡cosx

Bạn đã biến đổi các phương trình, bạn giải chúng và bạn đánh giá chúng. Bạn chưa bao giờ sửa đổi chúng:

nếu x đại diện cho một số trong một phần của phương trình, thì nó đại diện cho cùng một số trong phần còn lại của phương trình.

Câu lệnh gán thấp thực sự khá phức tạp, thực hiện ba nhiệm vụ riêng biệt:

1. Tính giá trị của biểu thức ở phía bên phải của câu lệnh.

2. Tính toán biểu thức ở phía bên trái của câu lệnh; biểu thức phải đánh giá

địa chỉ của một ô nhớ.

3. Sao chép giá trị thu được ở bước (1) vào các ô nhớ bắt đầu bằng địa chỉ thu được ở

bước (2).

Như vậy câu lệnh gán:

a (i + 1) = b + c;

mặc dù bề ngoài của nó giống với một phương trình xác định một phép tính phức tạp.

Các câu lệnh kiểm soát

Các câu lệnh gán thường được thực hiện theo trình tự mà chúng được viết. Các câu lệnh điều khiển được sử dụng để sửa đổi thứ tự thực hiện. Các chương trình hợp ngữ sử dụng các bước nhảy tùy ý từ địa chỉ lệnh này sang địa chỉ lệnh khác. Tương tự, một ngôn ngữ lập trình có thể bao gồm một câu lệnh chuyển đến một nhãn trên một câu lệnh tùy ý. Các chương trình sử dụng bước nhảy tùy ý rất khó đọc và do đó cần sửa đổi và duy trì.

Lập trình có cấu trúc là tên được đặt cho kiểu lập trình hạn chế việc sử dụng các câu lệnh điều khiển đối với những câu lệnh mang lại các chương trình có cấu trúc tốt, dễ đọc và dễ hiểu.

Có hai loại câu lệnh điều khiển có cấu trúc tốt:

  • Câu lệnh lựa chọn chọn một phương án thay thế từ hai hoặc nhiều trình tự thực thi có thể có:

câu lệnh if và câu lệnh case- hoặc switch-.

  • Các câu lệnh lặp thực hiện lặp đi lặp lại một chuỗi các câu lệnh: câu lệnh for và câu lệnh cho phép.

Hiểu rõ về các câu lệnh vòng lặp là đặc biệt quan trọng vì hai lý do: (1) phần lớn thời gian thực thi (hiển nhiên) sẽ được dành cho các câu lệnh vòng lặp và (2) nhiều lỗi do mã hóa sai ở đầu hoặc cuối vòng lặp. 

Chương trình con

Chương trình con là một đơn vị bao gồm các khai báo dữ liệu và các câu lệnh thực thi có thể được gọi (gọi) lặp lại từ các phần khác nhau của chương trình. Chương trình con (được gọi là thủ tục, hàm, chương trình con hoặc phương thức) ban đầu được sử dụng chỉ để cho phép tái sử dụng một đoạn chương trình. 

Quan điểm hiện đại hơn cho rằng chương trình con là yếu tố thiết yếu của cấu trúc chương trình và mọi phân đoạn chương trình thực hiện một số nhiệm vụ có thể xác định được nên được đặt trong một chương trình con riêng biệt.

Khi một chương trình con được gọi, nó được truyền vào một chuỗi các giá trị được gọi là tham số. Các tham số được sử dụng để sửa đổi mỗi lần thực thi chương trình con, để gửi dữ liệu đến chương trình con và nhận kết quả của một phép tính. Các cơ chế truyền tham số rất khác nhau từ ngôn ngữ này sang ngôn ngữ khác, và các lập trình viên phải hiểu đầy đủ ảnh hưởng của chúng đến độ tin cậy và hiệu quả của một chương trình.

Mô-đun

Thông thường một chương trình con nên được giới hạn trong 40 hoặc 50 dòng, bởi vì một lập trình viên không thể dễ dàng đọc và hiểu các đoạn mã lớn hơn. Hầu hết những chương trình nào lớn hơn 1600-2500 dòng đều khó hiểu. Vì các chương trình hữu ích có thể có hàng chục nghìn dòng, và các hệ thống hàng trăm nghìn dòng không phải là hiếm, nên rõ ràng là cần có các cấu trúc bổ sung để xây dựng các hệ thống lớn.

Các ngôn ngữ lập trình hiện đại chứa một phương pháp cấu trúc bổ sung để đóng gói dữ liệu và chương trình con trong các thực thể lớn hơn được gọi là mô-đun. Ưu điểm của các mô-đun đó là các giao diện giữa các mô-đun có thể được kiểm tra trong quá trình biên dịch để tránh sai sót và hiểu nhầm. Hơn nữa, các câu lệnh thực thi thực tế và hầu hết dữ liệu của một mô-đun, có thể bị ẩn để không thể sửa đổi hoặc sử dụng chúng trừ khi được chỉ định bởi giao diện.

Có hai khó khăn khi sử dụng các mô-đun:

  • Cần có một môi trường phát triển chương trình mạnh mẽ để theo dõi các mô-đun và kiểm tra các giao diện.
  • Mô-đun hóa khuyến khích việc sử dụng nhiều chương trình con nhỏ với chi phí thời gian chạy tương ứng của lệnh gọi chương trình con.

Cả hai điều này bây giờ không phải là vấn đề. Hiện nay với máy tính cá nhân trung bình là quá đủ để chạy môi trường cho C++ hoặc Ada.

Tạm kết

Bài viết chia sẻ về các thành phần cơ bản của ngôn ngữ lập trình khá dài và cũng chứa nhiều kiến thức chuyên môn. Vì vậy với người hoàn toàn mới tìm hiểu lập trình hẳn sẽ khó hiểu khi đọc bài. Tuy nhiên nếu bạn thấy nó khó hiểu cũng đừng vội nản nhé. Sau một thời gian cứ đọc thêm và quan trọng là thực hành với các ngôn ngữ lập trình bạn sẽ hiểu hơn. 

Để hiểu rõ một vấn đề là một quá trình đọc và thực hành, nghiệm lại và cứ xoay vòng liên tục như vậy. 

Leave a Comment

Your email address will not be published. Required fields are marked *