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

Đề tài: Vấn đề vòng lặp...

  1. #1
    Ngày gia nhập
    09 2011
    Bài viết
    1

    Red face Vấn đề vòng lặp...

    Cho mình hỏi giữa for, while và do while khác nhau chỗ nào??? Mình nghĩ nó hoàn toàn giống nhau vì thế ta có thể dùng 1 trong 3 để phục vụ mọi mục đích lập trình phải không??
    Mình mới học lập trình được 2 tuần có gì sai mong các bạn thông cảm!

  2. #2
    Ngày gia nhập
    07 2008
    Nơi ở
    /media/Anime
    Bài viết
    2,288

    for và while -> kiểm tra điều kiện trước rồi mới lặp.
    for đã biết trước số lần lặp, while chưa xác định được số lần lặp.
    do while -> lặp rồi mới kiểm tra điều kiện, chưa xác định được số lần lặp.
    Càng yêu mèo thì mèo càng mập. Mèo càng mập ta lại càng yêu.

  3. #3
    Ngày gia nhập
    07 2011
    Bài viết
    160

    Trích dẫn Nguyên bản được gửi bởi meoconlongvang Xem bài viết
    for và while -> kiểm tra điều kiện trước rồi mới lặp.
    for đã biết trước số lần lặp, while chưa xác định được số lần lặp.
    do while -> lặp rồi mới kiểm tra điều kiện, chưa xác định được số lần lặp.
    Như mèo đã nói, do while lặp rồi mới kiểm tra điều kiện nên sẽ thực hiện vòng lặp tối thiểu 1 lần. Vì vậy không thể chuyển do while về 2 dạng kia nếu không muốn trùng lặp code + không dùng break/goto.

    Còn nói dùng for khi đã biết trước số lần lặp là không hoàn toàn chính xác. Phát biểu này có thể đúng với 1 số ngôn ngữ khác, còn trong C/C++ thì for hoàn toàn có thể dùng thay cho while (có thể coi for là 1 cách viết gọn của while) như sau
    Code:
    for (câu lệnh 1; điều kiện; câu lệnh 2) {thân vòng lặp}
    tương đương với
    Code:
    {
      câu lệnh 1;
      while (điều kiện) {
        thân vòng lặp;
        câu lệnh 2;
      }
    }
    Ví dụ như việc duyệt các ký tự trong chuỗi s (C-style) như sau:
    for (; *s; ++s) {...} // không biết trước số lần lặp, mà dùng for vẫn gọn + dễ nhìn hơn dùng while!

  4. #4
    Ngày gia nhập
    07 2008
    Nơi ở
    /media/Anime
    Bài viết
    2,288

    @fbchicken : trong ngôn ngữ c, chúng ta có thể lợi dụng biểu thức điều kiện của for để biến nó thành while. Tuy nhiên đây là một cách làm méo mó, ko đúng công dụng của for. Cách làm này nặng nề về tính học thuật. Công dụng chính của for là để thay đổi 1 hoặc nhiều biến chạy. Chính vì vậy, biểu thức điều kiện của for được thiết kế linh động hơn các ngôn ngữ khác rất nhiều. Nhưng cũng ko nên vì thế mà bóp méo nó để làm cho việc khác.
    Càng yêu mèo thì mèo càng mập. Mèo càng mập ta lại càng yêu.

  5. #5
    Ngày gia nhập
    03 2010
    Nơi ở
    My Home
    Bài viết
    772

    Trích dẫn Nguyên bản được gửi bởi meoconlongvang Xem bài viết
    @fbchicken : trong ngôn ngữ c, chúng ta có thể lợi dụng biểu thức điều kiện của for để biến nó thành while. Tuy nhiên đây là một cách làm méo mó, ko đúng công dụng của for. Cách làm này nặng nề về tính học thuật. Công dụng chính của for là để thay đổi 1 hoặc nhiều biến chạy. Chính vì vậy, biểu thức điều kiện của for được thiết kế linh động hơn các ngôn ngữ khác rất nhiều. Nhưng cũng ko nên vì thế mà bóp méo nó để làm cho việc khác.
    Không đúng.
    Nếu ai đã lập trình realtime thì đều biết rằng sử dụng những lệnh thế nào cho nó có hiệu quả.
    Lặp mà sử dụng goto là nhanh nhât, for rồi mới đến while.

    Nhiều lúc ta còn dùng:

    Code:
    for(;;)
    {
    }
    Hoàn toàn có thể thay
    Code:
    while(1)
    {
    }

  6. #6
    Ngày gia nhập
    07 2011
    Bài viết
    160

    Mặc định Vấn đề vòng lặp...

    Trích dẫn Nguyên bản được gửi bởi meoconlongvang Xem bài viết
    @fbchicken : trong ngôn ngữ c, chúng ta có thể lợi dụng biểu thức điều kiện của for để biến nó thành while. Tuy nhiên đây là một cách làm méo mó, ko đúng công dụng của for. Cách làm này nặng nề về tính học thuật. Công dụng chính của for là để thay đổi 1 hoặc nhiều biến chạy. Chính vì vậy, biểu thức điều kiện của for được thiết kế linh động hơn các ngôn ngữ khác rất nhiều. Nhưng cũng ko nên vì thế mà bóp méo nó để làm cho việc khác.
    Mời bạn trích dẫn 1 cái nguồn nói làm vậy là méo mó, không đúng công dụng của for!!! Standard document của for không hề khuyến cáo 1 chút gì là thiết kế dùng cho trường hợp nào. Đừng áp đặt ý kiến chủ quan, còn nếu nếu như việc sử dụng for thế nào được khuyến cáo ở đâu đó thì cần trích nguồn - hoặc ít ra cũng nói "theo như tôi đọc ở đâu đó thì..."

    Với cả chuyện nào rõ ràng chuyện đó, luận chứng của bạn rất mập mờ. Dùng for cho biến chạy, được, ok, coi đó là công dụng chính của for cũng không sai (nhưng bảo dùng for cho mục đích khác là méo mó thì mình không tán thành nhé). Nhưng biến chạy chẳng liên quan gì đến "biết trước số lần lặp"! Ngay cả cái ví dụ của mình nêu trong post trước cũng được coi là "biến chạy" đó thôi, mình cũng chỉ sửa lại cái ý "biết trước số lần lặp" chứ không nói gì đến biến chạy cả. Nếu bạn làm việc với khái niệm iterator sẽ thấy rõ hơn sự không liên quan giữa "số lần lặp" và "biến chạy". Đừng bảo mình dùng for cho iterator là "méo mó" nhé.

    P.S: Nếu mình nhớ không nhầm thì quan điểm "dùng for khi biết trước số lần lặp" có ở pascal và được nêu trong 1 số sách về pascal, vì cấu trúc for của pascal là for i := a to b. Không phải ngẫu nhiên mà C có thiết kế for khác hẳn, và lôi quan điểm đó ra áp dụng cho C thật là khiên cưỡng.

    Edit: Ồ, chú thích thêm là mình thích tranh luận thẳng thắn cởi mở chứ không muốn cãi nhau hay kiếm chuyện với bạn nhé ngoài các lý do thông thường ra thì còn vì 1 lý do là mình cũng rất yêu mèo (dù là man). hehe
    Đã được chỉnh sửa lần cuối bởi fbchicken : 26-09-2011 lúc 10:14 PM.

  7. #7
    Ngày gia nhập
    07 2008
    Nơi ở
    /media/Anime
    Bài viết
    2,288

    Đó là quan niệm chủ quan của mình và của 1 vài ông thầy của mình, nếu bạn bảo rằng sai thì mình cũng ko có comment gì ở đây. Trình lập trình game của mình ko bằng bạn, do đó chuyện optimize cho realtime mình ko dám đưa ra tranh luận. Nhưng mình thấy phép so sánh for ( ; ; ) với while (1) là ko công bằng. 3 biểu thức bên trong for đã bị bỏ đi, tức là for ko phải tốn công kiểm tra điều kiện, nó chỉ thực hiện khối lệnh bên trong rồi goto về đầu. Trong khi cú pháp của while, nó phải có 1 biểu thức điều kiện bên trong và nó luôn thực hiện kiểm tra điều kiện dựa trên biểu thức đó, do đó nó tốn hơn for đoạn này. Nhưng chỉ vì vậy bảo rằng for tốt hơn là ko hợp lý. Trường hợp đó thì cứ goto thẳng tiến, đâu cần phải tới for ? Tuy nhiên nếu cho for và while cùng thực hiện 1 công viêc là tăng biến chạy cho đến 1 giá trị nào đó thì khi đó phép so sánh giữa for và while mới công bằng.
    Càng yêu mèo thì mèo càng mập. Mèo càng mập ta lại càng yêu.

  8. #8
    Ngày gia nhập
    03 2010
    Nơi ở
    My Home
    Bài viết
    772

    Công bằng là tận dụng mọi khả năng hỗ trợ, có như thế nào dùng hết khả năng của nó. Nếu sử dụng ở trường hợp này thì for ăn while rồi, goto thì khỏi bàn.

    Còn chiều theo ý của bạn, tớ sẽ cho cả 3 cùng công bằng để test.
    Mỗi vòng lặp chỉ mất một 1 phép so sánh thui nhé.

    C Code:
    1. #include <time.h>
    2. #include <stdio.h>
    3. int main()
    4. {
    5.     int i = 3000000000;
    6.     unsigned long s, t;
    7.     s = clock();
    8.     while(i)//for(;;)
    9.     {
    10.         --i;
    11.     }
    12.     t = clock() - s;
    13.  
    14.     printf("while: total time: %d\n", t);
    15.  
    16.     i = 3000000000;
    17.     s = clock();
    18.     for(;;)
    19.     {
    20.         if(!i)
    21.             break;
    22.         --i;
    23.     }
    24.     t = clock() - s;
    25.     printf("for: total time: %d\n", t);
    26.    
    27.     i = 3000000000;
    28.     s = clock();
    29. L1: if(!i)
    30.         goto L2;
    31.     else
    32.     {
    33.         --i;
    34.         goto L1;
    35.     }  
    36. L2:
    37.     t = clock() - s;
    38.     printf("goto: total time: %d\n", t);
    39.     return 0;
    40. }

    Chạy cỡ 10 - 20 lần rồi thống kê bằng cách chia trung bình xem ai nhanh nhất.

    Tớ rất ngạc nhiên khi nhiều người được học IT thấy tớ code mà kêu trời lên sao hay dùng goto thế. Phần lớn họ khẳng định là không được dùng goto. Trong các giáo trình họ chỉ nói là không nên, chứ không nói là không được.
    Tớ giải thích là: đúng là không nên khi chưa kiểm soát được thôi, còn khi mình kiểm soát được thì dùng thế nào hiệu quả hơn thì dùng.

  9. #9
    Ngày gia nhập
    07 2008
    Nơi ở
    /media/Anime
    Bài viết
    2,288

    Về tốc độ thì goto là vô đối. Dĩ nhiên, cấm goto là một trong những quan niệm thuộc dạng cẩn thận quá đáng, cái đó mình cũng ko ưa. Thậm chí 1 số ông thầy còn ko cho return giữa hàm nữa. Họ nhất nhất cứ phải if else lồng nhau, kết quả cuối cùng thì lưu vào biến, đợi đến cuối hàm return biến đó ra. Hồi xưa mình đi học cũng khá ức chế. Nhưng mà suy cho cùng thì những ông thầy đó cũng có ý tốt, tính đường an toàn nhất để cho sinh viên ko bị loạn. Thực tế thì có khá nhiều sinh viên lập trình cơ bản đã ko xong, để cho họ free-style với goto thì đến khi bị lỗi stack thì 100% là họ ko sửa được. Ngay cả khi làm những dự án lớn, code goto rất khó mà nâng cấp, bảo trì nếu như ko phải là người code. Hơn nữa những ứng dụng dạng quản lý này nọ thì cũng chẳng cần optimize vì thực tế nó luôn có những khoảng thời gian chết bắt buộc, ví dụ như chờ csdl, chờ socket ... Có optimze thì qua mấy chỗ này cũng đứng cứng đơ và người dùng cũng ko thấy nhanh hơn bao nhiêu. Chỉ có trong môi trường cần realtime thì mới phải tận dụng hết mọi cách để optimize. Quan điểm của mình là ko lạm dụng cái gì cả. Khi nào cần thì mới dùng. Còn nếu ko thật sự cần thì ưu tiên cho tính trong sáng của code.
    Càng yêu mèo thì mèo càng mập. Mèo càng mập ta lại càng yêu.

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

  1. Kỹ thuật C++ Nhập và gán 1 kí tự trong vòng lặp sao cho khi không nhập kí tự thì vòng lặp lại chạy tiếp.
    Gửi bởi note194 trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 3
    Bài viết cuối: 12-08-2013, 09:11 PM
  2. Lập trình C++ giá trị của xâu trong vòng lặp và ngoài vòng lặp khác nhau
    Gửi bởi virus93ttll trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 17
    Bài viết cuối: 14-05-2011, 02:43 PM
  3. Code cài đặt DSLK đơn vòng và kép vòng trên C++. Thêm 1 phần tử sau 1 phần tử trong DSLK đơn/kép
    Gửi bởi hoanghieu.fit.hcmus trong diễn đàn Thảo luận, góp ý code C/C++ của bạn
    Trả lời: 2
    Bài viết cuối: 09-04-2011, 02:54 PM
  4. Tìm max (Sử dụng vòng lặp)
    Gửi bởi cr9 trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 13
    Bài viết cuối: 08-05-2010, 10:53 AM
  5. Vòng lặp for lồng nhau, giúp tớ hiểu rõ hơn về vòng lặp for lồng nhau?
    Gửi bởi bk7million trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 11
    Bài viết cuối: 29-04-2009, 07:46 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