Từ 1 tới 6 trên tổng số 6 kết quả

Đề tài: Lập trình C++ | Cách đọc 1 statement !

  1. #1
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Mặc định Lập trình C++ | Cách đọc 1 statement !

    Đầu tiên, nói đến C++ thì ta phải hiểu C++ là 1 ngôn ngữ có cú pháp rất logic và rất khó chịu. Trong C++ không có may rủi hay đoán mò được, để hiểu thấu đáo thì ta phải từng bước từng bước dòng lệnh của nó. Bài này mình sẽ giới thiệu cách làm sao hiểu đúng ý nghĩa của những cách khai báo khó chịu, và mình tin rằng đối với những bạn mới học sẽ rất có ích T_T :

    Bây h xét 3 dòng lệnh sau :
    PHP Code:
    int  foo[5];     // foo là mãng gồm 5 phần tử kiểu int
    char  *foo;     // foo là con trỏ tới kiểu char
    double foo();  // foo là 1 hàm có kiểu trả về là double 
    Đơn giản nhỉ T_T, thế còn dòng này thì sao :
    PHP Code:
    char *(*(**foo[][8])())[]; //oops, cái quái gì thế này ????? 
    Mặc dù sẽ chẳng có ai khai báo 1 kiểu lạ lùng thế này, nhưng nếu chúng ta hiểu rõ bản chất thì dùng có gặp câu lệnh khủng bố hơn thế chúng ta vẫn có thể dễ dàng hiểu được.
    Trong C++, chúng ta phải hiểu rõ 3 toán tử sau :
    Toán tử * : ý nghĩa là ( trừ ý nghĩa dấu nhân ra ) nó đang trỏ tới 1 cái gì đó.
    Toán tử [] : ý nghĩa là mãng của gì đó.
    Toán tử () : hàm trả về cái gì đó, mặc dù trong đó sẽ có hoặc không có tham số, nhưng ta chú ý là dù có hay không toán tử này sẽ luôn ở bên phải 1 hàm nào đó, và 1 chú ý nữa trong 1 câu lệnh phức tạp thì dấu () thường ít có vai trò quan trọng hơn các toán tử còn lại, tại sao mình nói như vậy, đọc tiếp bạn sẽ hiểu ngay ...

    Bây h chúng ta sẽ tìm hiểu độ ưu tiên của 3 toán tử mà chúng ta đã đề cập ở trên. Dễ thấy rằng thằng [] và () có độ ưu tiên hơn thằng *. Và chắc chắn điều này sẽ là 1 mấu chốt quan trọng trong việc chúng ta sẽ đọc và hiểu những khai báo phức tạp như thế nào .
    Chúng ta sẽ có 1 quy luật nằm lòng như sau :
    Đi về bên phải khi có thể và đi về bên trái khi bắt buộc.
    Bây h còn chờ gì nữa nào, hãy thử đọc ví dụ sau :
    PHP Code:
    long **foo[7]; 
    Chú ý phần nào chúng ta đọc xong chúng ta sẽ xoá sổ chúng, để tiện cho việc theo dõi thằng nào đọc xong mình sẽ cho nó màu đen T_T.
    long **foo [7];
    -> foo... có kiểu là long
    long **foo [7];
    Tại điểm này chúng ta đã loại bỏ được 2 thông số cần biết là tên và kiểu, bây h vì thằng [] có độ ưu tiên cao hơn, chúng ta sẽ tiếp tục đi về bên phải.
    long **foo [7];
    -> Bây h ta sẽ có : foo là mãng của 7 phần tử ...kiểu long.
    long **foo [7];
    Bây h chúng ta sẽ đã hết đi về bên phải được nữa rùi, bây h chúng ta sẽ quay lại xử lý dấu * đầu tiên.
    -> foo là mãng của 7 phần tử trỏ tới...long.
    long **foo [7];
    Bây h là thằng * cuối cùng
    -> foo là mãng của 7 phần tử trỏ tới trỏ tới kiểu long
    Bingo !!! Phù, thế là xong, chua hơn dấm T_T.

    Để chắc rằng chúng ta đã là master về cú pháp, ta sẽ chơi thêm 1 ví dụ thật gấu nữa :
    PHP Code:
    char *(*(**foo [][8])())[]; //oops, what the hell T_T 
    Cũng theo qui luật trên, chúng ta cũng phân tích từng bước từng bước như vậy. Đầu tiên
    char *(*(**foo[] [8])())[];
    foo...có kiểu char. Tiếp theo :
    char *(*(**foo[] [8])())[];
    foo là mãng của....kiểu char.
    Thường thì đến đây chúng ta sẽ nghĩ là phải đi về bên trái, nhưng hãy nhớ lại qui luật mà xem :
    Đi về bên phải khi có thể và đi về bên trái khi bắt buộc.
    Vì thế tiếp tục đi về bên phải nào :
    char *(*(**foo[] [8])())[];
    -> foo là mãng của mãng của 8 phần tử....kiểu char.
    Oops, bây h chúng ta đã đụng phải thằng ngoặc mở, và tới đây chúng ta phải bắt buộc lùi lại để xử lý thằng bên trái thôi :
    char *(*(**foo[] [8])())[];
    -> foo là mãng của mãng của 8 phần tử trỏ tới trỏ tới hàm trả về....kiểu char.
    Bây h ta sẽ đứng giữa 2 dấu * bên trái, và () bên phải, ở TH này chúng ta sẽ tiếp tuc đi về bên phải và sau đó lại lùi về trái, ta có :
    -> char *(*(**foo[] [8])())[];
    foo là mãng của mãng của 8 phần tử trỏ tới trỏ tới hàm trả về trỏ tới mãng của....kiểu char.
    Bây h là giai đoạn cuối cùng :
    char *(*(**foo[] [8])())[];
    foo là mãng của mãng của 8 phần tử trỏ tới trỏ tới hàm trả về trỏ tới mãng của trỏ tới kiểu char.
    Chú ý là mình dùng trỏ tới chứ không hề có con trỏ ở trên, nếu chúng ta hiểu nó là con trỏ là sẽ sai trầm trọng đó.
    Có lẽ đọc vào cũng có hơi khó hiểu nhỉ, nhưng khi bạn đụng phải những câu lệnh phức tạp thì bạn sẽ thấy tác dụng của nó và hãy nhớ thật kĩ qui luật mà mình nên ra ở trên...!!
    Thân !

  2. #2
    Ngày gia nhập
    02 2008
    Bài viết
    5

    hi vọng rằng đời mình sẽ không gặp phải dòng lệnh nào thế này

  3. #3
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    hi vọng rằng đời mình sẽ không gặp phải dòng lệnh nào thế này
    Nếu cậu theo C/C++ thì vài 3 dòng lệnh trên chỉ là cơ bản thui. Cậu đọc code generic programming ( C++ là ngôn ngữ support generic mạnh nhất trong tất cả ngôn ngữ và cũng là 1 trong điểm mạnh nhất của C++ ) rùi cậu sẽ còn nhiều dịp bài đầu bức cổ để có thể hiểu được, good luck .
    C++ là 1 ngôn ngữ multiparadigm ( OOP + generic programing ). Trong C++ cậu cũng kế thừa, đóng gói kiểu object-oriented như các ngôn ngữ khác nhưng không có nghĩa chỉ OOP mới viết được code trong C++. Không có OOP C++ vẫn có thể handle được với template. Đó là lý do tại sao đọc code C++ không bao giờ dễ dàng. Hiểu bản chất thì sẽ dễ dàng hơn. Tuy vậy nói C++ mạnh nhất thì sẽ là sai lầm, tùy việc làm và tùy ngôn ngữ. Tuy tui rất mê C++ nhưng tui cũng phải tâm niệm điều này :
    All languages have advantages and drawbacks. Just pick the right tool for the job, and avoid temptation to become a nearsighted language zealot !

  4. #4
    Ngày gia nhập
    08 2008
    Bài viết
    3

    pro vãi. có bài tập hay post lên nhé

  5. #5
    Ngày gia nhập
    09 2008
    Nơi ở
    Kĩ viện
    Bài viết
    169

    Riêng NVD sẽ không bao giờ viết ra một chương trình mà có cái của này.

    char *(*(**foo [][8])())[]; //oops, what the hell T_T


    Và NVD sẽ luôn cố gắng làm cho code của mình dễ nhìn hết mức có thể . Tuy nhiên khi đọc code của người khác thì đành chịu biết làm thế nào . Hell!.
    Phá toái hư không - Bạch nhật thăng thiên.

  6. #6
    Ngày gia nhập
    10 2006
    Nơi ở
    In Your Bugs
    Bài viết
    823

    Mặc định Lập trình C++ | Cách đọc 1 statement !

    PHP Code:
    long **foo [7];
    -> 
    foo là mãng của 7 phần tử trỏ tới trỏ tới kiểu long 
    Nói thế này thì dễ hiểu hơn chứ R2:
    foo là mảng của 7 con trỏ, mà mỗi con trỏ, trỏ đến 1 con trỏ kiểu long.

    Chậc. Nhìn thấy muốn xỉu. Từ trước đến nay chỉ đụng đến mảng con trỏ 3,4 chiều là hết mức.

    Còn lên đến:
    char *(*(**foo[] [8])())[];

    Chắc cả đời ko sài.

Các đề tài tương tự

  1. Oracle với C# Gọi Procedure insert trong C# lỗi: invalid sql statement
    Gửi bởi kiofanta trong diễn đàn Thắc mắc Oracle
    Trả lời: 3
    Bài viết cuối: 18-07-2014, 01:45 PM
  2. Database Lỗi : Syntax error in INSERT INTO statement.
    Gửi bởi holygon trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 5
    Bài viết cuối: 30-04-2012, 11:03 PM
  3. [Help] Syntax error in UPDATE statement.
    Gửi bởi badboyst trong diễn đàn Nhập môn lập trình C#, ASP.NET
    Trả lời: 2
    Bài viết cuối: 09-05-2010, 10:51 PM
  4. Cách sử dụng using statement trong C# như thế nào?
    Gửi bởi stalinz trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 1
    Bài viết cuối: 12-09-2009, 05:53 PM
  5. Tổ chức lại Using Statement trong lập trình C#
    Gửi bởi nhc1987 trong diễn đàn Tutorials và Thủ thuật lập trình C#, ASP.NET
    Trả lời: 1
    Bài viết cuối: 07-02-2008, 10:14 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn