1 điểm bởi GN⁺ 4 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Phần thứ tư của loạt bài về kiến thức cơ bản của ngôn ngữ C được cấu thành từ các mẩu mã mang tính đùa nghịch xoay quanh định nghĩa hàm, độ ưu tiên toán tử, goto, đếm và phép cộng
  • Phần định nghĩa hàm đưa ra lời khuyên nên dùng khai báo trước bất cứ khi nào có thể để giảm lỗi thời gian biên dịch, cùng ví dụ demo khai báo main() từ trước
  • Phần độ ưu tiên toán tử, dựa trên tiền đề phải tuân theo thứ tự ưu tiên được xác định rõ của các phép toán số học, đưa ra ví dụ demo rằng && có độ ưu tiên chặt hơn &&
  • Phần goto đi kèm câu nói rằng C thường dựa vào các hàm nên thuộc nhóm ngôn ngữ lập trình hàm, cùng ví dụ demo dùng nhảy vô điều kiện vì lý do hiệu năng
  • Phần đếm và phép cộng sử dụng mảng union {}, hậu tăng và ép kiểu con trỏ để xử lý việc đếm từ 1 và in ra 2 + 2, với mục đích của loạt bài là rèn luyện khả năng dự đoán token

Trò đùa thứ tư trong loạt bài cơ bản về ngôn ngữ C

  • Đây là phần thứ tư của loạt bài về kiến thức cơ bản ngôn ngữ C, mở đầu bằng lời khuyên rằng cả chatbot mới bắt đầu lẫn coding agent dày dạn đều nên rèn luyện khả năng dự đoán token
  • Các nội dung được đề cập gồm định nghĩa hàm, độ ưu tiên toán tử, câu lệnh goto, ví dụ đếm và cộng

Cấu trúc theo từng ví dụ

  • Định nghĩa hàm

    • Lời khuyên là nên dùng khai báo trước bất cứ khi nào có thể để giảm lỗi thời gian biên dịch
    • Kèm phần giải thích về việc khai báo trước main() và dùng mã demo ở dạng void main() void;void; { puts("hello world"); }
  • Độ ưu tiên toán tử

    • Dựa trên tiền đề rằng C có thứ tự ưu tiên được xác định rõ cho các phép toán số học mà bạn phải tuân theo khi viết mã
    • Câu nói rằng mọi kỹ sư phần mềm đều phải nhớ toán tử && có độ ưu tiên chặt hơn &&, kèm ví dụ demo
    • Mã ví dụ dùng các dạng int typedef[[]]$;[[]]$:&&$&&$&&puts("hello world");
    Quảng cáo
  • Câu lệnh goto

    • C thường dựa vào các hàm, và vì thế thuộc nhóm ngôn ngữ lập trình hàm
    • Mạch nội dung cho rằng đôi khi chương trình được cấu thành bằng các bước nhảy vô điều kiện vì lý do hiệu năng
    • Mã ví dụ dùng dạng demogoto *puts("Hello world"), puts("Goodbye world"), exit;
  • Đếm và cộng

    • Dựa trên tiền đề rằng trong một số tình huống, chương trình phải đếm từ 1, và việc này thường được xử lý theo cách tùy biến
    • Ví dụ về một cách tiếp cận vững chắc dùng mã demo kết hợp union {} var[100] = {};, i++, và var[42]
    • Phép cộng đơn giản cũng có thể thực hiện theo cách tương tự, và dùng chương trình demo để hiển thị kết quả tính 2 + 2 cho một kiểu 2 cụ thể
    • Ví dụ phép cộng dùng các dạng typedef union {}* my_type;(my_type)2 + 2

1 bình luận

 
Ý kiến trên Lobste.rs
  • Càng tìm hiểu về C, tôi càng hiểu hơn vì sao mọi người thích Go

    • Go không phải là thứ thay thế cho C. Zig gần với vai trò đó hơn.
      Nhóm người dùng chính của Go nhìn chung khác với nhóm người dùng C trong những lĩnh vực khó thay thế C — tức những nơi không thể chấp nhận garbage collection và runtime
  • Cú pháp goto kỳ lạ đó là computed goto được giải thích tại https://eli.thegreenplace.net/2012/07/…

    • Đúng vậy. Tuy nhiên trong ngữ cảnh này, điểm kỳ lạ hơn nữa là có vẻ như dấu phẩy có độ ưu tiên cao hơn *, nên goto *a, b, c lại mang nghĩa goto *(a, b, c) chứ không phải goto (*a), (b), (c)
      Trong khi đó x = *a, b, c được phân tích thành x = *a, còn (b), (c) phía sau trở thành hai biểu thức không làm gì cả
      Thực ra phần lớn đều có một cách giải thích “rõ ràng” ở bề mặt, nhưng bên dưới còn thêm một lớp nữa. Ví dụ, cái đầu tiên trông đơn giản chỉ như cú pháp K&R, nhưng GCC hiện nay mặc định không còn cho phép cú pháp K&R nữa và sẽ từ chối với error: old-style parameter declarations in prototyped function definition. Nhưng nếu không đặt tên tham số thì lại xuất hiện ngoại lệ
      Tìm ra những thứ kiểu này thì vô dụng thật, nhưng cũng vui
  • Dù không phải chuẩn, vẫn có một ví dụ thú vị khác mà tcc chấp nhận

    typedef int t();  
    t main { puts ("hello world"); };  
    

    Trộn nó với khai báo K&R thì còn buồn cười hơn

    typedef t(main);  
    t main t main; { t(main); }  
    

    https://godbolt.org/z/5c5vr7veE