Cách dạy cách vượt qua khó khăn, đồng thời viết chu trình

Mặc dù thực tế là chúng ta sẽ nói về một trong những chủ đề cơ bản, bài viết này được viết cho các chuyên gia có kinh nghiệm. Mục đích là để chỉ ra những quan niệm sai lầm mà người mới bắt đầu gặp phải khi lập trình. Đối với các nhà phát triển thực hành, những vấn đề này từ lâu đã được giải quyết, bị lãng quên hoặc không hề được chú ý. Bài viết có thể hữu ích nếu bạn đột nhiên cần giúp đỡ ai đó về chủ đề này. Bài viết có sự tương đồng với tài liệu từ nhiều cuốn sách về lập trình khác nhau của Schildt, Stroustrup, Okulov.

Chủ đề về chu trình được chọn vì khá nhiều người bị loại khỏi nó khi thành thạo lập trình.

Kỹ thuật này được thiết kế cho học sinh yếu. Theo quy định, những người mạnh mẽ không bị mắc kẹt trong chủ đề này và không cần phải đưa ra các kỹ thuật đặc biệt cho họ. Mục tiêu phụ của bài viết là chuyển kỹ thuật này từ lớp “dành cho tất cả học sinh, nhưng chỉ một giáo viên” sang lớp “dành cho tất cả học sinh, tất cả giáo viên”. Tôi không khẳng định tính độc đáo tuyệt đối. Nếu bạn đã sử dụng một phương pháp tương tự để dạy chủ đề này, vui lòng viết ra phiên bản của bạn khác biệt như thế nào. Nếu bạn quyết định sử dụng nó, hãy cho chúng tôi biết nó diễn ra như thế nào. Nếu một kỹ thuật tương tự được mô tả trong một cuốn sách, vui lòng viết tên.


Tôi đã làm việc về kỹ thuật này trong 4 năm, nghiên cứu riêng với các sinh viên ở các cấp độ đào tạo khác nhau. Tổng cộng có khoảng năm mươi sinh viên và hai nghìn giờ học. Lúc đầu, học sinh luôn bị mắc kẹt trong chủ đề này và bỏ đi. Sau mỗi học sinh, phương pháp và tài liệu được điều chỉnh. Trong năm qua, học sinh không còn bị mắc kẹt trong chủ đề này nữa nên tôi quyết định chia sẻ những phát hiện của mình.

Sao nhiều chữ thế? Chu kỳ rất cơ bản!

Như tôi đã viết ở trên, đối với các nhà phát triển đang hành nghề và những sinh viên giỏi, độ phức tạp của khái niệm vòng lặp có thể bị đánh giá thấp. Ví dụ, bạn có thể giảng một bài dài, nhìn thấy những cái gật đầu và đôi mắt thông minh. Nhưng khi cố gắng giải quyết bất kỳ vấn đề nào, những vấn đề ngớ ngẩn và không thể giải thích được bắt đầu. Sau bài giảng, có lẽ học sinh chỉ hiểu được một phần. Tình hình trở nên trầm trọng hơn khi bản thân học sinh không thể nói lên chính xác ảo tưởng của mình là gì.
Một ngày nọ, tôi nhận ra rằng học sinh coi ví dụ của tôi là chữ tượng hình. Nghĩa là, giống như những đoạn văn bản không thể chia cắt mà bạn cần thêm một số chữ cái “ma thuật” vào và nó sẽ hoạt động.
Đôi khi tôi nhận thấy rằng học sinh nghĩ rằng để giải quyết một vấn đề cụ thể bạn cần thứ gì khác một thiết kế mà tôi chưa trình bày. Mặc dù giải pháp chỉ yêu cầu sửa đổi một chút ví dụ.

Vì vậy, tôi nảy ra ý tưởng rằng không nên tập trung vào cú pháp của các biểu thức mà là ý tưởng tái cấu trúc mã lặp đi lặp lại bằng cách sử dụng các vòng lặp. Một khi học sinh đã nắm vững ý tưởng này, bất kỳ cú pháp nào cũng có thể được cải thiện mà không cần thực hành nhiều.

Tôi dạy ai và tại sao?

Vì không có kỳ thi đầu vào nên các lớp học có thể bao gồm cả học sinh giỏi và học sinh rất yếu. Bạn có thể đọc thêm về các sinh viên của tôi trong bài viết Chân dung học viên khóa tối
Tôi đã cố gắng đảm bảo rằng tất cả những ai muốn học lập trình đều có thể học được nó.
Các lớp học của tôi được tổ chức riêng lẻ và học sinh tự trả tiền cho mỗi lớp. Có vẻ như sinh viên sẽ tối ưu hóa chi phí và yêu cầu ở mức tối thiểu. Tuy nhiên, mọi người đến các lớp học trực tiếp với một giáo viên trực tiếp không phải vì kiến ​​thức mà vì sự tự tin về những gì họ đã học, vì cảm giác tiến bộ và được sự chấp thuận của chuyên gia (giáo viên). Nếu sinh viên không cảm thấy tiến bộ trong việc học của họ, họ sẽ bỏ đi. Nhìn chung, các lớp học có thể được cấu trúc sao cho học sinh cảm nhận được sự tiến bộ trong việc tăng số lượng cấu trúc quen thuộc. Nghĩa là, đầu tiên chúng tôi học một cách chi tiết, sau đó chúng tôi học, sau đó học một lúc, và bây giờ chúng tôi đã có sẵn khóa học nghìn lẻ một đêm, trong đó chỉ học các chu kỳ trong hai tháng và cuối cùng - một sinh viên đã viết một thư viện tiêu chuẩn theo chính tả. Tuy nhiên, để giải quyết các vấn đề thực tế, bạn không chỉ cần có kiến ​​thức về tài liệu mà còn cần tính độc lập trong ứng dụng và tìm kiếm thông tin mới. Vì vậy, đối với các khóa học trực tiếp, tôi nghĩ nguyên tắc đúng đắn là dạy ở mức tối thiểu và khuyến khích việc nghiên cứu độc lập về các sắc thái và các chủ đề liên quan. Trong chủ đề về vòng lặp, tôi coi cấu trúc while là mức tối thiểu. Bạn có thể hiểu nguyên tắc từ nó. Biết được nguyên tắc, bạn có thể tự mình nắm vững cả việc làm và việc làm.

Để học sinh yếu có thể nắm vững nội dung, việc mô tả cú pháp là chưa đủ. Cần đưa ra những nhiệm vụ đơn giản nhưng đa dạng hơn và mô tả ví dụ chi tiết hơn. Cuối cùng, tốc độ phát triển bị hạn chế bởi khả năng của học sinh trong việc biến đổi các biểu thức và tìm kiếm các mẫu. Đối với những học sinh thông minh, hầu hết các bài tập sẽ nhàm chán. Khi học với họ, bạn không cần phải nhất quyết giải quyết 100% vấn đề. Tài liệu của tôi có thể được xem tại github của tôi. Đúng vậy, kho lưu trữ giống cuốn ma đạo thư của thầy phù thủy hơn - không ai ngoài tôi sẽ hiểu cái gì ở đâu và nếu bạn không kiểm tra được, bạn có thể phát điên

Phương pháp luận thiên về thực hành

Lý thuyết được giải thích bằng cách sử dụng ví dụ giải quyết vấn đề. Trong một lớp lập trình cơ bản dạy về nhánh và vòng lặp, không thể giảng một bài giảng hữu ích về một chủ đề trong suốt một giờ đồng hồ. 15-20 phút là đủ để giải thích khái niệm này. Những khó khăn chính nảy sinh khi thực hiện các nhiệm vụ thực tế.
Những giáo viên mới bắt đầu có thể giải thích các toán tử, nhánh, vòng lặp và mảng trong một bài giảng. Nhưng học sinh của họ sẽ phải đối mặt với vấn đề tiếp thu thông tin này.
Rốt cuộc, bạn không chỉ cần kể tài liệu mà còn phải đảm bảo rằng người nghe hiểu được nội dung đó.

Thực tế nắm vững một chủ đề được xác định bởi cách học sinh đối phó với công việc độc lập.
Nếu học sinh giải được một bài toán về một chủ đề mà không cần sự giúp đỡ của giáo viên thì chủ đề đó đã được nắm vững. Để đảm bảo việc tự kiểm tra, mỗi nhiệm vụ được mô tả trong bảng với các kịch bản kiểm tra. Các công việc có thứ tự rõ ràng. Bỏ qua nhiệm vụ không được khuyến khích. Nếu nhiệm vụ hiện tại quá khó thì việc chuyển sang nhiệm vụ tiếp theo cũng vô ích. Nó thậm chí còn phức tạp hơn. Để học sinh có thể nắm vững nhiệm vụ phức tạp hiện tại, một số kỹ thuật sẽ được giải thích cho học sinh bằng ví dụ về vấn đề đầu tiên. Trên thực tế, toàn bộ nội dung của chủ đề đều đề cập đến các kỹ thuật vượt qua khó khăn. Chu kỳ là một tác dụng phụ.

Nhiệm vụ đầu tiên luôn là một ví dụ. Phần thứ hai hơi khác một chút và được thực hiện “độc lập” ngay sau phần đầu tiên dưới sự giám sát của giáo viên. Tất cả các nhiệm vụ tiếp theo đều nhằm mục đích chú ý đến những điều nhỏ nhặt khác nhau có thể gây ra quan niệm sai lầm.

Phần giải thích của ví dụ là một cuộc đối thoại trong đó học sinh cần gọi lại việc truyền bá và xác nhận chéo để đảm bảo rằng mình đã nắm vững một phần tài liệu.

Tôi sẽ tầm thường và nói rằng ví dụ đầu tiên về chủ đề này là rất quan trọng. Nếu bạn có tài liệu cho công việc độc lập sâu rộng thì những thiếu sót trong ví dụ đầu tiên có thể được sửa chữa. Nếu không có gì khác ngoài ví dụ thì rất có thể học sinh sẽ không nắm vững được chủ đề.

Trong khi hay cho?

Một trong những vấn đề gây tranh cãi là việc lựa chọn cách xây dựng cho ví dụ: while hay for. Có lần, một người bạn là nhà phát triển thực hành của tôi không có kinh nghiệm giảng dạy đã dành cả giờ để thuyết phục tôi rằng vòng lặp for là dễ hiểu nhất. Các cuộc tranh luận tập trung vào “mọi thứ trong đó đều rõ ràng và được sắp xếp đúng vị trí của nó”. Tuy nhiên, nguyên nhân cốt lõi của những khó khăn đối với những người mới bắt đầu thực sự là ý tưởng về chính chu trình chứ không phải cách viết của nó. Nếu một người không hiểu ý tưởng này thì anh ta sẽ gặp khó khăn với cú pháp. Ngay khi ý tưởng được hiện thực hóa, các vấn đề về thiết kế mã sẽ tự biến mất.

Trong tài liệu của tôi, chủ đề vòng lặp tuân theo chủ đề phân nhánh. Sự giống nhau bên ngoài của if và while cho phép chúng ta rút ra một sự tương tự trực tiếp: “khi điều kiện trong tiêu đề là đúng thì phần thân sẽ được thực thi”. Điểm đặc biệt duy nhất của chu trình là cơ thể được thực hiện nhiều lần.

Lập luận thứ hai của tôi là while yêu cầu ít định dạng hơn for. Ít định dạng hơn có nghĩa là ít lỗi ngu ngốc hơn khi thiếu dấu phẩy và dấu ngoặc đơn. Những người mới bắt đầu chưa phát triển đủ sự chú ý và tỉ mỉ để tự động tránh các lỗi cú pháp.
Lập luận thứ ba được giải thích trong nhiều cuốn sách hay như lập luận đầu tiên.

Nếu học sinh có thể dễ dàng chuyển đổi các biểu thức, thì bạn có thể nói về for in pass. Sau đó học sinh sẽ chọn những gì mình thích nhất. Nếu việc biến đổi gây khó khăn thì tốt hơn hết bạn đừng nên phân tán sự chú ý của mình. Trước tiên hãy để học sinh giải quyết mọi việc bằng cách sử dụng while. Khi bạn đã nắm vững chủ đề về vòng lặp, bạn có thể viết lại các giải pháp để thực hành chuyển đổi while thành for.
Vòng lặp hậu điều kiện là một điều khá hiếm. Tôi không dành chút thời gian nào cho nó cả. Nếu một học sinh đã nắm vững các ý tưởng xác định các mẫu hình và biến đổi các biểu thức, thì học sinh đó có thể tìm ra nó mà không cần sự giúp đỡ của tôi.

Khi trình bày ví dụ đầu tiên cho những học sinh giỏi, tôi chú ý đến thực tế là trong ví dụ đầu tiên, điều quan trọng là không chỉ ghi lại giải pháp mà còn cả toàn bộ chuỗi hành động dẫn đến kết quả. Những học sinh lười biếng có thể bỏ bê việc viết và chỉ sao chép thuật toán cuối cùng. Họ cần được thuyết phục rằng một ngày nào đó một nhiệm vụ khó khăn sẽ đến với họ. Để giải quyết nó, bạn sẽ cần làm theo các bước như trong ví dụ này. Đó là lý do tại sao điều quan trọng là phải ghi lại tất cả các giai đoạn. Trong các vấn đề sau, chỉ có thể để lại phiên bản cuối cùng của giải pháp.

Ý tưởng chính của tự động hóa là chúng ta giao cho máy tính thực hiện công việc thường ngày cho một người. Một trong những kỹ thuật cơ bản là viết vòng lặp. Nó được sử dụng khi một số hành động lặp lại giống hệt nhau được viết liên tiếp trong một chương trình.

Rõ ràng tốt hơn ngầm

Có vẻ như là một ý tưởng hay khi hiển thị cùng một cụm từ nhiều lần trong tác vụ lặp lại đầu tiên. Ví dụ:

Hoan hô, nó hoạt động!
Hoan hô, nó hoạt động!
Hoan hô, nó hoạt động!
Hoan hô, nó hoạt động!
Hoan hô, nó hoạt động!
Hoan hô, nó hoạt động!
Hoan hô, nó hoạt động!
Hoan hô, nó hoạt động!

Tùy chọn này không tốt vì giá trị bộ đếm không hiển thị ở đầu ra. Đây là một vấn đề cho người mới bắt đầu. Đừng đánh giá thấp cô ấy. Lúc đầu, nhiệm vụ này là nhiệm vụ đầu tiên và nhiệm vụ suy ra một chuỗi số theo thứ tự tăng dần là nhiệm vụ thứ hai. Cần phải đưa thêm các thuật ngữ “chu kỳ N lần” và “chu kỳ từ A đến B”, về cơ bản là giống nhau. Để không tạo ra các thực thể không cần thiết, tôi quyết định chỉ hiển thị một ví dụ với đầu ra là một chuỗi số. Rất ít người học được cách ghi nhớ một bộ đếm trong đầu và mô hình hóa hành vi của một chương trình trong đầu mà không cần chuẩn bị. Một số học sinh lần đầu tiên bắt gặp mô hình tư duy về chủ đề chu kỳ.
Sau một thời gian thực hành, tôi giao nhiệm vụ lặp lại cùng một văn bản để độc lập giải quyết. Nếu bạn đưa ra một con số nhìn thấy được trước rồi đến một con số vô hình, học sinh sẽ gặp ít vấn đề hơn. Đôi khi gợi ý “không viết số đếm lên màn hình” là đủ.

Người khác giải thích thế nào?

Trong hầu hết các tài liệu giáo dục trên Internet, cú pháp của chu trình được đưa ra như một phần của “bài giảng”. Ví dụ: trên dev.mozilla.org (hiện tại), một số cấu trúc khác được mô tả cùng với vòng lặp while. Trong trường hợp này, chỉ bản thân các thiết kế mới được đưa ra dưới dạng mẫu. Kết quả ra mắt của họ được mô tả bằng lời nhưng không có hình ảnh minh họa. Theo tôi, việc trình bày chủ đề như vậy sẽ nhân lên tính hữu ích của những tài liệu đó bằng không. Học sinh có thể viết lại mã và tự chạy nhưng vẫn cần một tiêu chuẩn để so sánh. Làm sao bạn có thể hiểu rằng một ví dụ đã được viết lại chính xác nếu không có gì để so sánh kết quả?
Khi chỉ đưa ra mẫu mà không có ví dụ, điều đó càng trở nên khó khăn hơn đối với học sinh. Làm thế nào để hiểu rằng các đoạn mã được đặt chính xác trong mẫu? Bạn có thể thử viết bằng cách nào đó, rồi chạy. Nhưng nếu không có tiêu chuẩn để so sánh kết quả thì việc tung ra cũng chẳng giúp ích được gì.

Trong khóa học C++ về Trực quan, cú pháp vòng lặp được đưa vào trang thứ ba của Bài giảng 4 với chủ đề “toán tử”. Khi giải thích cú pháp của vòng lặp, người ta đặc biệt nhấn mạnh vào thuật ngữ “toán tử”. Thuật ngữ này được trình bày dưới dạng một tập hợp các dữ kiện như “ký hiệu; đây là một câu lệnh", "{} là một câu lệnh ghép", "phần thân của vòng lặp phải là một câu lệnh". Tôi không thích cách tiếp cận này vì nó có vẻ che giấu những mối quan hệ quan trọng đằng sau một học kỳ. Việc phân tích mã nguồn của chương trình thành các thuật ngữ ở cấp độ này là cần thiết đối với các nhà phát triển trình biên dịch để triển khai đặc tả ngôn ngữ, chứ không phải đối với sinh viên như một phép tính gần đúng đầu tiên. Những người mới làm quen với lập trình hiếm khi đủ tỉ mỉ để chú ý kỹ đến các thuật ngữ. Hiếm có người nào nhớ và hiểu được từ mới ngay lần đầu tiên. Hầu như không ai có thể áp dụng chính xác một thuật ngữ vừa học. Vì vậy, học sinh mắc rất nhiều lỗi như “Em viết while(a<7);{ nhưng chương trình không chạy.”
Theo tôi, lúc đầu tốt hơn là đưa ra cú pháp của cấu trúc ngay bằng dấu ngoặc đơn. Tùy chọn không có dấu ngoặc đơn chỉ nên được giải thích nếu học sinh có câu hỏi cụ thể: “tại sao không có dấu ngoặc đơn và nó có tác dụng”.

Trong cuốn sách “Cơ bản về lập trình” xuất bản năm 2012 của Okulov, phần giới thiệu về vòng lặp bắt đầu bằng mẫu for, sau đó đưa ra các khuyến nghị về cách sử dụng nó và sau đó chuyển ngay đến phần thử nghiệm của bài học. Tôi hiểu rằng cuốn sách này được viết dành cho một nhóm thiểu số học sinh có năng lực nhưng hiếm khi đến lớp của tôi.

Trong những cuốn sách phổ thông, kết quả của các đoạn mã luôn được viết ra. Ví dụ: ấn bản “Java 8. The Complete Guide” năm 2015 của Shildt. Đầu tiên, một mẫu được đưa ra, sau đó là một chương trình ví dụ và ngay sau đó - kết quả thực thi.

Ví dụ, hãy xem xét một vòng lặp while thực hiện ngược lại
Đếm ngược bắt đầu từ 10 và hiển thị đúng 10 dòng “thước đo”:

//Продемонстрировать применение оператора цикла while
class While {
    public static void main(String args []) {
        int n = 10;
        while (n > 0) {
            System.out.println("такт " + n);
            n--;
        }
    }
}

Sau khi chạy, chương trình này xuất ra XNUMX "chu kỳ" như sau:
такт 10
такт 9
такт 8
такт 7
такт 6
такт 5
такт 4
такт 3
такт 2
такт 1

Cách mô tả mẫu, chương trình mẫu và kết quả của chương trình cũng được sử dụng trong sách “Javascript for Kids” và trong khóa học js trên w3schools.com. Định dạng trang web thậm chí còn cho phép ví dụ này có tính tương tác.

Cuốn sách Nguyên tắc và Thực hành Sử dụng C++ năm 2016 của Stroustrup thậm chí còn đi xa hơn. Bước đầu tiên là giải thích kết quả cần đạt được và sau đó nội dung của chương trình sẽ được hiển thị. Hơn nữa, họ không chỉ lấy một chương trình ngẫu nhiên làm ví dụ mà còn đưa ra một chuyến du ngoạn vào lịch sử. Điều này giúp thu hút sự chú ý đến nó: “Hãy nhìn xem, đây không chỉ là một đoạn văn bản vô dụng. Bạn thấy điều gì đó có ý nghĩa."

Ví dụ về phép lặp, hãy xem xét chương trình đầu tiên được thực thi trên máy lập trình được lưu trữ (EDSAC). Nó được viết bởi David Wheeler tại Phòng thí nghiệm Máy tính của Đại học Cambridge, Anh vào ngày 6 tháng 1949 năm XNUMX. Chương trình này tính toán và in một danh sách các hình vuông đơn giản.
0 0
1 1
2 4
3 9
4 16
...
98 9604
99 9801

Ở đây, mỗi dòng chứa một số, theo sau là ký tự tab ('t') và bình phương của số đó. Phiên bản C++ của chương trình này trông như thế này:

//Вычисляем и распечатываем таблицу квадратов чисел 0-99
int main()
{
    int i = 0; // Начинаем с нуля
    while(i < 100){
        cout << i << 't' << square(i) << 'n';
        ++i;
    }
}

Điều thú vị là mẫu cú pháp không được mô tả trong cuốn sách này. Stroustrup trong sách hướng dẫn (dịch) nhấn mạnh rằng nó tôn trọng trí thông minh của học sinh. Có lẽ khả năng xác định khuôn mẫu trong một số ví dụ được coi là biểu hiện của trí thông minh như vậy.

Như tôi giải thích bản thân mình

Cách tiếp cận của Stroustrup: mô tả kết quả, sau đó giải quyết vấn đề và sau đó học sinh phân tích độc lập - có vẻ là phương pháp sâu sắc nhất. Vì vậy, tôi quyết định lấy nó làm cơ sở nhưng kể nó bằng một ví dụ ít mang tính lịch sử hơn - nhiệm vụ rút ra “mục lục”. Nó tạo thành một mỏ neo dễ nhận biết để sau đó bạn có thể nói “hãy nhớ nhiệm vụ về mục lục” và để học sinh nhớ chính xác điều này. Trong ví dụ của tôi, tôi đã cố gắng ngăn chặn thêm hai quan niệm sai lầm phổ biến nhất. Tiếp theo tôi sẽ viết về chúng chi tiết hơn.

Trong nhiệm vụ này, chúng ta được giới thiệu các kỹ thuật để giải quyết các vấn đề phức tạp. Quyết định ban đầu cần phải được đưa ra một cách nguyên thủy và đơn giản. Vậy thì bạn có thể nghĩ cách cải thiện giải pháp này.
Введение
Глава 1
Глава 2
Глава 3
Глава 4
Глава 5
Глава 6
Глава 7
Заключение

Theo quan sát của tôi, cách tiếp cận “mẫu-ví dụ-kết quả” với nhiều cách kết hợp khác nhau vẫn dẫn đến việc học sinh cảm nhận vòng tuần hoàn như một chữ tượng hình. Điều này thể hiện ở chỗ họ không hiểu tại sao lại có điều kiện để viết ở đó, làm thế nào để chọn giữa i++ và i— và những điều tưởng chừng như hiển nhiên khác. Để tránh những quan niệm sai lầm này, cách tiếp cận khi nói về chu kỳ nên nhấn mạnh ý nghĩa của việc lặp lại các hành động giống hệt nhau và chỉ sau đó hình thức hóa chúng bằng cách sử dụng một cấu trúc. Do đó, trước khi đưa ra cú pháp vòng lặp, bạn cần giải quyết vấn đề một cách trực tiếp. Một giải pháp cơ bản cho vấn đề mục lục trông như thế này:

Console.WriteLine("Введение");
Console.WriteLine("Глава 1");
Console.WriteLine("Глава 2");
Console.WriteLine("Глава 3");
Console.WriteLine("Глава 4");
Console.WriteLine("Глава 5");
Console.WriteLine("Глава 6");
Console.WriteLine("Глава 7");
Console.WriteLine("Заключение");

Làm thế nào nó có thể được cải thiện?
Thay thế các hành động đơn điệu bằng một chu trình.
Những hành động nào được lặp lại liên tiếp mà không thay đổi?
Không có gì trong đoạn này. Tuy nhiên, các lệnh hiển thị từ “Chương” kèm theo số rất giống nhau.
Do đó, giai đoạn tiếp theo là tìm ra sự khác biệt giữa các mảnh vỡ. Chỉ trong nhiệm vụ này, mọi thứ đều rõ ràng, khi đó không phải các lệnh đơn lẻ sẽ được lặp lại mà là các khối mã từ 5 dòng trở lên. Bạn sẽ phải tìm kiếm không chỉ trong danh sách lệnh mà còn trong các cấu trúc phân nhánh hoặc vòng lặp.
Trong ví dụ, sự khác biệt giữa các lệnh nằm ở số sau từ “Chương”.
Một khi sự khác biệt được tìm thấy, bạn cần hiểu mô hình thay đổi. Mảnh khác nhau là con số? Nó liên tục tăng hay giảm? Giá trị của một số thay đổi như thế nào giữa hai đội cạnh nhau?
Trong ví dụ, số sau từ “Chương” tăng theo gia số 1. Sự khác biệt được tìm thấy, mô hình được tiết lộ. Bây giờ bạn có thể thay thế đoạn khác bằng một biến.
Bạn cần khai báo một biến như vậy trước đoạn đầu tiên lặp lại. Biến như vậy thường được gọi là I hoặc j hoặc một cái gì đó chi tiết hơn. Giá trị ban đầu của nó phải bằng giá trị đầu tiên hiển thị trên màn hình. Trong ví dụ, giá trị đầu tiên là 1.
Giá trị ban đầu cần lấy để hiển thị dãy số “100, 101, 102, 103, 104, 105”?
Số đầu tiên trong chuỗi này là 100.
Sau mỗi lệnh xuất, bạn cần tăng giá trị của biến này lên 1. Đơn vị này là bước thay đổi.
Bước nào sẽ xảy ra trong dãy số “100, 102, 104, 106”?
Bước 2 ở hàng này.
Sau khi thay thế đoạn khác bằng một biến, mã sẽ trông như thế này:

Console.WriteLine("Введение");
int i;
i = 0;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Заключение");

Sau khi áp dụng kỹ thuật “thể hiện mẫu của một biến” trong mã, bạn sẽ nhận được một số nhóm hành động giống hệt nhau liên tiếp. Bây giờ các hành động lặp lại có thể được thay thế bằng một chu kỳ.

Trình tự giải quyết vấn đề cần sử dụng vòng lặp bao gồm các bước sau:

  1. Giải quyết “trực diện” bằng nhiều lệnh riêng biệt
  2. Tìm một mẫu
  3. Thể hiện mô hình của một biến
  4. Thiết kế như một chu kỳ

Tiếp theo, các thuật ngữ mới được giới thiệu để học sinh không rơi vào tình trạng “Tôi hiểu hết nhưng không nói được”:
— bộ đếm luôn là một biến cần thiết để theo dõi số bước trong một vòng lặp. Thông thường là một số nguyên được so sánh với ràng buộc.
- bước đếm - mô tả mô hình thay đổi của bộ đếm.
- ràng buộc - một số hoặc biến mà bộ đếm được so sánh để thuật toán cuối cùng. Giá trị bộ đếm thay đổi để đạt đến giới hạn.
— nội dung vòng lặp — một tập hợp các lệnh sẽ được lặp lại. Khi họ nói “lệnh được viết bên trong một vòng lặp”, họ có nghĩa là phần thân.
— lặp vòng lặp — thực hiện một lần phần thân vòng lặp.
— điều kiện vòng lặp — một biểu thức logic xác định liệu một lần lặp khác có được thực thi hay không. (Có thể có sự nhầm lẫn với cấu trúc phân nhánh ở đây)
Bạn cần chuẩn bị cho thực tế là lúc đầu học sinh sẽ sử dụng các thuật ngữ cho các mục đích khác. Điều này áp dụng cho cả kẻ mạnh và kẻ yếu. Xây dựng một ngôn ngữ chung là một nghệ thuật. Bây giờ tôi sẽ viết ngắn gọn: bạn cần đặt nhiệm vụ “đánh dấu đoạn mã bằng <term>” và tự mình sử dụng các thuật ngữ này một cách chính xác trong cuộc trò chuyện.
Sau khi chuyển đổi bằng vòng lặp, ta thu được đoạn:

Console.WriteLine("Введение");
int i = 0;
while (i < 7) {
    Console.WriteLine("Глава " + i);
    i = i + 1;
}
Console.WriteLine("Заключение");

Quan niệm sai lầm chính

Một quan niệm sai lầm phổ biến của học sinh là họ đặt các hành động vào trong một vòng lặp chỉ cần thực hiện một lần. Ví dụ như thế này:

;
int i = 0;
while (i < 7) {
    Console.WriteLine("Введение")
    Console.WriteLine("Глава " + i);
    i = i + 1;
    Console.WriteLine("Заключение");
}

Học sinh luôn gặp phải vấn đề này, cả ở giai đoạn đầu và ở những vấn đề phức tạp hơn.
Gợi ý chính trong trường hợp này:

Bạn nên lặp lại lệnh bao nhiêu lần: một lần hay nhiều lần?

Các lệnh in dòng chữ “Giới thiệu”, “Kết luận” và khai báo, khởi tạo biến i không giống như các thao tác lặp đi lặp lại khác. Chúng chỉ được thực thi một lần, có nghĩa là chúng cần được viết bên ngoài thân vòng lặp.

Tất cả ba giai đoạn của giải pháp phải được giữ nguyên trong mã để bạn có thể tham khảo sau này trong trường hợp gặp khó khăn. Chỉ cần nhận xét hai phương án đầu tiên là đủ để chúng không gây trở ngại.
Sự chú ý của học sinh cần được thu hút vào các sự kiện sau:
— Trong điều kiện vòng lặp, bộ đếm và giới hạn thường được so sánh. Bộ đếm có thể thay đổi trong phần thân vòng lặp nhưng giới hạn thì không. Để phá vỡ quy tắc này, bạn cần đưa ra những lý do thuyết phục.
— Các lệnh hiển thị các từ “Giới thiệu” và “Kết luận” nằm bên ngoài thân vòng lặp. Chúng ta cần thực hiện chúng 1 lần. “Giới thiệu” - trước khi lặp lại các hành động, “Kết luận” - sau.
Trong quá trình củng cố chủ đề này, nắm vững các chủ đề tiếp theo, cũng như giải quyết khó khăn, ngay cả những học sinh giỏi cũng nên đặt câu hỏi: “Hành động này cần phải thực hiện bao nhiêu lần? Một hay nhiều?

Phát triển các kỹ năng bổ sung

Trong quá trình học tập, học sinh còn phát triển kỹ năng chẩn đoán và giải quyết vấn đề. Để tiến hành chẩn đoán, học sinh cần trình bày kết quả mong muốn và so sánh với kết quả thực tế. Hành động khắc phục phụ thuộc vào sự khác biệt giữa chúng.
Vì học sinh ở giai đoạn này vẫn chưa hiểu rõ về kết quả “mong muốn” nên các em có thể tập trung vào dữ liệu bài kiểm tra. Theo quy định, không ai ở giai đoạn này hiểu được điều gì có thể xảy ra và cách giải quyết nó. Vì vậy, tôi viết vào sổ mô tả các vấn đề điển hình và một số cách giải quyết chúng. Lựa chọn cái phù hợp nhất là nhiệm vụ của chính học sinh.
Cần có một bản ghi để hỏi “điều gì được mong đợi đã xảy ra?”, “Tình huống nào trong số những tình huống này đã xảy ra bây giờ?”, “Giải pháp áp dụng có giúp ích được không?”

  1. Số lượng hành động ít hơn hoặc nhiều hơn 1 so với dự kiến. Các giải pháp:
    - tăng giá trị ban đầu của bộ đếm lên 1.
    — thay thế toán tử so sánh chặt chẽ (< hoặc >) bằng toán tử không nghiêm ngặt (<= hoặc >=).
    - thay đổi giá trị giới hạn thành 1.
  2. Các hành động trong vòng lặp được thực hiện không ngừng, vô thời hạn. Các giải pháp:
    — thêm lệnh thay đổi bộ đếm nếu thiếu.
    — sửa lệnh thay đổi bộ đếm để giá trị của nó trở nên gần với giới hạn hơn.
    — loại bỏ lệnh thay đổi ràng buộc nếu nó nằm trong thân vòng lặp.
  3. Số hành động trong một vòng lặp ít hơn 1 hoặc nhiều hơn dự kiến. Hành động trong vòng lặp không được thực hiện dù chỉ một lần. Đầu tiên bạn cần tìm ra giá trị thực của các biến ngay trước khi vòng lặp bắt đầu. Các giải pháp:
    - thay đổi giá trị ban đầu của ràng buộc
    - thay đổi giá trị ban đầu của bộ đếm

Vấn đề 3 thường liên quan đến việc sử dụng sai biến hoặc không đặt lại bộ đếm về XNUMX.

Sau phần giải thích này, học sinh có thể vẫn có nhiều quan niệm sai lầm khác nhau về cách hoạt động của vòng lặp.
Để xua tan những cái phổ biến nhất, tôi giao cho bạn những nhiệm vụ sau:

  1. Trong đó giới hạn, giá trị bộ đếm ban đầu hoặc bước bộ đếm được người dùng nhập vào.
  2. Trong đó giá trị bộ đếm phải được sử dụng trong một số biểu thức số học. Nên sử dụng bộ đếm trong biểu thức căn thức hoặc trong mẫu số để chênh lệch là phi tuyến.
  3. Trong đó giá trị bộ đếm không được hiển thị trên màn hình khi vòng lặp đang chạy. Ví dụ: hiển thị số lượng đoạn văn bản giống hệt nhau được yêu cầu hoặc vẽ một hình bằng đồ họa con rùa.
  4. Trong đó trước tiên bạn cần thực hiện một số hành động lặp đi lặp lại, sau đó là các hành động khác.
  5. Trong đó bạn cần thực hiện các hành động khác trước và sau khi lặp lại

Đối với mỗi nhiệm vụ, bạn cần cung cấp dữ liệu thử nghiệm và kết quả mong đợi.

Để hiểu bạn có thể di chuyển nhanh như thế nào, bạn cần đọc thuật ngữ của những vấn đề này và hỏi: “Chúng khác với ví dụ như thế nào?”, “Cần thay đổi điều gì trong ví dụ để giải quyết chúng?” Nếu học sinh trả lời có ý nghĩa thì để học sinh giải ít nhất một câu trên lớp và phần còn lại tự học ở nhà. Nếu giải pháp thành công thì chúng ta có thể bắt đầu giải thích các điều kiện bên trong vòng lặp.
Nếu bạn gặp khó khăn khi tự mình giải quyết vấn đề, bạn cần phải giải quyết mọi việc trong lớp. Để tránh việc giải bài toán gợi nhớ đến việc vẽ một con cú, trước tiên tôi khuyên bạn nên giải bài toán theo cách không phổ quát. Nghĩa là, để giải pháp vượt qua thử nghiệm đầu tiên và không sử dụng cấu trúc vòng lặp. Vâng, sau đó áp dụng các phép biến đổi để đạt được tính phổ quát của giải pháp.

Vòng và nhánh

Theo tôi, sẽ rất hữu ích nếu đưa ra chủ đề “các chu kỳ trong các nhánh” riêng biệt. Để sau này bạn có thể thấy sự khác biệt giữa việc kiểm tra một điều kiện nhiều lần và kiểm tra nó một lần.
Nhiệm vụ hợp nhất sẽ là xuất các số từ A đến B do người dùng nhập:
- luôn theo thứ tự tăng dần.
- tăng dần hoặc giảm dần tùy theo giá trị của A và B.

Chủ đề “phân nhánh trong vòng lặp” chỉ nên được chuyển sang sau khi học sinh đã nắm vững các kỹ thuật: “thay thế một mẫu bằng một biến” và “thay thế các hành động lặp đi lặp lại bằng một chu trình”.
Lý do chính cho việc sử dụng các nhánh bên trong vòng lặp là sự bất thường trong mẫu. Ở giữa nó bị hỏng tùy thuộc vào dữ liệu ban đầu.
Đối với những học sinh có khả năng tìm kiếm giải pháp bằng cách kết hợp các kỹ thuật đơn giản, chỉ cần nói “phân nhánh có thể được viết bên trong vòng lặp” và đưa ra vấn đề “ví dụ” hoàn toàn để giải quyết một cách độc lập là đủ.
Nhiệm vụ ví dụ:

Người dùng nhập số X. Hiển thị các số từ 0 đến 9 vào một cột và đặt dấu “+” đối diện với số bằng X.

Nếu nhập số 00+
1
2
3
4
5
6
7
8
9

Nếu nhập số 60
1
2
3
4
5
6+
7
8
9

Nếu nhập số 90
1
2
3
4
5
6
7
8
9+

Nếu nhập số 7770
1
2
3
4
5
6
7
8
9

Nếu một lời giải thích ngắn gọn là không đủ để viết bằng vòng lặp, thì bạn cần đạt được một giải pháp chung cho cùng một vấn đề mà không cần vòng lặp.
Bạn sẽ nhận được một trong hai lựa chọn:
mong muốn

string temp;
temp = Console.ReadLine();
int x;
x = int.Parse(temp);
if (x==0) {
    Console.WriteLine(0 + "+");
} else {
    Console.WriteLine(0);
}
if (x==1) {
    Console.WriteLine(1 + "+");
} else {
    Console.WriteLine(1);
}
if (x==2) {
    Console.WriteLine(2 + "+");
} else {
    Console.WriteLine(2);
}
if (x==3) {
    Console.WriteLine(3 + "+");
} else {
    Console.WriteLine(3);
}
if (x==4) {
    Console.WriteLine(4 + "+");
} else {
    Console.WriteLine(4);
}
if (x==5) {
    Console.WriteLine(5 + "+");
} else {
    Console.WriteLine(5);
}
if (x==6) {
    Console.WriteLine(6 + "+");
} else {
    Console.WriteLine(6);
}
if (x==7) {
    Console.WriteLine(7 + "+");
} else {
    Console.WriteLine(7);
}
if (x==8) {
    Console.WriteLine(8 + "+");
} else {
    Console.WriteLine(8);
}
if (x==9) {
    Console.WriteLine(9 + "+");
} else {
    Console.WriteLine(9);
}

Khả thi

string temp;
temp = Console.ReadLine();
int x;
x = int.Parse(temp);
if (x==0) {
    Console.WriteLine("0+n1n2n3n4n5n6n7n8n9");
}
if (x==1) {
    Console.WriteLine("0n1+n2n3n4n5n6n7n8n9");
}
if (x==2) {
    Console.WriteLine("0n1n2+n3n4n5n6n7n8n9");
}
if (x==3) {
    Console.WriteLine("0n1n2n3+n4n5n6n7n8n9");
}
if (x==4) {
    Console.WriteLine("0n1n2n3n4+n5n6n7n8n9");
}
if (x==5) {
    Console.WriteLine("0n1n2n3n4n5+n6n7n8n9");
}
if (x==6) {
    Console.WriteLine("0n1n2n3n4n5n6+n7n8n9");
}
if (x==7) {
    Console.WriteLine("0n1n2n3n4n5n6n7+n8n9");
}
if (x==8) {
    Console.WriteLine("0n1n2n3n4n5n6n7n8+n9");
}
if (x==9) {
    Console.WriteLine("0n1n2n3n4n5n6n7n8n9+");
}

Tôi đưa ra trước một nhiệm vụ tương tự khi nghiên cứu chủ đề phân nhánh.
Nếu học sinh đưa ra một phương án “có thể”, thì bạn cần nói với họ rằng có thể có nhiều giải pháp cho cùng một vấn đề. Tuy nhiên, chúng khác nhau ở khả năng chống lại những thay đổi trong yêu cầu. Đặt câu hỏi: “Cần sửa bao nhiêu vị trí trong mã nếu tôi phải thêm một số khác?” Trong phiên bản “có thể”, bạn sẽ cần thêm một nhánh nữa và thêm một số mới vào 10 vị trí khác. Trong phần “mong muốn”, chỉ cần thêm một nhánh là đủ.
Đặt nhiệm vụ để tái tạo tùy chọn “mong muốn”, sau đó tìm một mẫu trong mã, thực hiện thay thế biến và viết một vòng lặp.
Nếu bạn có ý tưởng về cách giải quyết vấn đề này mà không cần vòng lặp theo cách khác, vui lòng viết bình luận.

Vòng lặp trong Vòng lặp

Ở chủ đề này bạn cần chú ý những điều sau:
- bộ đếm cho vòng lặp bên trong và bên ngoài phải là các biến khác nhau.
— bộ đếm của vòng lặp bên trong phải được đặt lại nhiều lần (nghĩa là ở phần thân của vòng lặp bên ngoài).
— trong tác vụ xuất văn bản, trước tiên bạn không thể viết một chữ cái thành nhiều dòng, rồi viết chữ thứ hai. Trước tiên, bạn phải in tất cả các chữ cái của dòng đầu tiên, sau đó là tất cả các chữ cái của dòng thứ hai, v.v.

Tốt nhất là bắt đầu giải thích chủ đề về vòng lặp trong vòng lặp bằng cách giải thích tầm quan trọng của việc đặt lại bộ đếm về XNUMX.
Nhiệm vụ ví dụ:

Người dùng nhập hai số: R và T. In hai dòng ký tự “#”. Dòng đầu tiên phải chứa ký tự R. Dòng thứ hai chứa T mảnh. Nếu bất kỳ số nào âm, hiển thị thông báo lỗi.

R=5, T=11#####
###########

R=20, T=3#####################
# # #

R=-1, T=6Giá trị R phải không âm

R=6, T=-2Giá trị T phải không âm

Hiển nhiên, bài toán này cũng có ít nhất hai cách giải.
mong muốn

string temp;
int R;
int T;
temp = Console.ReadLine();
R = int.Parse(temp);
temp = Console.ReadLine();
T = int.Parse(temp);
int i = 0;
while (i < R)
{
    Console.Write("#");
    i = i + 1;
}
Console.WriteLine();
i = 0;
while (i < T)
{
    Console.Write("#");
    i = i + 1;
}

Có thể #1

string temp;
int R;
int T;
temp = Console.ReadLine();
R = int.Parse(temp);
temp = Console.ReadLine();
T = int.Parse(temp);
int i = 0;
while (i < R)
{
    Console.Write("#");
    i = i + 1;
}
Console.WriteLine();
int j = 0;
j = 0;
while (j < T)
{
    Console.Write("#");
    j = j + 1;
}

Sự khác biệt là trong giải pháp "có thể", biến thứ hai được sử dụng để xuất ra dòng thứ hai. Bạn nên nhấn mạnh vào việc sử dụng cùng một biến cho cả hai vòng lặp. Hạn chế này có thể được giải thích bằng thực tế là giải pháp có một bộ đếm cho hai chu kỳ sẽ là một minh họa cho thuật ngữ “đặt lại bộ đếm”. Việc hiểu thuật ngữ này là cần thiết khi giải các bài toán sau. Như một sự thỏa hiệp, bạn có thể lưu cả hai giải pháp cho vấn đề.

Một vấn đề điển hình khi sử dụng một biến đếm cho hai vòng lặp sẽ như sau:
R=5, T=11#####
######

Số ký tự ở dòng thứ hai không tương ứng với giá trị của T. Nếu bạn cần trợ giúp về vấn đề này, thì bạn cần xem ghi chú về các vấn đề điển hình với vòng lặp. Đây là triệu chứng số 3. Nó được chẩn đoán nếu bạn thêm đầu ra giá trị bộ đếm ngay trước chu kỳ thứ hai. Đã khắc phục bằng cách đặt lại. Nhưng tốt hơn hết là đừng nói điều này ngay. Học sinh phải cố gắng hình thành ít nhất một giả thuyết.

Tất nhiên là có một giải pháp khác. Nhưng tôi chưa bao giờ thấy điều đó ở các sinh viên. Ở giai đoạn nghiên cứu chu kỳ, câu chuyện về nó sẽ làm phân tán sự chú ý. Bạn có thể quay lại sau khi tìm hiểu về các hàm chuỗi.
Có thể #2

string temp;
int R;
int T;
temp = Console.ReadLine();
R = int.Parse(temp);
temp = Console.ReadLine();
T = int.Parse(temp);
Console.WriteLine(new String('#', R));
Console.WriteLine(new String('#', T));

Nhiệm vụ bắt buộc tiếp theo:

Hiển thị các số từ 0 đến 9. Mỗi số phải nằm trên một dòng riêng. Số chữ số trên một dòng (W) được nhập từ bàn phím.

W = 10
1
2
3
4
5
6
7
8
9

W = 100000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999

Nếu học sinh đã thành thạo kỹ thuật thay biến thì học sinh đó sẽ đối phó khá nhanh. Một vấn đề có thể xảy ra nữa là việc đặt lại biến. Nếu bạn không thể xử lý được việc chuyển đổi, điều đó có nghĩa là bạn đang vội và cần giải quyết những vấn đề đơn giản hơn.

Cám ơn vì sự quan tâm của bạn. Hãy like và đăng ký kênh nhé.

PS Nếu bạn tìm thấy lỗi chính tả hoặc lỗi trong văn bản, vui lòng cho tôi biết. Điều này có thể được thực hiện bằng cách chọn một phần văn bản và nhấn “⌘ + Enter” trên máy Mac và “Ctrl / Enter” trên bàn phím cổ điển hoặc thông qua tin nhắn riêng tư. Nếu các tùy chọn này không có sẵn, hãy viết về lỗi trong phần bình luận. Cảm ơn!

Chỉ những người dùng đã đăng ký mới có thể tham gia khảo sát. Đăng nhập, xin vui lòng.

Thăm dò ý kiến ​​độc giả không nghiệp chướng

  • 20,0%Tôi dạy chuyên nghiệp, +12

  • 10,0%Tôi dạy chuyên nghiệp, -11

  • 70,0%Tôi không dạy, +17

  • 0,0%Tôi không dạy, -10

  • 0,0%Khác0

10 người dùng bình chọn. 5 người dùng bỏ phiếu trắng.

Nguồn: www.habr.com

Thêm một lời nhận xét