Bắt đầu

Tìm hiểu qua ví dụ

Một trong những cách tốt nhất để học lập trình bằng một ngôn ngữ mới là xem xét rất nhiều chương trình mẫu. Điều tốt nhất bạn cần làm là sao chép và dán từng chương trình bên dưới vào một tệp văn bản và biên dịch chương trình đó. Sau đó, hãy thử nghiệm. Bằng cách mở rộng các chương trình mẫu này, bạn sẽ làm quen với nhiều khía cạnh của C++ và sẽ cảm thấy tự tin hơn khi đến lúc viết chương trình từ đầu.

Ví dụ 1: Làm cho trình biên dịch hoạt động!

Nếu bạn chưa thực hiện việc này, hãy sao chép và dán chương trình cũ sau đây vào một tệp văn bản và biên dịch chương trình đó. Bạn có thể xem hướng dẫn biên dịch tại đây.

Có vẻ như bạn đã tìm hiểu thông tin chi tiết về chương trình này trong phần hướng dẫn, vì vậy chúng tôi sẽ không cung cấp nội dung mô tả từng dòng ở đây. Tuy nhiên, bạn cần lưu ý một số điều về tính dễ đọc. Những nội dung này bao gồm các nhận xét và định dạng giúp các chương trình dễ đọc, dễ hiểu và dễ duy trì.

  • Mỗi chương trình chúng tôi viết đều bắt đầu bằng một nhận xét tiêu đề, trong đó cung cấp tên tác giả, thông tin liên hệ, nội dung mô tả ngắn và cách sử dụng (nếu thích hợp). Mỗi hàm bắt đầu bằng một nhận xét về hoạt động và cách sử dụng.
  • Chúng tôi thêm nhận xét giải thích bằng cách sử dụng câu đầy đủ bất cứ khi nào mã không ghi lại được (ví dụ: trong trường hợp quá trình xử lý có khó khăn, không rõ ràng, thú vị hoặc quan trọng).
  • Luôn sử dụng tên mô tả: biến là các từ viết thường được phân tách bằng dấu _, như trong my_variable. Tên hàm sử dụng chữ cái viết hoa để đánh dấu các từ, như trong MyExLưu hàm(). Các hằng số bắt đầu bằng "k" và sử dụng chữ cái viết hoa để đánh dấu các từ, như trong kDaysInWeek.
  • Thụt lề là bội số của 2. Cấp đầu tiên là 2 dấu cách; nếu cần thụt lề thêm, chúng tôi dùng 4 dấu cách, 6 dấu cách, v.v.
// hello.cpp: Maggie Johnson
// Description: a program that prints the immortal saying "hello world"

#include <iostream>
using namespace std;

int main() {
  cout << "Hello World!" << endl;
  return 0;
}

Một số tính năng thử nghiệm nên thử:

  • Điều quan trọng nhất là đảm bảo rằng bạn có thể biên dịch và chạy chương trình này.
  • Sửa đổi chương trình trên để in "Hello World!" 4 lần trên một dòng cho 6 dòng, trong đó mỗi dòng được in trong một trường có 17 dấu cách. Hãy sử dụng vòng lặp for để thực hiện việc này. Hãy nhấp vào đây để tìm hiểu về định dạng đầu ra bằng cout. Nhấp vào đây để xem giải pháp.
  • Trên chương trình bạn vừa hoàn tất, hãy tìm cách in dòng chữ "Hello World!" (Xin chào mọi người!) căn trái trong các trường có 17 dấu cách (mặc định thường là căn phải). Nhấp vào đây để xem giải pháp.

Ví dụ 2: Nhận dữ liệu đầu vào

Dễ dàng nhận dữ liệu nhập từ bàn phím trong C++ bằng cách sử dụng cin. Dưới đây là ví dụ:

// get_input.cpp: Maggie Johnson
// Description: Illustrate the use of cin to get input.

#include <iostream>
using namespace std;

int main() {
  int input_var = 0;
  // Enter the do while loop and stay there until either
  // a non-numeric is entered, or -1 is entered. Note that
  // cin will accept any integer, 4, 40, 400, etc.
  do {
    cout << "Enter a number (-1 = quit): ";
    // The following line accepts input from the keyboard into
    // variable input_var.
    // cin returns false if an input operation fails, that is, if
    // something other than an int (the type of input_var) is entered.
    if (!(cin >> input_var)) {
      cout << "You entered a non-numeric. Exiting..." << endl;
      break;
      // exit the do while loop
    }
    if (input_var != -1) {
      cout << "You entered " << input_var << endl;
    }
  } while (input_var != -1);
  cout << "All done." << endl;
  return 0;
}

Thử nghiệm:

  • Khi xảy ra lỗi đầu vào, luồng "bị ngắt", cin sẽ trả về giá trị false (sai) và chương trình sẽ dừng lại. Việc đề phòng những lỗi như vậy là rất quan trọng như chúng tôi đã làm trong chương trình trên. Nhưng nếu chúng ta muốn khôi phục lỗi, thay vì yêu cầu dừng chương trình thì sao? Có hai bước để khôi phục sau khi xảy ra lỗi:
    1. Xoá lỗi bằng hàm cin.clear().
    2. Xoá các ký tự không chính xác khỏi luồng. Một cách để thực hiện việc này là sử dụng cin.ignore().

Viết một chương trình khôi phục từ dữ liệu đầu vào không hợp lệ theo 2 bước sau. Hãy sử dụng Google để tìm kiếm cách hoạt động của các phương thức này. Giải pháp của chúng tôi tại đây.

Ví dụ 3: Chương trình này tạo ra gì?

#include <iostream>
using namespace std;

int main() {
  cout << " 1\t2\t3\t4\t5\t6\t7\t8\t9" << endl << "" << endl;
  for (int c = 1; c < 10; c++) {
    cout << c << "| ";
    for (int i = 1; i < 10; i++) {
      cout << i * c << '\t';
    }
    cout << endl;
  }
  return 0;
} 

Ví dụ 4: Việc phân tách giúp mọi thứ dễ dàng hơn...

Đã đến lúc chúng ta bắt đầu viết trò chơi máy tính! Câu đầu tiên này hơi đơn giản, nhưng là khởi đầu. Nhiệm vụ của chúng ta là viết một chương trình triển khai trò chơi phỏng đoán. Chương trình của chúng tôi tạo một số ngẫu nhiên từ 0 đến 100. Người chơi phải đoán số bí mật. Chương trình này đưa ra các gợi ý như "quá cao" hoặc "quá thấp" cho đến khi người chơi cuối cùng đoán được số bí mật.

Chúng ta sẽ tìm hiểu trò chơi này qua 3 bước. 

  1. Tìm cách tạo một số ngẫu nhiên trong một phạm vi giá trị cho trước.
  2. Tạo một hàm chính xử lý một lượt đoán từ người chơi và đưa ra gợi ý.
  3. Thêm những gì chúng tôi cần cho phép cho nhiều lần đoán cho đến khi người chơi đoán được con số đó.

Quá trình phát triển này được gọi là phân ly, tức là chia một tác vụ thành các tác vụ phụ, mỗi tác vụ đều dễ thực hiện.

Bắt đầu từ bước 1, hãy tìm kiếm trên Google để xem cách tạo một số ngẫu nhiên bằng C++. Hãy thử tìm kiếm bằng "rand C++". Đây là giải pháp của chúng tôi. 

Ở bước 2, chúng ta cần nhận được một dữ liệu đầu vào số nguyên từ trình phát (với chế độ kiểm tra lỗi thích hợp trên cin) và kiểm tra dữ liệu đó với số bí mật. Hãy thử và tự viết phần này của trò chơi trước khi xem giải pháp của chúng tôi.

Cuối cùng, chúng ta cần thêm một vòng lặp tiếp tục thu thập dự đoán từ người chơi cho đến khi cuối cùng họ đoán được số bí mật. Sau khi hoàn thành phần này của chương trình, bạn có thể xem giải pháp của chúng tôi.

Phân ly là một trong những kỹ năng quan trọng nhất mà lập trình viên cần học. Việc có thể chia nhỏ nhiệm vụ thành các phần có thể quản lý và sau đó hoàn thành từng nhiệm vụ một là điều vô cùng quan trọng, bất kể dự án lớn hay nhỏ. Sau đây là một số cơ hội khác để bạn thực hành phân ly.

  • Nhiều công việc hằng ngày mang đến cơ hội xây dựng kỹ năng phân ly. Bạn có thể ngạc nhiên khi phát hiện ra rằng trí óc của mình hoạt động theo cách này!

    Ví dụ: nếu tôi phải dọn dẹp một căn bếp rất bừa bộn (có thể là một số bé gái chỉ mới nướng bánh), tôi chia nhỏ công việc để lên kế hoạch và đảm bảo không phải làm lại công việc sau. Tôi không muốn rửa sàn trước nếu có tất cả những thứ trên quầy cần dọn. Có lẽ tôi sẽ phải làm lại sàn sau. Có lẽ tôi đem mọi nguyên liệu bỏ đi trước; chuyển hết bát đĩa vào bồn rửa; dọn sạch quầy hàng; rửa bát; và cuối cùng là dọn sạch sàn nhà. Có nhiều cách khác để thực hiện nhiệm vụ này, nhưng việc suy nghĩ kỹ trước tiên sẽ giúp tôi xác định một kế hoạch mà không cần chỉnh sửa lại.

    Dùng các công việc hằng ngày làm ví dụ để phát triển kỹ năng phân rã. Ai biết được, điều này thậm chí còn có thể giúp bạn làm việc hiệu quả hơn khi ở nhà!

  • Số ước số chung lớn nhất của hai số nguyên là số lớn nhất chia cả hai số đó đều cho nhau. Ví dụ: gcd(12, 18) = 6, gcd(−4, 14) = 2. Cách hiệu quả nhất để tính gcd là dùng thuật toán Euclidean. Viết một chương trình có hàm để tính toán gcd cho hai số nguyên. Trước tiên, hãy thử thực hiện hàm mà không cần đệ quy – điều này sẽ giúp bạn hiểu cách thuật toán hoạt động.

    Xác định rõ các nhiệm vụ phụ của bạn, ví dụ: tìm mã cho thuật toán Euclide; tạo một hàm không đệ quy cho thuật toán; v.v. Đây là giải pháp của chúng tôi.

Ví dụ 5: Câu đố toán học

Một trong những sức mạnh của điện toán là có thể thực hiện tìm kiếm brute force một giải pháp cho một vấn đề. Tính năng thử và lỗi vẫn hoạt động hiệu quả đối với một số vấn đề. Trên thực tế, máy tính có thể giải quyết những vấn đề như vậy. Hãy cân nhắc những điều sau:

Ngựa có giá 10 đô la, lợn có giá 3 đô la và thỏ chỉ có 0, 5 đô la. Một người nông dân mua 100 con vật với giá 100 đô la. Anh ấy đã mua bao nhiêu con mỗi con? 

Có một giải pháp cực kỳ đơn giản cho vấn đề này. Hãy xem liệu bạn có thể tìm thấy tài khoản này hay không trước khi xem của chúng tôi.

Mời bạn thử một cách khác:
Có bao nhiêu cách để sắp xếp 6 cuốn sách từ trái sang phải trên một kệ?

Lần này, chúng tôi sẽ chỉ đưa ra giải pháp và cho phép bạn viết chương trình: 720.

Ví dụ 6: Chuỗi cần cân nhắc

Chương trình sau đây tạo ra gì?

#include <iostream>
using namespace std;

int main() {
  string str1 = "To be or not to be, that is the question";
  string str2 = "only ";
  string str3 = str1.substr(6, 12);
  str1.insert(32, str2);
  str1.replace(str1.find("to be", 0), 5, "to jump");
  str1.erase(9, 4);
  cout << str1 << endl;
  for (int i = 0; i < str3.length(); i++)
    cout << str3[i]; cout << endl;
}

Hãy nhấp vào đây để được trợ giúp.

Ví dụ 7: Các bước tiếp theo của quá trình phân ly – Ngày đầu tiên bạn thực hiện công việc

Bạn vừa nhận được vị trí nhân viên bán hàng cho công ty ExerShoe, chuyên về giày thể thao cao cấp có giá khoảng 225 USD một đôi. Sếp của bạn đã đưa ra 3 lựa chọn trả thù lao mà bạn phải chọn trước khi bắt đầu làm việc vào ngày đầu tiên:

  1. Lương cố định 600 USD/tuần;
  2. Lương 7$/giờ, cộng 10% hoa hồng theo doanh số.
  3. Không có tiền lương, nhưng sẽ nhận được 20% tiền hoa hồng và 20 đô la Mỹ cho mỗi đôi giày bán được

Là một lập trình viên C++ chuyên nghiệp, bạn có thể viết một chương trình để giúp đưa ra lựa chọn mức thù lao tốt nhất.

Một phương pháp phổ biến khi phân ly cho một chương trình lớn hơn là tạo một hàm chính có chức năng đọc như đề cương để giải quyết vấn đề. Sau đó, chúng ta viết các hàm để thực hiện từng nhiệm vụ.

Dưới đây là lượt đầu tiên trong chương trình chính:

  GetInput(WeeklySales);
  CalcMethod1(WeeklySales);
  CalcMethod2(WeeklySales);
  CalcMethod3(WeeklySales); 

Hãy xem liệu bạn có thể triển khai từng chức năng này hay không trước khi tìm hiểu giải pháp của chúng tôi.

Ví dụ 8: Sản phẩm nào có sẵn ở đâu?

Kết quả của chương trình sau đây là gì?

// scope.cpp, Maggie Johnson
// Description: A program to illustrate different scopes

#include <iostream>
using namespace std;

int a = 18;
int b = 6;

int function1(int a, int b) {
  return a - b;
}

int function2() {
  int c;
  c = a + b;
  return c;
}

int main() {
  int b = 12;
  int c = 0;
  a = function1(b, a);
  c = function2();
  cout << "a: " << a << " b: " << b << " c: " << c << endl;
}

Khi bạn đã tìm ra câu trả lời, hãy xem phiên bản mã được nhận xét của chúng tôi tại đây.

Ví dụ 9: Xử lý tệp

Quá trình xử lý tệp trong C++ được thực hiện bằng cách sử dụng fstream. Để lưu vào một tệp, chúng ta khai báo một luồng và mở tệp đó bằng chế độ "out". Hãy xem điều này trong ví dụ sau.

// file.cpp, Maggie Johnson
// Description: An illustration of file processing
#include <fstream>
#include <iostream>
using namespace std;

int main() {
  char first_name[30], last_name[30]; int age;
  char file_name[20];
  // Collect the data.
  cout << "Enter First Name: "; cin >> first_name;
  cout << "Enter Last Name: "; cin >> last_name;
  cout << "Enter Age: "; cin >> age;
  cout << endl << "Enter the name of the file: "; cin >> file_name;

  // Create an ofstream called People, open the stream for output.
  ofstream People(file_name, ios::out);
  // Write the output to the stream.
  People << first_name << endl << last_name << endl << age << endl; return 0;
} 
  • Hãy xem liệu bạn có thể tìm ra cách mở tệp vừa tạo và hiển thị dữ liệu hay không.Đây là giải pháp của chúng tôi.
  • Bây giờ, hãy xem liệu bạn có thể sửa đổi chương trình này để cho phép người dùng nhập nhiều bản ghi dữ liệu bằng một vòng lặp hay không. Chúng tôi cũng muốn đọc lại mọi dữ liệu, từng bản ghi một.Đây là giải pháp của chúng tôi.

Bây giờ, bạn đã sẵn sàng tự mình thử một số bài tập thể dục và dự án !

Một kỹ sư phần mềm tại Google sẽ như thế nào

Hãy tìm hiểu về cách làm việc tại Google trên trang web này.

Bài tập và dự án

Các bài tập sau đây sẽ giúp bạn thực hành thêm với C++ cơ bản. Chúng tôi không đưa ra giải pháp cho các bài tập và dự án này vì chúng tôi muốn bạn hợp tác với các học viên khác trong khoá học này.

  1. Tiếng còi thông thường hót tương ứng với nhiệt độ hiện tại. Nếu cộng 40 với thời gian mà một con bóng gậy kêu trong một phút, rồi chia giá trị đó cho 4, chúng ta có được nhiệt độ. Viết một chương trình lấy dữ liệu đầu vào là số chi tiết trong một phút và in nhiệt độ hiện tại. Ví dụ:
    Number of chirps: 120
    The temperature is: 40.0 degrees. 
  2. Viết một chương trình để tính điểm cuối cùng cho khoá học lập trình mà bạn đang tham gia. Dưới đây là sơ đồ chấm điểm:
    Final grades will be based on the following:
    40% Assignments   15% Midterm Examination
    35% Final Examination
    10% Class Participation Grade 

    Chương trình của bạn nên yêu cầu người dùng cho điểm của bốn bài tập, đó là điểm giữa kỳ, điểm cuối kỳ và điểm phần. Sau đó, điểm cuối cùng sẽ được tính toán và in ra. Để tính toán, bạn lấy trung bình cộng của 4 điểm bài tập, sau đó nhân với 0,4 (40%). Sau đó, bạn nhân điểm giữa kỳ với 0,15, điểm tổng kết với 0,35 và điểm tham gia với 0,1. Sau đó, bạn cộng tất cả kết quả của các phép nhân này lại với nhau.

    Sử dụng các hàm ở bất cứ đâu có thể trong chương trình này. Bạn có thể tạo một hàm để nhận dữ liệu đầu vào bằng cách truyền vào dưới dạng tham số mà chuỗi sẽ hiển thị trong bản giải thích. Dưới đây là một ví dụ về lần chạy:

    Enter the score for the first assignment. 75
    Enter the score for the second assignment. 85
    Enter the score for the third assignment. 82
    Enter the score for the fourth assignment. 94
    Enter the score for the midterm. 81
    Enter the score for the final. 89
    Enter the score for the section grade. 100
    The final grade is: 86.9
  3. Vì đồng hồ bấm giờ điện tử ngày càng rẻ hơn và chính xác hơn, nên chắc chắn chúng ta sẽ phải đo lường với các kết quả đo lường thời gian với mức độ chính xác không thể tin được. Viết một chương trình lấy dữ liệu đầu vào trong một khoảng thời gian tính bằng giây, rồi xuất ra số giờ, phút và giây mà chương trình biểu thị. Ví dụ:
    Number of seconds: 3662
    Hours: 1
    Minutes: 1
    Seconds: 2     
  4. Trong phần sau, hãy phân ly trước khi viết chương trình. Hãy dùng các hàm bất cứ khi nào có thể để tạo ra những chương trình có cấu trúc hợp lý.

  5. Giả sử chúng ta muốn in biểu ngữ cho những mục đích sau:

    "

    Chúng ta muốn các chữ cái khá lớn vì đây là biểu ngữ:

    FFFFF
    F
    FFF
    F
    F
    
    EEEEE
    E
    EEE
    E
    EEEEE
    
    , v.v.

    Là một trình phân rã vấn đề hiệu quả, bạn có thể nhận thấy rằng thay vì đặt tất cả các cout vào hàm chính, việc đưa chúng vào các hàm sẽ hiệu quả hơn nhiều. Vì vậy, chúng tôi có thể có hàm "printE" và hàm "printZ", v.v.

    Viết một chương trình có các hàm tạo một biểu ngữ gồm một từ hoặc cụm từ có nhiều chữ cái lặp lại. Một số khả năng:

    FREEZY BREEZE MAKES FLEAS
    SNEEZE TWEETLE BEETLE PADDLE BATTLE
    SIX SICK CHICKS KICK
    SUE SEWS SUE'S SOCKS
    BEN BENDS BIM'S BROOM 
  6. Sau đây là bài toán về "số ma thuật": Hãy yêu cầu người dùng nhập một số có ba chữ số có chữ số đầu tiên lớn hơn chữ số cuối. Chương trình của bạn sẽ đảo ngược số và trừ số đảo ngược từ số ban đầu. Cuối cùng, đảo ngược số thu được và thêm số đó vào dạng không đảo ngược. Xuất kết quả cuối cùng. Số ban đầu mà người dùng nhập phải là số nguyên (không phải ba ký tự). Hãy nghĩ cách viết một hàm lấy một số nguyên làm dữ liệu đầu vào và trả về giá trị đảo ngược của số đó. Ví dụ:
    input number: 901
    reverse it: 109
    subtract: 901 - 109 = 792
    reverse it: 297
    add: 297 + 792 = 1089   
  7. Luật yêu cầu các nhà sản xuất sản phẩm thực phẩm phải đặt ngày hết hạn trên các sản phẩm của họ, nhưng vẫn có một lỗ hổng trong luật: luật này không yêu cầu ngày hết hạn phải dưới bất kỳ hình thức cụ thể nào. Vì vậy, trường hợp này có thể được viết bằng tiếng Swahili và vẫn hợp pháp.

    Nadine, em họ thứ ba của Rar Nader, tự xưng là điệp viên đánh giá chất lượng thực phẩm. Cô biết được rằng nhiều nhà sản xuất sản phẩm thực phẩm đã bắt đầu mã hoá ngày hết hạn của sản phẩm để khiến khách hàng không biết được có tuổi của sản phẩm hay không.

    Tuy nhiên, quy trình mã hoá cho phép các cửa hàng tạp hoá xác định được ngày hết hạn nếu muốn vì lý do nào đó.

    Một phương pháp mã hoá phổ biến:

    • mã hoá các tháng từ tháng 1 đến tháng 12 dưới dạng 'A' đến 'L'
    • mã hoá từng chữ số của ngày dưới dạng "Q" đến "Z"
    • mã hoá năm dưới dạng "A" đến "Z" (nghĩa là từ 1 đến 26, sau đó được thêm vào năm 1995).

    Nadine đã tìm thấy một ổ bánh mì đặc biệt đáng ngờ vào ngày này: ARZM. Viết một chương trình để xác định ngày tháng.

  8. Đây là một con số tương tự như một trò lừa đảo nổi tiếng. Yêu cầu người dùng nhập một số có ba chữ số. Hãy coi số đó là ABC (trong đó A, B, C là ba chữ số của số đó). Bây giờ, hãy tìm phần dư của các số tạo thành bởi ABC, BCA và CAB khi chia cho 11. Chúng tôi sẽ gọi các phần dư này là X, Y, Z. Cộng chúng dưới dạng X+Y, Y+Z, Z+X. Nếu bất kỳ tổng nào là số lẻ, hãy tăng hoặc giảm tổng đó đi 11 (bất kỳ phép toán nào cho ra số dương nhỏ hơn 20; lưu ý nếu tổng bằng 9 thì chỉ cần báo cáo và dừng quá trình). Cuối cùng, hãy chia đôi mỗi tổng. Các chữ số thu được là A, B, C. Viết một chương trình triển khai thuật toán này.

Ứng dụng: Trực quan hoá âm nhạc bằng ảnh động

Các kỹ sư phần mềm tạo ra nhiều ứng dụng thường thú vị và sáng tạo. Trong mỗi học phần của khoá học này, chúng tôi sẽ giới thiệu một ứng dụng do các kỹ sư thiết kế và triển khai, nhằm giúp bạn hiểu tất cả các lĩnh vực mà các kỹ sư làm việc trong đó.

Đây là một ứng dụng thú vị, được xây dựng để trực quan hoá âm nhạc.