Các Tiêu Chuẩn Lập Trình C++ (dịch từ tiếng Anh)

Xin chào đại gia đình DNH! Hôm nay mình xin phép post bài đầu tiên. Thi thoảng khi tự mày mò học lập trình, mình cố gắng dịch tài liệu tiếng Anh trên mạng sang tiếng Việt như một bài tập dùng mình hiểu sâu hơn về chủ đề mình đang đọc. Nhân tiện mình muốn chia sẻ 1 bài dịch, hy vọng có thể giúp một số người tiếp cận với thông tin/kiến thức mới!

Note: Mình không chắc topic này nên nằm trong category “programming” hay “english” nhưng có lẽ “programming” phù hợp hơn vì mình tin chủ đề này “liên quan trực tiếp đến lập trình” chứ không phải về “ngữ pháp cơ bản và tiếng Anh chuyên ngành CNTT” vì mình không giải thích từ ngữ tiếng Anh mà chỉ đơn thuần dịch theo cách hiểu của mình về một chủ đề mà, theo mình, cực kỳ quan trọng với một người bắt đầu lập trình C++.

Hôm nay, như tên topic, mình tìm hiểu về Các Tiêu Chuẩn Lập Trình C++, cụ thể là từ trang web:
http://www.mta.ca/~rrosebru/oldcourse/171199/171199_programming_standards.html

CS1711 Các Tiêu Chuẩn Lập Trình C++ (C++ Programming Standards)
Những tiêu chuẩn (standards) dưới đây, dựa trên những tiêu chuẩn cho khóa CS180 tại Purdue University, cần phải được chấp hành khi viết chương trình C++.
[Note: Đối tượng của bài viết là sinh viên trong trường nên tác giả khẳng định cần phải được chấp hành, với chúng ta thì chúng là các đề xuất nên làm theo.]
Chúng là một phần lớn trong tiêu chí đánh giá chấm điểm mọi chương trình.
Việc thiếu tôn trọng các tiêu chuẩn sẽ khiến bạn không nhận được đủ tín chỉ (credits).
Trách nhiệm của bạn là đặt câu hỏi về bất kỳ điều gì bạn chưa hiểu trong tiêu chuẩn mà bạn cần cho 1 bài tập lập trình (programming assigment).
Những cấu trúc (Constructs) chưa được nhắc tới trong các tiêu chuẩn này cần phải được áp dụng (implemented) một cách dễ đọc (readable fashion), nhất quán (consistent) với các chương trình trên lớp (class programs).
***

MỤC ĐÍCH (PURPOSE)
Mục đích của những quy tắc sau là
(1) để giới thiệu với bạn một bộ tiêu chuẩn lập trình điển hình (representative) thường thấy (typical) trong môi trường lập trình chuyên nghiệp và
(2) để giúp bạn phát triển phong cách tốt (good style) như một thói quen, điều bạn sẽ rất cần để hoàn thành các chương trình lớn một cách thành công.
Tất nhiên các bạn có thể viết chương trình C++ để giải các bài tập nhỏ trong khóa học này mà không chú ý đến phong cách. Nhưng bạn cần phải nhớ bạn đang xây dựng kỹ năng lập trình và giải quyết vấn đề (solving problems), không chỉ tìm đáp án cho các bài tập trên lớp.

TÊN TỆP VÀ MÔI TRƯỜNG C++ (FILE NAMES AND C++ ENVIRONMENT)
Trong khóa học này mỗi tên tệp (file name) C++ nên thể hiện rõ bản chất chương trình là gì và nên có đuôi “.cpp”. Tên tệp khi nộp assignment phải chỉ rõ nộ dung bài tập.

GIỚI THIỆU VỀ CUNG CẤP TÀI LIỆU (INTRODUCTORY DOCUMENTATION)
Bắt đầu mỗi chương trình nên có 1 khối comment (comment block) chứa:
1. Tên chương trình.
2. Tên của bạn và tên người dùng (username).
3. Ngày/tháng/năm mà chương trình được hoàn thành.
4. Tóm tắt nội dung chương trình, miêu tả phương pháp (method) hay thuật toán (algorithm) được sử dụng để tìm ra giải pháp (solution), các cấu trúc dữ liệu lớn (major data structures) (nếu có) trong chương trình và các comment chung chung khác bao gồm các tính năng bổ sung (extra features).
5. Tên tệp (file name)
Một VD của định dạng được yêu cầu (required format) như sau:

//******************************************************************* 
//                                                                    
//  Chuong trinh:  Converting temperatures                                           
//                                                                     
//  Tac gia:  Jane Doe, [email protected]
//                                                                    
//  Mieu ta:  /**mieu ta tom tat cho chuong trinh**/                    
//                                                                    
//  Ngay:  September 28, 1999
//
//  Thong tin Khoa hoc: CS 1711, Section A, Assignment 2, Problem 1
//
//  Ten tep: convert.cpp 
//                                                                    
//*******************************************************************

KHAI BÁO (DECLARATIONS)

  1. Bạn phải dùng các tên dễ nhớ (mnemonic names) cho tất cả các từ nhận dạng (identifiers). Đây là các tên có ý nghĩa đối với bài tập. Những tên gọi này nên gợi ý cách sử dụng của identifier.

  2. Lệnh khai báo mọi identifier (bao gồm cả khai báo các hàm) phải đi kèm với 1 comment giải thích cách sử dụng của nó.

  3. Classes và Structs phải bắt đầu bằng chữ in hoa (capital letter) (VD: Date, Vehicle, Software_engineer).

  4. Tên biến (variable names) phải bắt đầu bằng chữ in thường (lowercase letter) (VD: student, temperature, weight, salary). Phân biệt các từ trong tên biến bằng chữ in hoa (VD: payRate, fuelLevel, serialNumber). Chú ý: Chúng ta sử dụng tiêu chuẩn này đẻ bám theo (conform) sách của chúng ta. Nhiều tác giả sử dụng gạch dưới (underscore) cho mục đích này (VD: pay_rate, fuel_level, serial_number).

  5. Các hằng số trong chương trình phải được khai báo bằng const. Constant identifiers phải luôn luôn viết hoa toàn bộ. VD:

const float BASE = 2.0;      	// uoc so de chuyen doi sang he co so nhi phan  (obtain base 2)
const char HYPHEN = '-';      // bao hieu tu tiep tuc o dong tiep theo (signals word continued
on next line)
const int NAME_LENGTH = 20;   	// ten co the dai 20 chu cai
  1. KHÔNG ĐƯỢC khai báo biến toàn cục (globally-visible variables). Các hằng số (constants), kiểu đánh số (enumerated types), lớp (classes), cấu trúc (structures), và tên tệp (file names) thì được khai báo toàn cục (globally-visible).

CÁC QUY ĐỊNH CHUNG (GENERAL RULES)

  1. Mỗi lệnh khai báo (declaration) biến và hằng số phải đẻ ở 1 dòng riêng biệt trong đó chứa 1 comment giải thích nó là gì. VD:
		float volts;                   // dien ap trong mach dien (voltage in the circuit) 
		int amps;                     // cuong do dong dien trong mach dien (amperage in the circuit) 
		char circuitName[NAME_LENGTH];  // ten cua mach dien (name of the circuit) 
  1. Mỗi câu lệnh nên ở 1 dòng riêng biệt. VD thay vì viết
		left = nextLeft;    right = nextRight;

hãy viết như sau

		left  = nextLeft;     // dich sang ben trai (move to the left)
		right = nextRight;    // dich sang ben phai (move to the right)

Đôi khi quy tắc này có thể bỏ qua, VD khi khởi tạo biến đếm (index).

  1. Mỗi hàm phải bắt đầu với một khối comment (comment block) miêu tả muc đích (purpose), các tham số (parameters), và các hàm (functions) được gọi.
    Định dạng (format) cần sử dụng như sau:
//******************************************************************
//                                                                  
//  Ham: findSpaceCost
//                                                                  
//  Muc dich:  tinh va tra ve chi phi (cost) van chuyen hang hoa
//             giua 2 hanh tinh.                                  
//                                                                  
//  Tham so:  distance - khoang cach don vi dam (miles) giua 2 
//			 hanh tinh
//            weight   - khoi luong don vi pound cua khoi hang (item)
//		         duoc van chuyen
//                                                                  
//  Goi:  ham cargoRates
//                                                                  
//******************************************************************
  1. Các khối comment phải được tách ra khỏi code ít nhất 1 dòng trống (blank line), giúp dễ nhìn xem vị trí ở đâu thì code kết thúc và ở đâu thì comment bắt đầu.

CHÚ Ý: Theo ý kiến đóng góp của nhiều người, mình phải note thêm để tránh hiểu nhầm: Ý 5) dưới đây không nên áp dụng trong bất kỳ trường hợp nào ngoại trừ nếu khóa học của bạn yêu cầu. Mình nghĩ có lẽ ở một số nơi yêu cầu dùng void main() để tiện cho việc chấm điểm tự động? Còn thực tế mà nói luôn luôn dùng int main(). Bản thân tác giả cũng nói các compilers thường sẽ cảnh báo nếu dùng void main() và các sách cũng luôn dùng int main().

  1. Hàm main nên bắt đầu bằng
		void main ()

mặc dù nó có thể gây ra các cảnh báo (warnings) từ một số trình biên dịch (compilers), và để ý thấy rằng sách của bạn dùng cách phổ biến

		int main ()
  1. Các nguyên mẫu hàm (function prototypes) phải bao gồm kiểu (type) và tên của từng tham số (parameter):
		float expo (float value, int exponent);
  1. Sử dụng cấu trúc (construction) endl (thay vì \n) để ký hiệu xuống dòng (end-of-line). VD hãy dùng
		cout << "Today's date is " << today << endl;

thay vì

		cout << "Today's date is " << today << "\n";		/** VI SAO NEN TRANH "\n"??? Hay tim hieu them!!! **/

ĐINH DẠNG VÀ COMMENT CÁC CÂU LỆNH (FORMATTING AND COMMENTING OF STATEMENTS)

  1. Gióng hàng (alignment) và thụt dòng (indentation) các câu lệnh C++ là cực kỳ quan trọng cho tính dễ đọc (readability) của chương trình. Thụt dòng và sử dùng các dòng trống tăng độ dễ đọc cho chương trình của bạn.
  1. Hãy sử dụng dấu cách (whitespace) (các dòng trống (blank lines) và dấu cách trên các dòng) một cách tự do (liberally)!
    Hãy sử dụng các dấu ngoặc (parentheses) một cách tự do (liberally)!!
  1. Phần thân của 1 cấu trúc điều khiển (control structure), chẳng hạn như câu lệnh if, switch, while, do, hoặc for, phải được thụt dòng. Bạn có thể sử dụng từ 3 đến 6 dấu cách ở mỗi cấp độ thụt dòng (3 to 6 spaces per level of indentation).
  1. Phần thân của mỗi cấu trúc điều khiển chứa nhiều dòng (multiple line control structure body) phải được khoanh vùng bằng ngoặc (braces) trên từng dòng riêng biệt. Nếu số dòng trong phần thân của cấu trúc điều khiển vượt quá 5 dòng thì phải có 1 comment báo hiệu kết thúc cấu trúc.

Như vậy, các cấu trúc chính sẽ có dạng như sau trong chương trình của bạn:

/*cau lenh if*/

if (expression)
{
    statements 
}

hoặc nếu có hơn 5 dòng trong phần thân:

if (expression)
{
    statements
}  // ket thuc if (expression)
/*cau lenh if-else*/

if (expression)
{
    statements
}
else
{
    statements
} // ket thuc if (expression)
/*cau lenh switch*/

switch (selector variable)
{
    case case-1-value: case 1 statements;
         break;
    case case-2-value: case 2 statements;
         break;
    ...
    case case-n-value: case n statements;
         break;
    default: default statements;
         break;
}  // ket thuc switch (selector)    
/*cau lenh while*/

while (expression)
{
    statements
}  // ket thuc while (expression)
/*cau lenh do-while*/
do  // while (expression)
{
    statements
}
while (expression);
/*cau lenh for*/

for (initialization; test; increment)
{
    statements
} // ket thuc for (initialization)

THIẾT KẾ CHƯƠNG TRÌNH (PROGRAM DESIGN)

  1. Sử dụng phương pháp cải tiến từng bước (stepwise refinement). Các bài tập lập trình được giao là các bài có thể giải theo lối từng-bước-từng-bước (step-by-step manner). Phương pháp giải trong chương trình của bạn nên thể hiện kiểu cấu trúc này.

  2. Thành phần hóa/Đơn bộ hóa (modularize) chương trình của bạn. Khi giải pháp của bài toán dễ dàng chia thành các công việc riêng biệt, chương trình của bạn nên xử lý mỗi công việc trong 1 hàm riêng biệt và theo cách trực tiếp thẳng thắn (straightforward manner). Trong nhiều trường hợp bài tập sẽ chỉ rõ các hàm và các tham số của chúng.

  3. Hãy làm chương trình của bạn hiệu quả (efficient). Thuật toán của bạn nên thẳng thắn đơn giản (direct) và không phức tạp một cách không cần thiết. Sử dụng các cấu trúc dữ liệu phù hợp thường sẽ đơn giản hóa một thuật toán.

  4. Mọi biến dùng trong một hàm (all variables used in a function) phải được khai báo như các tham số (parameters) hoặc khai báo cục bộ (locally) bên trong hàm.

XUẤT DỮ LIỆU (OUTPUT)

  1. Tất cả các giá trị đầu vào (input values) phải được phản hồi (echoed) theo lối dễ đọc (readable manner) trừ khi có chỉ thị khác.

  2. Dữ liệu xuất ra của chương trình nên dễ đọc (readable) và được đánh dấu rõ ràng (clearly labelled). Tiêu đề (headings) nên được sử dụng khi cần thiết.

  3. Cuối cùng, tất nhiên, chương trình của bạn nên xuất ra các kết quả đúng!

Trong quá trình dịch, chắc chắn không tránh khỏi thiếu sót! Mong các bạn góp ý giúp mình chỉnh sửa. Cảm ơn rất nhiều!

1 Like

Tiêu chuẩn nội bộ thì nên dùng cái nào khả tín chút chứ bảo dùng void main() thì lạy hồn.

2 Likes

Bản thân em/mình cũng chỉ dùng int main() nên cũng không rõ vì sao tác giả khuyến khích void main() (có thể bài viết cũng lạc hậu rồi chăng?)

2 Likes

Cám ơn bạn đã dịch, mặc dù chưa chính xác lắm, mình góp ý để sau này bạn có thể hiểu tài liệu tiếng Anh chính xác hơn nhé:

  • Modularize : thành phần hóa, chia chương trình thành các module (thành phần), thành phần này có thể là class, struct, function…

Bạn nên dùng tiêu chuẩn hiện đại này:

3 Likes

Cảm ơn anh! (Chắc phải ít nhất là anh rồi ^^) Đúng là từ “đơn bộ hóa” (mặc dù theo em thì ý của nó cũng như “thành phần hóa”) có vẻ ít dùng nên nghe cũng kỳ… Thường mọi người cũng dùng luôn từ module nên dịch ra có lẽ cũng không cần thiết lắm.

Cảm ơn anh đã chia sẻ cuốn sách về tiêu chuẩn/phương pháp C++ hiện đại, cuốn sách có vẻ đầy đủ hơn rất nhiều và hướng tới độc giả là lập trình viên có kinh nghiệm. Bài dịch này ngắn gọn và hướng tới đối tượng sinh viên như em nên em đọc để giúp mình làm bài tập tốt hơn trong lúc học :slight_smile:

1 Like

Giữa học và thực tế/đi làm luôn có 1 khoảng cách nhất định, thế nên nếu được em nên học luôn các tiêu chuẩn/sách để giúp ích cho việc đi làm! Nếu em theo C++ thì anh gợi ý 1 số sách:

4 Likes

Sorry em nha thấy void main nên lỡ tay bấm report rồi

Search cái CppCoreGuildlines ấy, cả trăm mục nhưng ko ai rảnh đọc hết cả

2 Likes

Em đã bổ sung dòng note hy vọng sẽ tránh gây hiểu nhầm. Bản thân em mới học lập trình nên vừa rồi là đơn thuần dịch sát nghĩa của bài gốc. Tuy nhiên qua đây cũng học được một cách chắc chắn về sự quan trọng trong việc sử dụng int main(). Rất cảm ơn anh đã góp ý!

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?