Bài 56.124 phút đọc
Đặt tên
Sau bài này bạn sẽ làm được
- Áp dụng một quy ước đặt tên nhất quán
- Đặt tiền tố cho mọi ký hiệu công khai của thư viện
- Tránh sáu kiểu tên gây hiểu nhầm
- Đặt tên hàm theo cặp đối xứng
Mã của bạn được đọc nhiều hơn được viết, và thứ được đọc nhiều nhất trong mã là tên. Một cái tên tốt tiết kiệm một câu bình luận; một cái tên xấu tạo ra một lỗi.
#Chọn một quy ước
| Loại | Kiểu C chuẩn | Kiểu Linux kernel | Kiểu này dùng trong sách |
|---|---|---|---|
| Hàm | do_the_thing | do_the_thing | tinh_dien_tich |
| Biến cục bộ | count | cnt | so_luong |
| Tham số | n, buf | n, buf | n, bo_dem |
| Kiểu struct | struct foo_bar | struct foo_bar | SinhVien |
| typedef | foo_bar_t | Ít dùng typedef | SinhVien |
| Hằng, macro | MAX_SIZE | MAX_SIZE | CO_TOI_DA |
| Biến toàn cục | g_count | count | g_so_luong |
| Trường struct | name | name | ten |
| Tệp | foo_bar.c | foo-bar.c | danh_sach.c |
#Tiền tố cho ký hiệu công khai
Không gian tên phẳng
C không có namespace. Mọi ký hiệu không phải
static nằm chung một không gian tên duy nhất cho toàn bộ chương trình, kể cả các thư viện được liên kết vào. Tiền tố là cách duy nhất để tránh va chạm.Không nên
/* hinh.h, thu vien hinh hoc cua ban */
double dien_tich(double r);
double chu_vi(double r);
void ve(Hinh *h);
int khoi_tao(void);
/* Bon ten pho bien nhat the gioi. Ban vua chiem ca bon
trong khong gian ten TOAN CUC cua moi chuong trinh
dung thu vien nay. */
Nên
/* hinh.h */
double hinh_dien_tich(double r);
double hinh_chu_vi(double r);
void hinh_ve(Hinh *h);
int hinh_khoi_tao(void);
/* Cac thu vien that deu lam vay:
SQLite sqlite3_open, sqlite3_exec
zlib deflate, inflate, gzopen (tien to gz cho mot phan)
libcurl curl_easy_init, curl_easy_setopt
OpenSSL SSL_new, EVP_EncryptInit_ex, X509_verify */
#Va chạm tên
Va chạm với thư viện chuẩn
#include <stdio.h>
typedef struct { int *pt; int co; } DsSo;
/* Xoa mot phan tu khoi danh sach */
int remove(DsSo *d, int vi_tri) {
if (vi_tri < 0 || vi_tri >= d->co) return -1;
for (int i = vi_tri; i + 1 < d->co; ++i) d->pt[i] = d->pt[i + 1];
d->co--;
return 0;
}terminal
gcc -std=c11 -Wall -Wextra vacham2.c -o vacham2.exe
vacham2.c:7:5: error: conflicting types for 'remove'
int remove(DsSo *d, int vi_tri) {
^~~~~~
In file included from vacham2.c:2:
.../include/stdio.h:676:15: note: previous declaration of 'remove' was here
int __cdecl remove(const char *_Filename);
^~~~~~#Sáu kiểu tên gây hiểu nhầm
Một: tên nói dối
int dem_ky_tu(const char *s) {
int n = 0;
while (*s) { if (*s != ' ') ++n; ++s; } /* KHONG dem dau cach */
return n;
}
/* Ten noi "dem ky tu", ma khong dem dau cach.
Nguoi goi tin ten, khong doc than ham, va sinh ra mot loi.
Ten dung: dem_ky_tu_khong_trang, hoac doi ham cho khop ten. */Hai: tên khác nhau cho cùng một thứ
typedef struct { ... } NguoiDung;
NguoiDung *lay_nguoi_dung(int id);
NguoiDung *tim_user(const char *ten);
NguoiDung *doc_tai_khoan(int id);
NguoiDung *nap_thanh_vien(int id);
/* Bon tu cho MOT khai niem, va ba dong tu cho MOT hanh dong.
Nguoi doc phai tu hoi: "doc" va "nap" khac nhau cho nao?
Chon MOT tu cho MOI khai niem va viet vao tai lieu:
nguoi_dung khong dung user, tai khoan, thanh vien
lay khong dung tim, doc, nap */
NguoiDung *nguoi_dung_lay_theo_id(int id);
NguoiDung *nguoi_dung_lay_theo_ten(const char *ten);Ba: tên chỉ khác nhau một chữ
int xu_ly_don_hang(Don *d);
int xu_ly_don_hang_2(Don *d);
int xu_ly_don_hang_moi(Don *d);
int xu_ly_don_hang_cu(Don *d);
/* Ban se goi nham. Khong phai co the, ma la chac chan.
Nhat la trong danh sach tu dong hoan thanh cua trinh soan thao.
Neu ban thay minh dat ten kieu nay, do la dau hieu thiet ke sai:
bon ham do co gi khac nhau ma khong noi ra duoc bang tu? */
int don_hang_xac_nhan(Don *d);
int don_hang_huy(Don *d);
int don_hang_giao(Don *d);Bốn: mã hoá kiểu vào tên
int iSoLuong; /* ky phap Hungary */
char *szTen;
double dGiaTri;
LPCSTR lpszDuongDan;
/* Vi sao no da chet:
- Trinh bien dich da biet kieu. Ban khong can nhac lai.
- Khi ban doi int thanh long, ban phai doi TEN o moi cho.
Va neu ban luoi thi ten noi doi.
- Trinh soan thao hien kieu khi ban tro chuot vao.
Nhung mot phan cua Hungary VAN co ich: ma hoa Y NGHIA,
khong phai kieu. Do la "Hungary ung dung": */
int rong_px; /* pixel */
int rong_em; /* em */
int cho_ms; /* mili giay */
int cho_s; /* giay */
/* Bay gio cho_ms = cho_s la mot loi ban NHIN THAY duoc,
trong khi int a = int b thi khong. */Năm: phủ định trong tên
if (!khong_hop_le(x)) { ... } /* hai lan phu dinh */
if (!chua_khoi_tao) { ... }
if (!bo_qua_kiem_tra) { ... }
/* Nao khong hop le nghia la hop le? Nao chua khoi tao nghia la
da khoi tao? Moi lan doc la mot lan phai dao nguoc trong dau.
Dat ten o dang KHANG DINH: */
if (hop_le(x)) { ... }
if (da_khoi_tao) { ... }
if (can_kiem_tra) { ... }Sáu: tên chung chung
void xu_ly(void *du_lieu);
int kiem_tra(int x);
Data *lay_du_lieu(void);
void thuc_hien(void);
int quan_ly_trang_thai(int co);
/* "Xu ly" cai gi? "Kiem tra" dieu gi va tra ve gi?
Neu ban khong dat duoc mot cai ten cu the cho ham, thuong la
vi ham do lam QUA NHIEU viec. Ten chung chung la mot mui
thiet ke, khong chi la mot van de tham my. */
void don_hang_tinh_thue(DonHang *d);
int email_dung_dinh_dang(const char *s);
CauHinh *cau_hinh_doc_tu_tep(const char *duong_dan);#Đặt tên theo cặp
| Dùng cho | ||
|---|---|---|
| tao | huy | Cấp phát và giải phóng một đối tượng |
| mo | dong | Tài nguyên hệ thống: tệp, socket, kết nối |
| khoi_tao | don_dep | Cấu trúc do người gọi cấp bộ nhớ |
| them | xoa | Bộ chứa |
| day | lay | Ngăn xếp, hàng đợi |
| khoa | mo_khoa | Mutex |
| bat_dau | ket_thuc | Một giai đoạn có thời gian |
| dang_ky | huy_dang_ky | Bộ xử lý sự kiện, hàm gọi lại |
| nap | luu | Bền vững hoá |
| ma_hoa | giai_ma | Chuyển đổi hai chiều |
Header khó đọc
/* ds.h */
Ds *create(void);
void destroy(Ds *d);
int add(Ds *d, int x);
int get(Ds *d, int i);
int size(Ds *d);
void clear(Ds *d);
int find(Ds *d, int x);
Header tự giải thích
/* ds.h */
Ds *ds_tao(void);
void ds_huy(Ds *d);
int ds_them(Ds *d, int x);
int ds_lay(const Ds *d, size_t i, int *ra);
size_t ds_so_luong(const Ds *d);
void ds_xoa_het(Ds *d);
long ds_tim(const Ds *d, int x); /* -1 neu khong thay */
/* Ba cai duoc them ngoai tien to:
- const cho ham chi doc: doc header la biet ham nao sua
- size_t cho chi so va so luong, khong dung int
- ds_lay tra ve ma loi va dua gia tri qua *ra, vi
moi gia tri int deu hop le nen khong co gia tri "loi" */
Tự làm thử
- Viết ra quy ước đặt tên của dự án bạn đang làm, một trang, và dán vào
CONTRIBUTING.md. - Tìm trong mã của bạn một hàm không phải
staticmà lẽ ra phải là, và sửa. - Tái hiện lỗi
multiple definitionbằng hai tệp và giải thích vì sao bước biên dịch không báo gì. - Lấy một header của bạn và thêm tiền tố cho mọi ký hiệu công khai.
- Tìm một tên phủ định trong mã của bạn và viết lại ở dạng khẳng định.
- Liệt kê mọi cặp tạo và huỷ trong dự án của bạn, và kiểm tra chúng có đối xứng không.
Trình chấm điểm tự động sẽ được bổ sung ở giai đoạn sau. Hiện tại bạn tự chạy thử trên máy.
Tóm tắt
- Nhất quán quan trọng hơn đẹp: chọn một quy ước và giữ nó.
- C có không gian tên phẳng, nên mọi ký hiệu công khai cần tiền tố, và mọi thứ không phải giao diện phải là
static. - Va chạm tên với thư viện chuẩn có thể là lỗi biên dịch, lỗi liên kết, hoặc im lặng; tên bắt đầu bằng gạch dưới là dành riêng.
- Sáu kiểu tên xấu: nói dối, không nhất quán, khác một chữ, mã hoá kiểu, phủ định, và chung chung.
- Đặt tên theo cặp đối xứng để mắt quét được và thấy ngay chỗ thiếu.