Tôi muốn hiểu đoạn mã sau:
//...
#define _C 0x20
extern const char *_ctype_;
//...
__only_inline int iscntrl(int _c)
{
return (_c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)_c] & _C));
}
Nó bắt nguồn từ tập tin ctype.h từ mã nguồn của hệ điều hành obenbsd. Hàm này kiểm tra xem char là ký tự điều khiển hay chữ cái có thể in bên trong phạm vi ascii. Đây là chuỗi suy nghĩ hiện tại của tôi:
- iscntrl ('a') được gọi và 'a' được chuyển đổi thành giá trị nguyên
- đầu tiên kiểm tra xem _c là -1 sau đó trả về 0 khác ...
- tăng địa chỉ con trỏ không xác định trỏ lên 1
- khai báo địa chỉ này như một con trỏ tới một mảng có độ dài (unsign char) ((int) 'a')
- áp dụng bitwise và toán tử cho _C (0x20) và mảng (???)
Bằng cách nào đó, thật kỳ lạ, nó hoạt động và mọi lúc khi 0 được trả về char _c đã cho không phải là một ký tự có thể in được. Mặt khác, khi nó có thể in, hàm chỉ trả về một giá trị số nguyên không được quan tâm đặc biệt. Vấn đề hiểu biết của tôi là ở bước 3, 4 (một chút) và 5.
Cảm ơn bạn đã giúp đỡ.
(unsigned char)
là để chăm sóc khả năng các nhân vật được ký và tiêu cực.
_ctype_
về cơ bản là một mảng của bitmasks. Nó được lập chỉ mục bởi các nhân vật quan tâm. Vì vậy,_ctype_['A']
sẽ chứa các bit tương ứng với "alpha" và "chữ hoa",_ctype_['a']
sẽ chứa các bit tương ứng với "alpha" và "chữ thường",_ctype_['1']
sẽ chứa một bit tương ứng với "chữ số", v.v ... Có vẻ như0x20
là bit tương ứng với "control" . Nhưng vì một số lý do,_ctype_
mảng được bù 1, vì vậy các bit cho'a'
thực sự nằm trong_ctype_['a'+1]
. (Đó có lẽ là để cho nó hoạt độngEOF
ngay cả khi không có bài kiểm tra bổ sung.)