131
Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin Tổ tin học Cơ sở 1 CHƯƠNG I: TỔNG QUAN VỀ NGÔN NGỮ C++ I.1 CÁC KHÁI NIỆM CƠ BẢN Nội dung chương này giới thiệu những phần cơ bản của một chương trình C++. Một số ví dụ ñơn giản ñể trình bày cấu trúc các chương trình C++ và cách thức biên dịch chúng. Các khái niệm cơ bản như là hằng, biến, và việc lưu trữ chúng trong bộ nhớ… I.1.1. Lập trình Máy tính số là một công cụ ñể giải quyết hàng loạt các bài toán lớn. Một lời giải cho một bài toán nào ñó ñược gọi là một giải thuật (algorithm), nó mô tả một các bước cần thực hiện ñể giải quyết bài toán Giải thuật ñược diễn giải bằng các thuật ngữ trừu tượng mang tính chất dễ hiểu. Ngôn ngữ thật sự ñược hiểu bởi máy tính là ngôn ngữ máy. Một chương trình ñược viết bằng bất kỳ một ngôn ngữ nào khác thì trước hết cần ñược dịch sang ngôn ngữ máy ñể máy tính có thể hiểu và thực thi nó. Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy ñể viết chương trình. Một sự trừu tượng khác là ngôn ngữ assembly. Nó cung cấp những tên dễ nhớ cho các lệnh và một ký hiệu dễ hiểu hơn cho dữ liệu. Bộ dịch ñược gọi là assembler chuyển ngôn ngữ assembly sang ngôn ngữ máy. Ngay cả những ngôn ngữ assembly cũng khó sử dụng. Những ngôn ngữ cấp cao như C++ cung cấp các ký hiệu thuận tiện hơn nhiều cho việc thi hành các giải thuật. Chúng giúp cho các lập trình viên không phải nghĩ nhiều về các thuật ngữ cấp thấp, và giúp họ chỉ tập trung vào giải thuật. Trình biên dịch (compiler) sẽ ñảm nhiệm việc dịch chương trình viết bằng ngôn ngữ cấp cao sang ngôn ngữ assembly. Mã assembly ñược tạo ra bởi trình biên dịch sau ñó sẽ ñược tập hợp lại ñể cho ra một chương trình có thể thực thi. I.1.2. Một chương trình C++ ñơn giản Ví dụ :xuất ra màn hình dòng chữ Hello World // my first program in C++ #include <conio.h> #include <iostream.h> int main () { cout << "Hello World!"; getch(); return 0; } ðây là chương trình ñơn giản nhưng nó ñã bao gồm những phần cơ bản mà mọi chương trình C++ ñều có. Với ý nghĩa của từng dòng như sau: //Kết quả: Hello World!

CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 1

CHƯƠNG I: TỔNG QUAN VỀ NGÔN NGỮ C++

I.1 CÁC KHÁI NIỆM CƠ BẢN

Nội dung chương này giới thiệu những phần cơ bản của một chương trình C++. Một số ví dụ ñơn giản ñể trình bày cấu trúc các chương trình C++ và cách thức biên dịch chúng. Các khái niệm cơ bản như là hằng, biến, và việc lưu trữ chúng trong bộ nhớ…

I.1.1. Lập trình

Máy tính số là một công cụ ñể giải quyết hàng loạt các bài toán lớn. Một lời giải cho một bài toán nào ñó ñược gọi là một giải thuật (algorithm), nó mô tả một các bước cần thực hiện ñể giải quyết bài toán

Giải thuật ñược diễn giải bằng các thuật ngữ trừu tượng mang tính chất dễ hiểu. Ngôn ngữ thật sự ñược hiểu bởi máy tính là ngôn ngữ máy. Một chương trình ñược viết bằng bất kỳ một ngôn ngữ nào khác thì trước hết cần ñược dịch sang ngôn ngữ máy ñể máy tính có thể hiểu và thực thi nó.

Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy ñể viết chương trình. Một sự trừu tượng khác là ngôn ngữ assembly. Nó cung cấp những tên dễ nhớ cho các lệnh và một ký hiệu dễ hiểu hơn cho dữ liệu. Bộ dịch ñược gọi là assembler chuyển ngôn ngữ assembly sang ngôn ngữ máy.

Ngay cả những ngôn ngữ assembly cũng khó sử dụng. Những ngôn ngữ cấp cao như C++ cung cấp các ký hiệu thuận tiện hơn nhiều cho việc thi hành các giải thuật. Chúng giúp cho các lập trình viên không phải nghĩ nhiều về các thuật ngữ cấp thấp, và giúp họ chỉ tập trung vào giải thuật. Trình biên dịch (compiler) sẽ ñảm nhiệm việc dịch chương trình viết bằng ngôn ngữ cấp cao sang ngôn ngữ assembly. Mã assembly ñược tạo ra bởi trình biên dịch sau ñó sẽ ñược tập hợp lại ñể cho ra một chương trình có thể thực thi.

I.1.2. Một chương trình C++ ñơn giản

Ví dụ :xuất ra màn hình dòng chữ Hello World // my first program in C++ #include <conio.h> #include <iostream.h> int main () { cout << "Hello World!"; getch(); return 0; }

ðây là chương trình ñơn giản nhưng nó ñã bao gồm những phần cơ bản mà mọi chương trình C++ ñều có. Với ý nghĩa của từng dòng như sau:

//Kết quả: Hello World!

Page 2: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 2

// my first program in C++

ðây là dòng chú thích. Tất cả các dòng bắt ñầu bằng hai dấu // ñược coi là chú thích mà nó không ảnh hưởng ñến hoạt ñộng của chương trình, dùng ñể giải thích mã nguồn của chương trình, dòng chú thích thường là một giải thích ngắn gọn những ý nghĩa của dòng lệnh tương ứng.

#include

Các câu bắt ñầu bằng dấu # ñược dùng cho chỉ thị tiền xử lý (preprocessor). Trong ví dụ này, câu lệnh #include báo cho trình dịch biết cần phải "include" thư viện iostream.h là tập tin header chuẩn của C++, chứa các ñịnh nghĩa cho xuất và nhập

int main ()

ðịnh nghĩa hàm main. Hàm main là ñiểm mà tất cả các chương trình C++ bắt ñầu thực hiện. Nó không phụ thuộc vào vị trí của hàm, nội dung của nó luôn ñược thực hiện ñầu tiên khi chương trình thực thi. một chương trình C++ ñều phải tồn tại một hàm main(). Hàm main() có thể có hoặc không có tham số. Nội dung của hàm main tiếp ngay sau phần khai báo chính thức ñược ñặt trong các ngoặc { }.

cout << "Hello World";

ðây là nội dung chính của chương trình. cout là một dòng (stream) output chuẩn trong C++ ñược ñịnh nghĩa trong thư viện iostream.h, khi dong lệnh này ñược thực thi, thì kết quả là xuất kí tự "Hello World" ra màn hình. Dòng lệnh ñược kết thúc bằng dấu chấm phẩy ( ; ).

getch();

Lệnh này tạm dừng màn hình ñể xem kết quả.

return 0;

Lệnh return kết thúc hàm main và trả về mã ñi sau nó, trong trường hợp này là 0. ðây là một kết thúc bình thường của một chương trình không có một lỗi nào trong quá trình thực hiện. Chương trình trên có thể viết lại như sau:

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

cũng cho một kết quả chính xác như nhau.

I.1.3. Các chú thích.

Các chú thích ñược các lập trình viên sử dụng ñể ghi chú hay mô tả trong các phần của chương trình. Trong C++ có hai cách ñể chú thích:

− // Chú thích theo dòng : bắt ñầu từ cặp dấu // cho ñến cuối dòng.

− /* Chú thích theo khối */ : bắt ñầu bằng /* và kết thúc bằng */ Ví dụ:

/* my second program in C++ with more comments */ #include <conio.h> #include <iostream.h> int main ()

Page 3: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 3

{ cout << "Hello World! "; // says Hello World! cout << "I'm a C++ program"; // says I'm a C++ program getch();

return 0; }

Kết quả của chương trình: Hello World! I'm a C++ program

I.2 BIẾN – KIỂU DỮ LIỆU – HẰNG

I.2.1. Identifiers (ðịnh danh)

Một tên (indentifiers) hợp lệ là một gồm các chữ cái, chữ số hoặc kí tự gạch dưới. Chiều dài của một tên là không giới hạn Tên dùng làm tên hằng, tên biến , nhãn , tên hàm.... Ví dụ :

- Tên ñúng : _abc, Delta_1, BETA.

- Tên sai : 1xyz ( vì bắt ñầu là 1 chữ số )

A#B ( vì có dâu #)

X-1 (vì sử dụng dấu gạch ngang).

Tên không ñược chứa khoảng trắng, tên biến luôn phải bắt ñầu bằng một chữ cái, kí tự gạch dưới ( _ ) . Không bắt ñầu bằng một chữ số, các tên không ñược trùng với khoá của ngôn ngữ hay của trình dịch.

I.2.2. Keyword (Từ khóa)

Một số từ ñược giữ bởi C++ cho một số mục ñích riêng và không thể ñược dùng cho các ñịnh danh gọi là từ khóa. Dưới ñây là danh sách từ khoá theo chuẩn ANSI-C++

asm continue float new signed try auto default for operator sizeof typedef break Delete friend private static union case Do goto protected struct unsigned catch double if public switch virtual char Else inline register template void class Enum int return this volatile const extern long short throw while

Ngoài ra, một số biểu diễn khác của các toán tử (operator) cũng không ñược dùng làm tên vì chúng là những từ ñược dành riêng trong một số trường hợp như:

and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor, xor_eq

Trình dịch có thể thêm một từ dành riêng ñặc trưng khác. Ví dụ, rất nhiều trình dịch 16 bit (như các trình dịch cho DOS) còn có các từ khoá far, huge và near.

Page 4: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 4

Chú ý: Ngôn ngữ C++, phân biệt chữ hoa chữ thường. Do vậy biến RESULT khác với result cũng như Result.

I.2.3. Các kiểu dữ liệu

Khi lập trình, ta lưu trữ dữ liệu trong bộ nhớ của máy tính, các kiểu dữ liệu khác nhau sẽ cần dung lượng bộ nhớ khác nhau.

Bộ nhớ của máy tính ñược tổ chức thành các ñơn vị lưu trữ nhỏ nhất là byte. Một byte có thể dùng ñể lưu trữ một loại dữ liệu nhỏ như là kiểu số nguyên từ 0 ñến 255 hay một kí tự.

Tuy nhiên, máy tính có thể xử lý các kiểu dữ liệu phức tạp hơn bằng cách gộp nhiều byte lại với nhau, như số nguyên dài hay số thập phân.

Ngôn ngữ C++ có các kiểu dữ liệu cơ bản: kiểu số nguyên, kiểu số thực.

I.2.3.1. Kiểu số nguyên

Name Description Size Range*

Char Character or small integer.

1byte signed: -128 to 127 unsigned: 0 to 255

Short int (short)

Short Integer. 2bytes signed: -32768 to 32767 unsigned: 0 to 65535

Int Integer. 4bytes signed: -2147483648 to 2147483647 unsigned: 0 to 4294967295

long int (long)

Long integer. 4bytes signed: -2147483648 to 2147483647 unsigned: 0 to 4294967295

I.2.3.2. Kiểu số thực

Name Description Size Range*

float Floating point number. 4bytes 3.4e +/- 38 (7 digits)

Page 5: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 5

double Double precision floating point number.

8bytes 1.7e +/- 308 (15 digits)

long double

Long double precision floating point number.

10bytes 1.2e +/- 4932 (19 digits)

I.2.4. Khai báo biến

Biến ñại lượng thay ñổi, mỗi biến có 1 tên và ñịa chỉ vùng nhớ dành riêng cho nó. ðể có thể sử dụng một biến trong C++, trước hết ta phải khai báo biến. Cú pháp: Ví dụ :

int a; // Khai báo một biến a kiểu int

float mynumber;//khai báo một biến kiểu float với tên mynumber

Nếu khai báo nhiều biến có cùng một kiểu, ta có thể khai báo chúng trên một dòng, ngăn cách các tên bằng dấu phẩy.

Ví dụ int a, b, c; //khai báo ba biến kiểu int (a,b và c) tương ñương với: int a; int b; int c;

Các kiểu số nguyên (char, short, long và int) có thể là số có dấu hay không dấu tuỳ theo miền giá trị mà chúng ta cần biểu diễn. Vì vậy khi xác ñịnh một kiểu số nguyên, ta ñặt từ khoá signed hoặc unsigned trước tên kiểu dữ liệu.

Ví dụ: unsigned short NumberOfSons; signed int MyAccountBalance;

Nếu không chỉ rõ signed hay unsigned thì biến ñó sẽ ñược coi là có dấu, vì vậy trong khai báo thứ hai ta có thể viết lại: int MyAccountBalance, cũng hoàn toàn tương ñương với dòng khai báo ở trên.

Trong thực tế, rất ít khi dùng ñến từ khoá signed. Ngoại lệ duy nhất của luật này là kiểu char. Trong chuẩn ANSI-C++ nó là kiểu dữ liệu khác với signed char và unsigned char.

Ví dụ:

// operating with variables #include <conio.h> #include <iostream.h> int main () { // declaring variables: int a, b; int result;

// process:

< Kiểu dữ liệu > < Danh sách các biến >;

Page 6: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 6

a = 5; b = 2; a = a + 1;

result = a - b; // print out the result: cout << result; // terminate the program:

getch(); return 0;

}

I.2.5. Khởi tạo các biến

Khi khai báo một biến, giá trị mặc ñịnh của biến là không xác ñịnh. Nếu muốn biến mang một giá trị xác ñịnh nào ñó thì phải khởi tạo nó

Cú pháp:

Ví dụ:

int a = 0;

Ngoài ra trong C++ cũng có thể khởi tạo biến bằng cách khác như sau:

type identifier (initial_value) ;

Ví dụ:

int a(0);

I.2.6. Phạm vi hoạt ñộng của các biến

Tất cả các biến sẽ sử dụng trong chương trình ñều phải ñược khai báo trước. Một ñiểm khác biết giữa Cvà C++ là trong C++ có thể khai báo biến ở bất kì vị trí nào trong chương trình, Tuy nhiên ta nên khai báo trước và ñặt nó trong phần bắt ñầu của mỗi hàm (biến cục bộ) hay trực tiếp trong thân chương trình, ngoài tất cả các hàm (biến toàn cục).vì nó sẽ rất hữu dụng khi cần sửa chữa một chương trình có tất cả các phần khai báo ñược gộp lại với nhau.

Biến toàn cục (Global variables ): là biến mà có thể ñược sử dụng ở bất kì ñâu trong chương trình, ngay sau khi nó ñược khai báo.

Biến cục bộ (local variables) :Tầm hoạt ñộng của biến bị giới hạn trong hàm mà nó ñược khai báo. Nếu chúng ñược khai báo ở ñầu một hàm main() thì tầm hoạt ñộng sẽ là toàn bộ hàm main. ðiều ñó có nghĩa là trong ví dụ trên, các biến ñược khai báo trong hàm main() chỉ có thể ñược dùng trong hàm ñó, không ñược dùng ở bất kì ñâu khác.

Ngoài ra còn có các biến ngoài (external). Các biến này không những ñược dùng trong một file mã nguồn mà còn trong tất cả các file ñược liên kết trong chương trình.

Trong C++ tầm hoạt ñộng của một biến chính là khối lệnh mà nó ñược khai báo (một khối lệnh là một tập hợp các lệnh ñược ñặt trong cặp dấu ngoặc nhọn

type identifier = initial_value ;

Page 7: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 7

{ } ). Nếu nó ñược khai báo trong một hàm tầm hoạt ñộng sẽ là hàm ñó, còn nếu ñược khai báo trong vòng lặp thì tầm hoạt ñộng sẽ chỉ là vòng lặp ñó....

I.2.7. Các hằng số (Constants):

I.2.7.1. ðịnh nghĩa:

Hằng là một ñại lượng mà giá trị của nó không ñổi.

I.2.7.2. Phân loại:

Có thể chia ra các loại hằng sau: hằng số nguyên, hằng số thực, hằng chuỗi,…

I.2.7.3. Các hằng số nguyên

− Có giá trị từ -32768 ñến 32767 − Có thể viết theo hệ 16 bằng cách thêm tiền tố Ox − Hoặc theo cơ số 8 bằng cách thêm tiền tố O

Ví dụ : 75 // Cơ số 10 0113 // cơ số 8 0x4b // cơ số 16

O3068 =6 * 80 +0*81 + 3* 82 = 198 trong hệ 10

O3458 = 5*80 +4*81+ 3*82 = 29 trong hệ 10

Ox147 = 7*160 +4*161 + 1*162 =327 trong hệ 10

I.2.7.4. Hằng long int

Giống như hằng số nguyên, chỉ khác thêm L hoặc l ở cuối.

Ví dụ: 75u // unsigned int 75l // long 75ul // unsigned long

I.2.7.5. Các hằng số thập phân (dạng dấu phẩy ñộng)

Hằng thập phân biểu diễn các số với phần thập phân và/hoặc số mũ. Chúng có thể bao gồm phần thập phân và kí tự e (biểu diễn 10 mũ...).

Có 2 cách viết

Cách 1 : dạng thập phân:

phần nguyên, dấu chấm thập phân và phần phân

Ví dụ : 214.35 , - 234.34.

Cách 2 : Viết theo dạng khoa học

Ví dụ : 1.543e7 = 15430000

123.456E-4 = 0.123456 ( 123.456/105)

I.2.7.6. Kí tự và xâu kí tự

Trong C++ còn tồn tại các hằng không phải kiểu số như:

Page 8: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 8

Ví dụ:

'z' 'p' "Hello world" "How do you do?"

Hai biểu thức ñầu tiên biểu diễn các kí tự ñơn, các kí tự ñược ñặt trong dấu nháy ñơn ('), hai biểu thức tiếp theo biểu thức các xâu kí tự ñược ñặt trong dấu nháy kép (").

Khi viết các kí tự ñơn hay các xâu kí tự cần phải ñặ chúng trong các dấu nháy ñể phân biệt với các tên biến hay các từ khoá.

Các kí tự ñơn và các xâu kí tự có một tính chất riêng biệt là các mã ñiều khiển, như là mã xuống dòng (\n) hay tab (\t). Tất cả ñều bắt ñầu bằng dấu xổ ngược (\). Sau ñây là danh sách các mã ñiều khiển ñó:

\n xuống dòng

\r lùi về ñầu dòng

\t kí tự tab

\v căn thẳng theo chiều dọc

\b backspace

\f sang trang

\a Kêu bíp

\' dấu nháy ñơn

\" dấu nháy kép

\ dấu hỏi

\\ kí tự xổ ngược

Ví dụ:

'\n' '\t' "Left \t Right" "one\ntwo\nthree"

Ngoài ra, ñể biểu diễn một mã ASCII, cần sử dụng kí tự xổ ngược (\) tiếp theo ñó là mã ASCII viết trong hệ cơ số 8 hay cơ số 16.

Trường hợp 1: mã ASCII ñược viết ngay sau dấu sổ ngược \

Trường hợp 2: ñể sử dụng số trong hệ cơ số 16 ta cần viết kí tự x trước số ñó

Ví dụ: \x20 hay \x4A

Các hằng kí tự có thể ñược viết trên nhiều dòng nếu mỗi dòng ñược kết thúc bằng một dấu sổ ngược (\)

Ví dụ:

Page 9: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 9

"string expressed in \ two lines"

I.2.8. ðịnh nghĩa các hằng (#define)

ðịnh nghĩa các hằng với tên tùy ý do lập trình viên tự ñặt ñể có thể sử dụng thường xuyên mà không mất tài nguyên cho các biến.

Cú pháp

Ví dụ:

#define PI 3.14159265 #define NEWLINE '\n' #define WIDTH 100

Sau khi ñịnh nghĩa ta có thể sử dụng chúng như bất kì các hằng số nào khác

ví dụ

circle = 2 * PI * r; cout << NEWLINE;

Trong thực tế việc duy nhất mà trình dịch làm khi nó tìm thấy một chỉ thị #define là thay thế các tên hằng tại bất kì chỗ nào chúng xuất hiện (như trong ví dụ trước, PI, NEWLINE hay WIDTH) bằng giá trị mà chúng ñược ñịnh nghĩa. Vì vậy các hằng số #define ñược coi là các hằng số macro

Chỉ thị #define không phải là một lệnh thực thi, nó là chỉ thị tiền xử lý (preprocessor), ñó là lý do trình dịch coi cả dòng là một chỉ thị và dòng ñó không cần kết thúc bằng dấu chấm phẩy. Nếu bạn thêm dấu chấm phẩy vào cuối dòng, nó sẽ ñược coi là một phần của giá trị ñịnh nghĩa hằng.

I.2.9. Khai báo các hằng (const)

Cú pháp: const <kiểu dữ liệu> tên hằng = giá trị

Ví dụ:

const int width = 100; const to char tab = '\t'; const zip = 12440;

Nếu kiểu không ñược chỉ rõ (như trong ví dụ cuối) trình dịch sẽ xem nó là kiểu int

I.3 Các lệnh xuất nhập chuẩn

I.3.1. Lệnh xuất (cout) Cú pháp:

cout trong thư viện iostream.h ñược sử dụng với toán tử << (overloaded) trong ñó biểu thức có thể là hằng, biến, biểu thức.

cout<<biểu thức;

#define identifier value

Page 10: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 10

Ví dụ: cout << "Output sentence"; // Hiển thị Output sentence lên màn hình cout << 120; // Hiển thị số 120 lên màn hình cout << x; // Hiển thị nội dung biến x lên màn hình

− Toán tử << ñược gọi là toán tử chèn vì nó chèn dữ liệu ñi sau nó vào dòng dữ liệu ñứng trước. Trong ví dụ trên nó chèn "Output sentence", hằng số 120 và biến x vào dòng dữ liệu ra cout.

− Toán tử chèn (<<) có thể ñược sử dụng nhiều lần trong một câu lệnh:

Ví dụ:

cout << "Hello, "<<" I am "<<"a C++ sentence";

Câu lệnh trên sẽ in thông báo Hello, I am a C++ sentence lên màn hình. Sự tiện lợi của việc sử dụng lặp lại toán tử chèn (<<) thể hiện rõ khi chúng ta muốn hiển thị nhiều biến và hằng.

Ví dụ: cout << "Hello, I am "<<age<<"years old and my email address is " << email_add;

− cout không nhảy xuống dòng sau khi xuất dữ liệu, vì vậy hai câu lệnh sau :

cout << "This is a sentence.";

cout << "This is another sentence.";

sẽ ñược hiển thị trên màn hình:

This is a sentence.This is another sentence.

− Vì vậy khi muốn xuống dòng chúng ta phải sử dụng kí tự xuống dòng, trong C++ là: \n

Ví dụ: cout << "First sentence.\n ";

cout << "Second sentence.\nThird sentence.";

Kết quả trên màn hình như sau:

First sentence.

Second sentence.

Third sentence.

− Ngoài ra, ñể xuống dòng ta có thể sử dụng endl.

Ví dụ

cout << "First sentence." << endl;

cout << "Second sentence." << endl;

sẽ in ra màn hình:

First sentence.

Second sentence.

− endl có một tác dụng ñặc biệt khi nó ñược dùng với các dòng dữ liệu sử dụng bộ ñệm: các bộ ñệm sẽ ñược flushed (chuyển toàn bộ thông tin từ bộ

Page 11: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 11

ñệm ra dòng dữ liệu). Tuy nhiên, theo mặc ñịnh cout không sử dụng bộ ñệm.

I.3.2. Nhập dữ liệu (cin)

Thao tác nhập chuẩn trong C++ ñược thực hiện bằng cách sử dụng toán tử >> với dòng cin (trong thư viện iostream.h) Theo sau toán tử này là biến sẽ lưu trữ dữ liệu ñược ñọc vào.

Cú pháp:

Ví dụ:

Int age;

cin >> age;

Khai báo biến age có kiểu int và ñợi nhập dữ liệu từ cin (bàn phím) ñể lưu trữ nó trong biến kiểu nguyên này.

cin chỉ bắt ñầu xử lý dữ liệu nhập từ bàn phím sau khi phím Enter ñược gõ. Vì vậy dù bạn chỉ nhập một kí tự thì cin vẫn sẽ chờ cho ñến khi bạn gõ phím Enter.

Người sử dụng chương trình có thể là một trong những nguyên nhân gây ra lỗi trong một chương trình ñơn giản sử dụng cin. Trong khi bạn muốn nhận một số nguyên thì người sử dụng lại nhập vào một xâu kí tự. Kết quả là chương trình sẽ chạy sai vì ñó không phải là những gì mà chương trình mong ñợi từ người dùng.

Vì vậy khi bạn sử dụng dữ liệu nhập vào từ cin bạn phải tin chắc rằng người dùng sẽ hoàn toàn hợp tác và rằng anh ta sẽ không nhập tên của mình khi chương trình yêu cầu nhập số nguyên.

Có thể dùng cin ñể nhập một lúc nhiều dữ liệu từ người dùng.

Ví dụ:

cin >> a >> b;

tương ñương với

cin >> a; cin >> b;

Trong cả hai trường hợp người sử dụng phải cung cấp hai dữ liệu, một cho biến a và một cho biến b và ñược ngăn cách bởi một dấu trống hợp lệ: một dấu cách, dấu tab hay kí tự xuống dòng.

I.3.3. Lệnh nhập trong ngôn ngữ C: hàm scanf (ñọc thêm)

Là hàm cho phép ñọc dữ liệu từ bàn phím và gán cho các biến trong chương trình khi chương trình thực thi. Trong ngôn ngữ C, ñó là hàm scanf() nằm trong thư viện stdio.h.

Cú pháp:

cin>>tên biến;

scanf(“ ñịnh dạng”, ñịa chỉ của các biến);

Page 12: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 12

Giải thích: - ñịnh dạng: dùng ñể qui ñịnh kiểu dữ liệu, cách biểu diễn, ñộ rộng, số

chữ số thập phân... Một số ñịnh dạng khi nhập kiểu số nguyên, số thực, ký tự.

- Các ñịnh dạng: %[số ký số]d :Nhập số nguyên có tối ña <số ký số> %[số ký số] f :Nhập số thực có tối ña <số ký số> tính cả dấu chấm %c : Nhập một ký tự

Ví dụ: %d : Nhập số nguyên %4d : Nhập số nguyên tối ña 4 ký số, nếu nhập nhiều hơn 4 ký số thì chỉ

nhận ñược 4 ký số ñầu tiên %f : Nhập số thực %6f : Nhập số thực tối ña 6 ký số (tính luôn dấu chấm), nếu nhập nhiều

hơn 6 ký số thì chỉ nhận ñược 6 ký số ñầu tiên (hoặc 5 ký số với dấu chấm)

- ðịa chỉ của các biến: là ñịa chỉ (&) của các biến mà ta cần nhập giá trị cho nó. ðược viết như sau: &<tên biến>.

Ví dụ: scanf(“%d”,&bien1);/*Doc gia tri cho bien1 co kieu nguyen*/ scanf(“%f”,&bien2); /*Doc gia tri cho bien2 co kieu thưc*/ scanf(“%d%f”,&bien1,&bien2);

I.3.4. Lệnh xuất trong ngôn ngữ C: hàm printf (ñọc thêm)

Hàm printf (trong thư viện stdio.h) dùng ñể xuất giá trị của các biểu thức lên màn hình.

Cú pháp:

Giải thích: - ñịnh dạng: dùng ñể qui ñịnh kiểu dữ liệu, cách biểu diễn, ñộ rộng, số chữ

số thập phân... Một số ñịnh dạng khi ñối với số nguyên, số thực, ký tự. - Các ñịnh dạng:

ðịnh dạng Kiểu dữ liệu Công dụng %c char Xuất một ký tự có mã ASCII tương ứng %[n]d int Xuất một số nguyên có chiều dài tối ña n %[n]ld long int Xuất một số nguyên dài có chiều dài tối ña n

%[n]u int Xuất một số nguyên ở hệ 10 không dấu có

chiều dài tối ña n

%[n]o int Xuất một số nguyên ở hệ 8 tương ứng không

dấu có chiều dài tối ña n

%[n]x int Xuất một số nguyên ở hệ 16 tương ứng

không dấu có chiều dài tối ña n %[n.m]f float Xuất một số thực có chiều dài tối ña n và

printf(“ ñịnh dạng ”, Các biểu thức);

Page 13: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 13

làm tròn m chữ số phần thập phân %s char Xuất nhiều ký tự (một chuỗi ký tự) %e %E %g %G

Xuất số nguyên dạng khoa học

Ví dụ: %d // In ra số nguyên %4d //In số nguyên tối ña 4 ký số, nếu số cần in nhiều hơn 4 ký số thì in hết %f //In số thực %6f // In số thực tối ña 6 ký số (tính luôn dấu chấm), nếu số cần in nhiều hơn 6 ký số thì in hết Ví dụ:

include<stdio.h> void main() {

int bien_nguyen=1234, i=65; float bien_thuc=123.456703; printf(“Gia tri nguyen cua bien nguyen =%d\n”,bien_nguyen); printf(“Gia tri thuc cua bien thuc =%f\n”,bien_thuc); printf(“Truoc khi lam tron=%f \n Sau khi lam tron=%.2f”,bien_thuc, bien_thuc);

}

I.3.5. ðịnh dạng kết quả xuất:

Khi xuất dữ liệu ra màn hình, ñôi khi ta cần ñịnh dạng theo một yêu cầu nào ñó. Ngôn ngữ C++, cung cấp cho người lập trình một số cách ñể ñịnh dạng dữ liệu xuất như sau:

• setw(n): ấn ñịnh ñộ rộng ñể in một số là n • setprecision(n): ấn ñịnh số chữ số thập phân sẽ hiển thị. • dec: hiển thị giá trị số ở hệ thập phân • hec: hiển thị giá trị số ở hệ thập lục phân • oct : hiển thị giá trị số ở hệ bát phân

Ví dụ:

#include <iostream.h> #include <iomanip.h> void main() { cout <<setw(5)<<12; //kết quả “...12” cout <<setw(10)<<hex <<15 // kết quả f cout <<oct <<10; // kết quả 12 cout <<dec <<0x10; // kết quả 16

return; }

Page 14: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 14

I.4 Cấu trúc của một chương trình C++

I.4.1. Tiền xử lý và biên dịch

Trong C/C++, việc dịch (translation) một tập tin nguồn ñược tiến hành trên hai bước hoàn toàn ñộc lập với nhau:

- Tiền xử lý.

- Biên dịch.

Hai bước này trong phần lớn thời gian ñược nối tiếp với nhau một cách tự ñộng mà ta có cảm giác rằng nó ñã ñược thực hiện như là một xử lý duy nhất.

Nói chung, việc tồn tại của một bộ tiền xử lý (preprocessor?) nhằm chỉ rõ chương trình thực hiện việc xử lý trước.

Bước tiền xử lý tương ứng với việc cập nhật trong văn bản của chương trình nguồn, chủ yếu dựa trên việc diễn giải các mã lệnh rất ñặc biệt gọi là các chỉ thị dẫn hướng của bộ tiền xử lý (destination directive of preprocessor); các chỉ thị này ñược nhận biết bởi chúng bắt ñầu bằng ký hiệu #.

Hai chỉ thị quan trọng nhất là: - Chỉ thị sự gộp vào của các tập tin nguồn khác: #include - Chỉ thị việc ñịnh nghĩa các macros hoặc ký hiệu: #define

Chỉ thị thứ nhất ñược sử dụng trước hết là nhằm gộp vào nội dung của các tập tin cần có (header file), không thể thiếu trong việc sử dụng một cách tốt nhất các hàm của thư viện chuẩn, phổ biến nhất là:

#include <stdio.h> hoặc #include<iostream.h>

Chỉ thị thứ hai rất hay ñược sử dụng trong các tập tin thư viện (header file) ñã ñược ñịnh nghĩa trước ñó và thường ñược khai thác bởi các lập trình viên trong việc ñịnh nghĩa các ký hiệu như là:

#define NB_COUPS_MAX 100 #define SIZE 25

I.4.2. Cấu trúc một chương trình C++

Một chương trình C/C++ bao gồm các phần như: Các chỉ thị tiền xử lý, khai báo biến ngoài, các hàm tự tạo, chương trình chính (hàm main).

Cấu trúc có thể như sau:

Các chỉ thị tiền xử lý (Preprocessor directives) #include <Tên tập tin thư viện> #define …

ðịnh nghĩa kiểu dữ liệu (phần này không bắt buộc): dùng ñể ñặt tên lại cho một kiểu dữ liệu nào ñó ñể gợi nhớ hay ñặt 1 kiểu dữ liệu cho riêng mình dựa trên các kiểu dữ liệu ñã có. Cú pháp: typedef <Tên kiểu cũ> <Tên kiểu mới> Ví dụ: typedef int SoNguyen; // Kiểu SoNguyen là kiểu int

Page 15: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 15

I.4.3. Các tập tin thư viện thông dụng

ðây là các tập tin chứa các hàm thông dụng khi lập trinh C/C++, muốn sử dụng các hàm trong các tập tin header này thì phải khai báo #include <Tên tập tin> ở phần ñầu của chương trình

1) stdio.h hoặc iostream.h (C++) Tập tin ñịnh nghĩa các hàm vào/ra chuẩn (standard input/output). Gồm các hàm in dữ liệu (printf())/cout, nhập giá trị cho biến (scanf())/cin, nhận ký tự từ bàn phím (getc()), in ký tự ra màn hình (putc()), nhận một dãy ký tự từ bàm phím (gets()), in ký tự ra màn hình (puts()), xóa vùng ñệm bàn phím (fflush()), fopen(), fclose(), fread(), fwrite(), getchar(), putchar(), getw(), putw()…

2) conio.h : Tập tin ñịnh nghĩa các hàm vào ra trong chế ñộ DOS (DOS console). Gồm các hàm clrscr(), getch(), getche(), getpass(), cgets(), cputs(), putch(), clreol(),…

3) math.h: Tập tin ñịnh nghĩa các hàm tính toán gồm các hàm abs(), sqrt(), log(). log10(), sin(), cos(), tan(), acos(), asin(), atan(), pow(), exp(),…

Khai báo các prototype (tên hàm, các tham số, kiểu kết quả trả về,… của các hàm sẽ cài ñặt trong phần sau, phần này không bắt buộc): phần này chỉ là các khai báo ñầu hàm, không phải là phần ñịnh nghĩa hàm.

Khai báo các biến ngoài (các biến toàn cục) phần này không bắt buộc: phần này khai báo các biến toàn cục ñược sử dụng trong cả chương trình.

Chương trình chính phần này bắt buộc phải có <Kiểu dữ liệu trả về> main() {

Các khai báo cục bộ trong hàm main: Các khai báo này chỉ tồn tại trong hàm mà thôi, có thể là khai báo biến hay khai báo kiểu. Các câu lệnh dùng ñể ñịnh nghĩa hàm main return <kết quả trả về>; // Hàm phải trả về kết quả

}

Cài ñặt các hàm <Kiểu dữ liệu trả về> function1( các tham số) {

Các khai báo cục bộ trong hàm. Các câu lệnh dùng ñể ñịnh nghĩa hàm return <kết quả trả về>;

} …

Page 16: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 16

4) alloc.h: Tập tin ñịnh nghĩa các hàm liên quan ñến việc quản lý bộ nhớ. Gồm các hàm calloc(), realloc(), malloc(), free(), farmalloc(), farcalloc(), farfree(), …

5) io.h: Tập tin ñịnh nghĩa các hàm vào ra cấp thấp. Gồm các hàm open(), _open(), read(), _read(), close(), _close(), creat(), _creat(), creatnew(), eof(), filelength(), lock(),…

6) graphics.h: Tập tin ñịnh nghĩacác hàm liên quan ñến ñồ họa. Gồm initgraph(), line(), circle(), putpixel(), getpixel(), setcolor(), …

Còn nhiều tập tin khác nữa.

Page 17: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 17

CHƯƠNG II: BIỂU THỨC (Expression)

II.1 GIỚI THIỆU Chương này giới thiệu các toán tử xây dựng sẵn cho việc soạn thảo các biểu thức. Một biểu thức là bất kỳ sự tính toán nào mà cho ra một giá trị. Biểu thức là một sự kết hợp giữa các toán tử (operator) và các toán hạng (operand) theo ñúng một trật tự nhất ñịnh. Mỗi toán hạng có thể là một hằng, một biến hoặc một biểu thức khác. Khi thảo luận về các biểu thức, ta thường sử dụng thuật ngữ ước lượng. Ví dụ, chúng ta nói rằng một biểu thức ước lượng một giá trị nào ñó. Thường thì giá trị sau cùng chỉ là lý do cho việc ước lượng biểu thức. Tuy nhiên, trong một vài trường hợp, biểu thức cũng có thể cho các kết quả phụ. Các kết quả này là sự thay ñổi lâu dài trong trạng thái của chương trình. Trong trường hợp này, các biểu thức C++ thì khác với các biểu thức toán học. C++ cung cấp các toán tử cho việc soạn thảo các biểu thức toán học, quan hệ, luận lý, trên bit, và ñiều kiện. Nó cũng cung cấp các toán tử cho ra các kết quả phụ hữu dụng như là gán, tăng, và giảm. Chương này lần lượt giới thiệu từng loại toán tử, luật ưu tiên mà nó ảnh hưởng ñến thứ tự ước lượng của các toán tử trong một biểu thức có nhiều tóan tử.

II.2 TOÁN TỬ

II.2.1. Toán tử gán (assignment operator):

Toán tử gán dùng ñể gán một giá trị nào ñó cho một biến

Ví dụ: a = 5; //Gán giá trị nguyên 5 cho biến a.

− Vế trái bắt buộc phải là một biến còn vế phải có thể là bất kì hằng, biến hay kết quả của một biểu thức. Toán tử gán luôn ñược thực hiện từ trái sang phải.

Ví dụ: a = b; //gán giá trị của biến a bằng giá trị ñang chứa trong biến b.

− Chú ý rằng chúng ta chỉ gán giá trị của b cho a và sự thay ñổi của b sau ñó sẽ không ảnh hưởng ñến giá trị của a.

− Một thuộc tính của toán tử gán trong C++ góp phần giúp nó vượt lên các ngôn ngữ lập trình khác là việc cho phép vế phải có thể chứa các phép gán khác.

Ví dụ:

a = 2 + (b = 5);

tương ñương với

b = 5; a = 2 + b;

Vì vậy biểu thức sau cũng hợp lệ trong C++

a = b = c = 5; //gán giá trị 5 cho cả ba biến a, b và c

Page 18: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 18

II.2.2. Các toán tử số học (number operator)

Trong ngôn ngữ C/C++, các toán tử +, -, *, / làm việc tương tự như khi chúng làm việc trong các ngôn ngữ khác. Ta có thể áp dụng chúng cho ña số kiểu dữ liệu có sẵn ñược cho phép bởi C. Khi ta áp dụng phép / cho một số nguyên hay một ký tự, bất kỳ phần dư nào cũng bị cắt bỏ. Chẳng hạn, 5/2 bằng 2 trong phép chia nguyên.

Toán tử Tên Ví dụ

+ Cộng 12 + 4.9 // kết quả 16.9

- Trừ 3.98 - 4 // kết quả -0.02

* Nhân 2 * 3.4 // kết quả 6.8

/ Chia (chia nguyên) 9 / 2.0 // kết quả 4.5

% Lấy phần dư 13 % 3 // kết quả 1

− Trừ toán tử lấy phần dư (% ) thì tất cả các toán tử số học có thể chấp nhận pha trộn các toán hạng số nguyên và toán hạng số thực.

• Nếu cả hai toán hạng là số nguyên thì kết quả sẽ là một số nguyên. • Một hoặc cả hai toán hạng là số thực thì kết quả sẽ là một số thực (real

hay double)

II.2.3. Các toán tử gán phức hợp (complex operator)

Một ñặc tính của ngôn ngữ C++ làm cho nó nổi tiếng là một ngôn ngữ súc tích chính là các toán tử gán phức hợp cho phép chỉnh sửa giá trị của một biến với một trong những toán tử cơ bản sau:

Toán Tử Ví dụ Tương ñương với

+= n += 25 n = n + 25

-= n -= 25 n = n – 25

*= n *= 25 n = n * 25

/= n /= 25 n = n / 25

%= n %= 25 n = n % 25

Ví dụ:

#include <iostream.h> int main () {

int a, b=3; a = b; a+=2; //tương ñương với a=a+2 cout << a; return 0;

}

Page 19: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 19

II.2.4. Tóan tử tăng và giảm (increase/descrease operator)

− Toán tử tăng (++) và toán tử giảm (--) có tác dụng làm tăng hoặc giảm 1 giá trị lưu trong biến. Chúng tương ñương với +=1 hoặc -=1. Vì vậy, các dòng sau là tương ñương:

a++; a+=1; a=a+1;

− Toán tử tăng/giảm có 2 dạng: Tiền tố :++a Hậu tố: a++

Trường hợp toán tử ñược sử dụng như là một tiền tố ++a: giá trị của a tăng trước khi biểu thức ñược tính và giá trị ñã tăng ñược sử dụng trong biểu thức Trong trường hợp toán tử ñược sử dụng như là một hậu tố a++ : giá trị trong biến a ñược tăng sau khi ñã tính toán. Ví dụ 1:

B=3; A=++B; Kết quả: A chứa giá trị 4, B chứa giá trị 4

Ví dụ 2: B=3;

A=B++;

Kết quả: A chứa giá trị 3, B chứa giá trị 4

II.2.5. Toán tử quan hệ (relation operator):

ðể có thể so sánh hai biểu thức với nhau ta sử dụng các toán tử quan hệ. Theo chuẩn ANSI-C++ thì giá trị của thao tác quan hệ chỉ có thể là giá trị logic - chúng chỉ có thể có giá trị true hoặc false, tuỳ theo biểu thức kết quả là ñúng hay sai.

Toán tử Tên Ví dụ

== So sánh bằng 5 == 5 // kết quả 1

!= So sánh không bằng 5 != 5 // kết quả 0

< So sánh nhỏ hơn 5 < 5.5 // kết quả 1

<= So sánh nhỏ hơn hoặc bằng 5 <= 5 // kết quả 1

> So sánh lớn hơn 5 > 5.5 // kết quả 0

>= So sánh lớn hơn hoặc bằng 6.3 >= 5 //kết quả1

− Các toán hạng của một toán tử quan hệ phải ước lượng về một số. Các

ký tự là các toán hạng hợp lệ vì chúng ñược ñại diện bởi các giá trị số. Ví dụ :

'A' < 'F' // kết quả là 1 //(tương ñương với 65 < 70)

Page 20: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 20

II.2.6. Toán tử logic (logic operator):

Toán tử Ý nghĩa Ví dụ

! Phủ ñịnh !(5 == 5) // kết quả là 0

&& và 5 < 6 && 6 < 6 // kết quả là 0

|| Hoặc 5 < 6 || 6 < 5 // kết quả là 1

Toán tử ! tương ñương với toán tử logic NOT, chỉ có một ñối số ở phía bên phải và có tác dụng làm là ñổi ngược giá trị của ñối số từ true sang false hoặc ngược lại.

Toán tử logic && và || ñược sử dụng khi tính toán hai biểu thức ñể lấy ra một kết quả duy nhất. Chúng tương ứng với các toán tử logic AND và OR. Kết quả của chúng phụ thuộc vào mối quan hệ của hai ñối số.

ðối số thứ nhất a

ðối số thứ hai b

Kết quả a && b

Kết quả a || b

true true true true

true false false true

false true false true

false false false false

II.2.7. Toán tử ñiều kiện (condition operator):

Toán tử ñiều kiện yêu cầu 3 toán hạng. Cú pháp:

− E1 ñược ước lượng ñầu tiên và ñược xem như là một ñiều kiện. Nếu kết quả là 1 (true) thì E2 ñược ước lượng và giá trị của nó là kết quả sau cùng. Ngược lại, E3 ñược ước lượng và giá trị của nó là kết quả sau cùng.

Ví dụ: X = 10 Y = X > 9 ? 100 : 200

− Phép toán ñiều kiện cũng là một biểu thức nên nó có thể ñược sử dụng như một toán hạng của phép toán ñiều kiện khác.

Ví dụ: int m = 1, n = 2, p =3; int min =(m<n ? (m<p ? m:p):(n<p ? n:p));

II.2.8. Toán tử lấy kích thước (size operator)

E 1 ? E 2 : E 3

Sizeof(data_Type)

Page 21: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 21

Chức năng: dùng ñể tính kích thước của bất kỳ hạng mục dữ liệu hay kiểu dữ liệu nào. Kết quả trả về là kích thước của kiểu dữ liệu ñã chỉ ñịnh theo byte.

Ví dụ: #include <iostream.h> void main (void) {

cout << "char size = " << sizeof(char) << " bytes\n"; cout << "char* size = " << sizeof(char*) << " bytes\n";

cout << "short size = " << sizeof(short) << " bytes\n"; cout << "int size = " << sizeof(int) << " bytes\n";

cout << "long size = " << sizeof(long) << " bytes\n";

cout << "float size = " << sizeof(float) << " bytes\n";

cout << "double size = " << sizeof(double) << " bytes\n";

cout << "1.55 size = " << sizeof(1.55) << " bytes\n"; cout << "1.55L size = " << sizeof(1.55L) << " bytes\n";

cout << "HELLO size = " << sizeof("HELLO") << " bytes\n"; }

Kết quả: char size = 1 bytes

char* size = 2 bytes

short size = 2 bytes int size = 2 bytes

long size = 4 bytes

float size = 4 bytes

double size = 8 bytes 1.55 size = 8 bytes

1.55L size = 10 bytes

HELLO size = 6 bytes

II.2.9. Toán tử BITWISE (Bit operator) Các toán tử Bitwise ý nói ñến kiểm tra, gán hay sự thay ñổi các Bit thật sự trong 1 Byte của Word, mà trong C chuẩn là các kiểu dữ liệu và biến char, int. Ta không thể sử dụng các toán tử Bitwise với dữ liệu thuộc các kiểu float, double, long double, void hay các kiểu phức tạp khác

Toán tử Tên Ví dụ

~ Phủ ðịnh Bit ~'\011' // ñược '\366'

& Và bit '\011' & '\027‘ // ñược '\001'

| Hoặc bit '\011' | '\027‘ // ñược '\037'

^ Hoặc exclusive bit '\011' ^ '\027‘ // ñược '\036'

<< Dịch trái bit '\011' << 2 // ñược '\044'

>> Dịch phải bit '\011' >> 2 // ñược '\002'

Page 22: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 22

− Phủ ñịnh bit(~) là một toán tử ñơn hạng thực hiện ñảo các bit trong toán hạng của nó.

− Và bit(&): so sánh các bit tương ứng của các toán hạng của nó và cho kết quả là 1 khi cả hai bit là 1, ngược lại là 0.

− Hoặc bit(|): so sánh các bit tương ứng của các toán hạng của nó và cho kết quả là 0 khi cả hai bit là 0, ngược lại là 1.

− XOR bit(^): so sánh các bit tương ứng của các toán hạng của nó và cho kết quả 0 khi cả hai bit là 1 hoặc cả hai bit là 0, ngược lại là 1.

− Toán tử dịch trái bit và dịch phải bit: lấy một bit làm toán hạng trái của chúng và một số nguyên dương n làm toán hạng phải.

o Toán tử dịch trái cho kết quả là một bit sau khi thực hiện dịch n bit trong bit của toán hạng trái về phía trái.

o Toán tử dịch phải cho kết quả là một bit sau khi thực hiện dịch n bit trong bit của toán hạng trái về phía phải. Các bit trống sau khi dịch ñược ñặt tới 0.

Ví dụ : 105 & 7 = 1// 01101001 & 0000 0111= 00000001

105 | 7 = 127//01101001 | 0000 0111= 01101111 0x60 = 0x96 /* 0110 1001 = 1001 0110 */

II.2.10. Toán tử con trỏ & và * (pointer operator)

Một con trỏ là ñịa chỉ trong bộ nhớ của một biến. Một biến con trỏ là một biến ñược khai báo riêng ñể chứa một con trỏ ñến một ñối tượng của kiểu ñã chỉ ra nó. Ta sẽ tìm hiểu kỹ hơn về con trỏ trong chương về con trỏ. Trong phần này chỉ ñề cập ngắn gọn ñến hai toán tử ñược sử dụng ñể thao tác với các con trỏ.

Toán tử &: là một toán tử quy ước trả về ñịa chỉ bộ nhớ của hệ số của nó.

Ví dụ: m = &count

− ðặt vào biến m ñịa chỉ bộ nhớ của biến count.Chẳng hạn, biến count ở vị trí bộ nhớ 2000, giả sử count có giá trị là 100. Sau câu lệnh trên m sẽ nhận giá trị 2000.

Toán tử *: là một bổ sung cho &; ñây là một toán tử quy ước trả về giá trị của biến ñược cấp phát tại ñịa chỉ theo sau ñó.

Ví dụ: q = *m

− Sẽ ñặt giá trị của count vào q. Bây giờ q sẽ có giá trị là 100 vì 100 ñược lưu trữ tại ñịa chỉ 2000

II.3 CHUYỂN ðỔI KIỂU DỮ LIỆU: Một giá trị thuộc về những kiểu xây dựng sẵn mà chúng ta biết ñến thời ñiểm này ñều có thể ñược chuyển về bất kỳ một kiểu nào khác. Cách cơ bản nhất ñược thừa kế từ ngôn ngữ C là :

(Kiểu dữ liệu)<biểu thức>

Page 23: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 23

Ví dụ: (int) 3.14 // chuyển 3.14 sang int ñể ñược 3 (long) 3.14 // chuyển 3.14 sang long ñể ñược 3L (double) 2 // chuyển 2 sang double ñể ñược 2.0 (char) 122 // chuyển 122 sang char có mã là 122 (unsigned short) 3.14 // ñược 3 như là một unsigned short

Các kiểu xây dựng sẵn có thể ñược sử dụng như các toán tử kiểu. Các toán tử kiểu là ñơn hạng (chỉ có một toán hạng) và xuất hiện bên trong các dấu ngoặc về bên trái toán hạng của chúng. ðiều này ñược gọi là chuyển kiểu tường minh. Khi tên kiểu chỉ là một từ thì có thể ñặt dấu ngoặc xung quanh toán hạng

Ví dụ: int(3.14) // như là: (int) 3.14

Trong một vài trường hợp, C++ cũng thực hiện chuyển kiểu không tường minh khi các giá trị của các kiểu khác nhau ñược trộn lẫn trong một biểu thức.

Ví dụ: double d = 1; // d nhận 1.0 int i = 10.5; // i nhận 10 i = i + d; // nghĩa là: i = int(double(i) + d)

Trong ví dụ cuối, i + d bao hàm các kiểu không hợp nhau, vì thế trước hết, i ñược chuyển thành double (thăng cấp) và sau ñó ñược cộng vào d. Kết quả là double không hợp kiểu với i trên phía trái của phép gán, vì thế nó ñược chuyển thành int (hạ cấp) trước khi ñược gán cho i.

II.4 ðỘ ƯU TIÊN CỦA CÁC TOÁN TỬ: Thứ tự các toán tử ñược thực hiện trong một biểu thức là rất quan trọng, và ñược xác ñịnh theo các luật ưu tiên. Các luật này chia các toán tử trong C++ ra thành các mức ñộ ưu tiên khác nhau. Các toán tử ở mức cao sẽ có ñộ ưu tiên cao hơn so với các toán tử có ñộ ưu tiên thấp hơn.

Toán tử ðộ ưu tiên ( ) 1 !, ++, --, sizeof() 2 *, /, % 3 +, - 4 <<, >> 5 <, <=, >, >= 6 = =, != 7 ( ) 1 & 8 ^ 9 | 10 && 11 || 12 ? : 13 =, +=, -=, *=, /= 14

Page 24: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 24

Ví dụ: Trong biểu thức: a = = b + c * d

• c * d ñược ước lượng trước vì toán tử * có ñộ ưu tiên cao hơn toán tử + và = =.

• Sau ñó kết quả ñược cộng tới b vì toán tử + có ñộ ưu tiên cao hơn toán tử = =

• Sau cùng toán tử = = ñược ước lượng. − Các luật ưu tiên có thể ñược cho quyền cao hơn thông qua việc sử dụng

các dấu ngoặc. Ví dụ: Biểu thức trên ñược viết lại như sau

a == (b + c) * d

• Làm cho toán tử + ñược ước lượng trước toán tử *. − Các toán tử với cùng mức ñộ ưu tiên ñược ước lượng theo thứ tự ước

lượng là từ phải sang trái

Ví dụ: Trong biểu thức

a = b += c

vì thế b += c ñược ước lượng trước và kế ñó là a = b.

Nếu muốn viết một biểu thức phức tạp mà lại không chắc lắm về thứ tự ưu tiên của các toán tử thì nên sử dụng các ngoặc ñơn, thực hiện ñiều này vì nó sẽ giúp chương trình dễ ñọc hơn.

Page 25: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 25

Bài tập 1. Nhập bán kính ñường tròn r. Tính và xuất chu vi, diện tích ñường tròn tương ứng.

(Hướng dẫn: cv=2*ππππ*r và dt=ππππ*r2

- Dùng ππππ=3.14,

- hoặc khai báo hằng PI,

- hoặc dùng hằng M_PI trong thư viện <math.h> của ngôn ngữ lập trình)

Cách 1: dùng ππππ=3.14

//Phan khai bao thu vien

#include<conio.h>

#include<iostream.h>

void main()

{

clrscr(); //Lenh xoa man hinh

//Phan khai bao bien

float r,cv,dt;

//Phan nhap du lieu

cout<<"Ban hay nhap ban kinh duong tron: ";

cin>>r;

//Phan xu ly tinh toan

cv = 2*3.14*r;

dt = 3.14*r*r;

//Phan xuat du lieu

cout<<"Chu vi duong tron ban kinh "<<r<<" la "<< cv;

cout<<endl;

cout<<"Dien tich duong tron ban kinh "<<r<<" la "<<dt;

getch(); //Lenh dung man hinh

}

Cách 2: dùng hằng PI tự ñịnh nghĩa

//Phan khai bao thu vien

#include<conio.h>

#include<iostream.h>

//Phan khai bao hang so

const float PI=3.14159264;

void main()

{

Page 26: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 26

clrscr(); //Lenh xoa man hinh

//Phan khai bao bien

float r,cv,dt;

//Phan nhap du lieu

cout<<"Ban hay nhap ban kinh duong tron: ";

cin>>r;

//Phan xu ly tinh toan

cv = 2*PI*r;

dt = PI*r*r;

//Phan xuat du lieu

cout<<"Chu vi duong tron ban kinh "<<r<<" la "<< cv<<endl;

cout<<"Dien tich duong tron ban kinh "<<r<<" la "<<dt;

getch(); //Lenh dung man hinh

}

Cách 3: dùng hằng M_PI do ngôn ngữ lập trình cung cấp sẵn trong thư viện math.h

//Phan khai bao thu vien

#include<conio.h>

#include<iostream.h>

#include<math.h>

void main()

{

clrscr(); //Lenh xoa man hinh

//Phan khai bao bien

float r,cv,dt;

//Phan nhap du lieu

cout<<"Ban hay nhap ban kinh duong tron: ";

cin>>r;

//Phan xu ly tinh toan

cv = 2*M_PI*r;

dt = M_PI*r*r;

//Phan xuat du lieu

cout<<"Chu vi duong tron ban kinh "<<r<<" la "<< cv<<endl;

cout<<"Dien tich duong tron ban kinh "<<r<<" la "<<dt;

getch(); //Lenh dung man hinh

}

Page 27: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 27

Chú ý: muốn làm tròn số thì ta dùng hàm setprecision(n), với n là số chữ số lẻ

//Phan khai bao thu vien

#include<conio.h>

#include<iostream.h>

#include<math.h>

#include<iomanip.h>

const float PI=M_PI;

void main()

{

clrscr(); //Lenh xoa man hinh

//Phan khai bao bien

float r,cv,dt;

//Phan nhap du lieu

cout<<"Ban hay nhap ban kinh duong tron: ";

cin>>r;

//Phan xu ly tinh toan

cv = 2*PI*r;

dt = PI*r*r;

//Phan xuat du lieu

cout<<"Chu vi duong tron ban kinh "<<r<<" la "<<setprecision(2)<<cv;

cout<<endl;

cout<<"Dien tich duong tron ban kinh "<<r<<" la "<<setprecision(2)<<dt;

getch(); //Lenh dung man hinh

}

2. Nhập cạnh a. Tính và xuất chu vi, diện tích hình vuông.

HD: cv=4*a và dt=a2

3. Nhập cạnh a,b. Tính và xuất chu vi, diện tích hình chữ nhật.

HD: cv=2*(a+b) và dt=a*b

4. Nhập cạnh a,h1,h2. Tính và xuất chu vi, diện tích hình thoi.

HD: cv=4*a và dt=1.0/2*h1*h2

5. Nhập cạnh a,b,c,d,h. Tính và xuất chu vi, diện tích hình thang.

HD: cv=(a+b+c+d) và dt=1.0/2*h*(a+b)

6. Nhập cạnh a,b,c. Tính và xuất chu vi, diện tích hình tam giác.

HD: cv=a+b+c và dt= )(*)(*)(* cpbpapp −−− với p=cv/2

7. Nhập vào hai số nguyên dương a,b. Tính và xuất tổng, hiệu, tích, thương.

Page 28: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 28

8. Nhập 2 số nguyên a,b. Tính và xuất ab.

HD: dùng hàm pow(x,y) ���� xy

9. Nhập 1 số n. Tính và xuất giá trị tuyết ñối.

HD: dùng hàm abs(a) ���� |a|

10. Nhập 1 số n. Tính và xuất căn bậc hai của n.

HD: dùng hàm sqrt(a) ���� a

11. Nhập 1 góc x. Tính và xuất sinx, cosx, tgx, cotgx.

HD: các hàm sin, cos, tan chỉ tính theo ñơn vị radian nên chúng ta phải ñổi từ ñộ x sang ñộ radian t như sau: t=x*π/180 => sinx=sin(t), cosx=cos(t), tgx=tan(t), cotgx=1/tgx

12. Nhập toạ ñộ 2 ñiểm A(xA,yA), B(xB,yB). Tính và xuất ñộ dài ñoạn AB.

HD: |AB|=dAB= ))()( 22ABAB yyxx −+−

13. Nhập toạ ñộ 2 ñiểm A(xA,yA), B(xB,yB). Tính hệ số góc của ñường thẳng ñi qua hai ñiểm ñó theo công thức: Hệ số góc = (yB - yA) /(xB - xA)

14. Viết chương trình nhập vào số nguyên n và số thực x. Tính và in ra biểu thức nn xxxxA )1()1( 22

+−+++=

15. Nhập vào số giây bất kỳ t. Tính và xuất ra dạng Giờ:Phút:Giây

Ví dụ: Nhập 3750 thì xuất ra 1:2:30 AM

Nhập 51100 thì xuất ra 2:11:40 PM

HD: hour=(t/3600)%24, minute=(t%3600)/60, second=(t%3600)%60

16. Viết chương trình nhập vào ngày, tháng, năm. In ra ngày tháng năm theo dạng dd/mm/yy. (dd: ngày, mm: tháng, yy : năm. Ví dụ: 20/11/99 )

17. Viết chương trình tính logax với a, x là các số thực nhập vào từ bàn phím, và x>0, a>0, a != 1.( dùng logax=lnx/lna)

18. Viết chương trình nhập vào một ký tự:

a) In ra mã ASCII của ký tự ñó. b) In ra ký tự kế tiếp của nó.

19. Viết chương trình nhập vào ñiểm ba môn Toán, Lý, Hóa của một học sinh. In ra ñiểm trung bình của học sinh ñó với hai số lẻ thập phân.

20. Viết chương trình ñảo ngược một số nguyên dương có ñúng 3 chữ số. VD: 468 -> 864

Page 29: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 29

CHƯƠNG III: CẤU TRÚC ðIỀU KHIỂN

III.1 GIỚI THIỆU Một chương trình ñang chạy dành toàn bộ thời gian ñể thực thi các câu lệnh. Thứ tự mà các câu lệnh ñược thực hiện ñược gọi là dòng ñiều khiển (flow control). Thuật ngữ này phản ánh việc các câu lệnh ñang thực thi hiện thời có sự ñiều khiển của CPU, khi CPU hoàn thành sẽ ñược chuyển giao tới một lệnh khác.

ðặc trưng dòng ñiều khiển trong một chương trình là tuần tự, nhưng có thể chuyển hướng tới ñường dẫn khác bởi các lệnh rẽ nhánh. Dòng ñiều khiển là một sự xem xét quan trong vì nó quyết ñịnh lệnh nào ñược thực thi và lệnh nào không ñược thực thi trong quá trình chương trình thực thi, vì thế làm ảnh hưởng ñến kết quả toàn bộ của chương trình.

Giống nhiều ngôn ngữ thủ tục khác, C++ cung cấp những cấu trúc ñiều khiển khác nhau cho các mục ñích khác nhau.

− Các lệnh khai báo ñược sử dụng cho ñịnh nghĩa các biến. − Các lệnh gán ñược sử dụng cho các tính toán ñại số ñơn giản. − Các lệnh rẽ nhánh ñược sử dụng ñể chỉ ñịnh ñường dẫn của việc thực thi

phụ thuộc vào kết quả của một ñiều kiện luận lý. − Các lệnh lặp ñược sử dụng ñể chỉ ñịnh các tính toán cần ñược lặp cho tới

khi một ñiều kiện luận lý nào ñó ñược thỏa.

Các lệnh ñiều khiển ñược sử dụng ñể làm chuyển ñường dẫn thực thi tới một ñường dẫn khác của chương trình.

III.2 CẤU TRÚC RẼ NHÁNH

Cấu trúc rẽ nhánh là một cấu trúc ñược dùng rất phổ biến trong các ngôn ngữ lập trình nói chung. Khi lập trình, ñôi khi một lệnh thực hiện phụ thuộc vào một ñiều kiện nào ñó cần ñược thỏa. Lệnh if cung cấp cách ñể thực hiện công việc này. Có hai dạng:

Dạng 1:

Lưu ñồ cú pháp:

if (<biểu thức ñiều kiện>) lệnh;

Page 30: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 30

Ý nghĩa: Trước hết <biểu thứcñiều kiện> ñược ước lượng. Nếu kết quả là 0 (true) thì <lệnh> ñược thực thi. Ngược lại, không làm gì cả.

Ví dụ : Viết chương trình nhập vào một số thực a. In ra màn hình kết quả nghịch ñảo của a khi a ≠ 0

#include <iostream.h> #include <conio.h> int main () {

float a; cout<<"Nhap a = "; cin>>a; if (a !=0 )

cout<<"Nghich dao cua “<<a<<”la ”<<1/a; getch(); return 0;

} Giải thích: − Nếu nhập một số a ≠0 thì câu lệnh

cout<<"Nghich dao cua “<<a<<”la ”<<1/a; ñược thực hiện, ngược lại câu lệnh này không ñược thực hiện.

− Lệnh getch() luôn luôn ñược thực hiện vì nó không phải là “lệnh liền sau” ñiều kiện if.

Ví dụ : Viết chương trình nhập 2 số a và b, xuất ra màn hình số lớn nhất #include <iostream.h> #include<conio.h> int main () {

int a,b; cout<<”Nhap gia tri cua 2 so a, b"; cin>>a>>b; if (a>b) {

cout<<"Gia tri cua a lon hon gia tri cua b"<<endl; cout<<”a =”<<a<<endl; cout<<”b=”<<b;

} getch(); return 0;

}

Dạng 2:

if (<Biểu thức ñiều kiện>) <lệnh 1>

else <lệnh 2>

Page 31: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 31

Lưu ñồ cú pháp:

Ý nghĩa: Trước hết <biểu thức ñiều kiện> ñược ước lượng. Nếu kết quả là 0 (true) thì <lệnh1> ñược thực thi. Ngược lại, thì <lệnh 2> ñược thực thi.

Ví dụ :

Viết chương trình nhập vào một số thực a. In ra màn hình kết quả nghịch ñảo của a khi a ≠0, khi a =0 in ra thông báo “Khong the tim duoc nghich dao cua a”

#include <iostream.h> #include <conio.h> int main () {

float a; cout<<"Nhap a = "; cin>>a; if (a !=0 )

cout<<"Nghich dao cua “<<a<<”la”<<1/a; else

cout<<“Khong the tim duoc nghich dao cua a”; getch(); return 0;

}

Ví dụ Viết chương trình nhập vào một số nguyên dương là tháng trong năm và in ra số ngày của tháng ñó. Biết rằng

- Tháng có 31 ngày: 1, 3, 5, 7, 8, 10, 12

- Tháng có 30 ngày: 4, 6, 9, 11 - Tháng có 28 hoặc 29 ngày : 2

#include <iostream.h> #include<conio.h> void main ()

Page 32: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 32

{ int m; cout<<"Nhap vao thang trong nam !"; cin>>m; if (m= =1||m= =3||m= =5||m= =7||m= =8||m= =10||m= =12)

cout<<"Thang “<<m<<”co 31 ngay "; else

if (m= =4||m= =6||m= =9||m= =11) cout<<"Thang “<<m<<”co 30 ngay";

else if (m= =2)

cout<<"Thang “<<m<<”co 28 hoac 29 ngay"; else

cout<<"Khong co thang”<<m; getch();

} Lưu ý:

- Ta có thể sử dụng các câu lệnh if…else lồng nhau. Trong trường hợp if…else lồng nhau thì else sẽ kết hợp với if gần nhất chưa có else.

- Trong trường hợp câu lệnh if “bên trong” không có else thì phải viết nó trong cặp dấu {} (coi như là khối lệnh) ñể tránh sự kết hợp else if sai.

Ví dụ: if (ch >= '0' && ch <= '9')

kind = digit; else {

if (ch >= 'A' && ch <= 'Z') kind = upperLetter;

else {

if (ch >= 'a' && ch <= 'z') kind = lowerLetter;

else kind = special;

} }

ðể cho dễ ñọc có thể sử dụng hình thức sau:

if (ch >= '0' && ch <= '9') kind = digit;

else if (ch >= 'A' && ch <= 'Z') kind = capitalLetter;

else if (ch >= 'a' && ch <= 'z') kind = smallLetter;

else kind = special;

Page 33: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 33

III.3 CẤU TRÚC LỰA CHỌN (switch):

Lệnh switch cung cấp phương thức lựa chọn giữa một tập các khả năng dựa trên giá trị của biểu thức.

Cú pháp:

Lưu ñồ:

Giải thích: − Trước hết tính giá trị của biểu thức. − Nếu giá trị của biểu thức bằng giá trị 1 thì thực hiện lệnh 1 rồi thoát. − Nếu giá trị của biểu thức khác giá trị 1 thì so sánh với giá trị 2, nếu

bằng giá trị 2 thì thực hiện lệnh 2 rồi thoát…., so sánh tới giá trị n. − Nếu tất cả các phép so sánh trên ñều sai thì thực hiện công việc mặc

ñịnh của trường hợp default.

Lưu ý:

switch (<Biểu thức>) {

case giá trị 1: Khối lệnh thực hiện công việc 1; break;

… case giá trị n:

Khối lệnh thực hiện công việc n; break;

[default : Khối lệnh thực hiện công việc mặc ñịnh; break;]

}

Page 34: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 34

− Biểu thức trong switch() phải có kết quả là giá trị kiểu số nguyên (int, char, long, …).

− Các giá trị sau case cũng phải là kiểu số nguyên. − Không bắt buộc phải có default.

Ví dụ : Nhập vào một số nguyên, chia số nguyên này cho 2 lấy phần dư. Kiểm tra nếu phần dư bằng 0 thì in ra thông báo “là số chẵn”, nếu số dư bằng 1 thì in thông báo “là số lẻ”.

#include <iostream.h> #include<conio.h> void main () {

clrscr(); int n, phandu; cout<<” Nhap vao so nguyen : "; cin>>n; phandu=(songuyen % 2); switch(phandu) {

case 0: cout<<n<<” la so chan"; break; case 1: cout<<n<<” la so le"; break;

} getch();

}

Ví dụ : Nhập vào 2 số nguyên và 1 phép toán. − Nếu phép toán là ‘+’, ‘-‘, ‘*’ thì in ra kết qua là tổng, hiệu, tích của 2 số. − Nếu phép toán là ‘/’ thì kiểm tra xem số thứ 2 có khác không hay không?

Nếu khác không thì in ra thương của chúng, ngược lại thì in ra thông báo “khong chia cho 0”.

#include <iostream.h> #include<conio.h> int main () {

int a, b; float thuong; char pheptoan; clrscr(); cout<<” Nhap vao 2 so nguyen :"; cin>>a>>b; fflush(stdin);//Xóa ký tự enter trong vùng ñệm trước khi nhập phép toán cout<<”Nhap vao phep toan "; cin>>pheptoan; switch(pheptoan) {

case '+': cout<<a<<” + “<<b<<” =”<<a+b; break;

case '-':

Page 35: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 35

cout<<a<<” - “<<b<<” =”<<a-b; break;

case '*': cout<<a<<” * “<<b<<” =”<<a*b; break;

case '/': if (b!=0) {

thuong=(float)a/b; cout<<a<<” / “<<b<<” =”<<thuong;

} else

cout<<"Khong chia duoc cho 0"; break;

} getch();

}

Ví dụ : Yêu cầu người thực hiện chương trình nhập vào một số nguyên dương là tháng trong năm và in ra số ngày của tháng ñó. - Tháng có 31 ngày: 1, 3, 5, 7, 8, 10, 12 - Tháng có 30 ngày: 4, 6, 9, 11 - Tháng có 28 hoặc 29 ngày : 2 - Nếu nhập vào số <1 hoặc >12 thì in ra câu thông báo “không có tháng này “. #include <iostream.h> #include<conio.h> int main () {

int thang; clrscr(); cout<<" Nhap vao thang trong nam "; cin>>thang; switch(thang) {

case 1: case 3: case 5: case 7: case 8: case 10: case 12:

cout<<"Thang ”<<thang<<” co 31 ngay"; break;

case 4: case 6: case 9: case 11:

cout<<"Thang ”<<thang<<” co 30 ngay"; break;

Page 36: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 36

case 2: cout<<" Thang 2 co 28 hoac 29 ngay"; break;

default : cout<<”Khong co thang ”<<thang ; break;

} getch();

}

III.4 CẤU TRÚC LẶP (reiterate structure) Cấu trúc vòng lặp cho phép lặp lại nhiều lần 1 công việc (ñược thể hiện bằng 1 câu lệnh hay 1 khối lệnh) nào ñó cho ñến khi thỏa mãn 1 ñiều kiện cụ thể.

III.4.1. Vòng lặp while

Vòng lặp while cho phép thực hiện lệnh trong khi biểu thức ñiều kiện lặp vẫn còn ñúng.

Cú pháp: Lưu ñồ cú pháp:

− Biểu thức ñiều kiện lặp: ñược kiểm tra ñầu tiên. Nếu kết quả là 1 ( nghĩa là ñúng ⇔ true) thì thực hiện lệnh (thân vòng lặp) và toàn bộ quá trình ñược lặp lại. Ngược lại, nếu kiểm tra biểu thức ñiều kiện lặp là 0 (nghĩa là sai ⇔ false) thì vòng lặp sẽ kết thúc.

− Khối lệnh thực hiện có thể rỗng, có thể làm thay ñổi ñiều kiện. − Vòng lặp while có thể không thực hiện lệnh lần nào cả nếu ngay lần ñầu

tiên kiểm tra biểu thức ñiều kiện lặp là sai.

Ví dụ:

viết chương trình tính tổng của tất cả các số nguyên từ 1 tới n. #include<iostream.h> #include<conio.h> void main ()

while (<biểu thức ñiều kiện lặp>) lệnh;

Page 37: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 37

{ clrscr(); int i, n, sum; cout<<”Nhap n =”; cin>>n; i = 1; sum = 0; while (i<=n) {

sum += i; i++;

} getch();

}

Ví dụ : Viết ñoạn chương trình in dãy số nguyên từ 1 ñến 10.

#include<iostream.h> #include<conio.h> void main () {

int i; clrscr(); cout<<”Day so tu 1 den 10 : "; i=1; while (i<=10) {

cout<< setw(3) <<i; i++;

} getch();

}

Ví dụ :

Viết chương trình nhập vào một số nguyên n. Tính tổng của các số nguyên từ 1 ñến n.

#include <iostream.h> #include<conio.h> void main () {

unsigned int n,i,tong; clrscr(); cout<<” Nhap vao so nguyen duong n:"; cinn>>n; tong=0; i=1; while (i<=n) {

tong+=i; i++;

lần lặp i n i <= n sum += i Một 1 5 1 1 Hai 2 5 1 3 Ba 3 5 1 6 Bốn 4 5 1 10 Năm 5 5 1 15 Sáu 6 5 0

Page 38: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 38

} Cout<<” Tong tu 1 den “<<n<<”=”<<tong; getch();

}

Ví dụ : Viết chương trình in ra trên màn hình một ma trận có n dòng m cột:

1 2 3 4 5 6 7 2 3 4 5 6 7 8 3 4 5 6 7 8 9

#include<iostream.h> #include<conio.h> #include<iomanip.h> void main () {

unsigned int dong=0, cot, n, m; clrscr(); cout<<” Nhap vao so dong va so cot :"; cin>>n>>m; while (dong<n) {

cout<<"\n"; cot=1; while (cot<=m) {

cout<<setw(3)<<dong+cot; cot++;

} dong++;

} getch();

} Lưu ý: vòng lặp phải kết thúc ở một ñiểm nào ñó, vì vậy bên trong vòng lặp phải cung cấp một phương thức nào ñó ñể buộc <biểu thức ñiều kiện> trở thành sai nếu không thì chương trình sẽ lặp vô tận.

III.4.2. Vòng lặp do… while

Vòng lặp do … while giống như vòng lặp while, dùng ñể lặp lại một công việc nào ñó (lệnh) trong khi biểu thức ñiều kiện lặp vẫn còn ñúng. − Trước hết <lệnh> ñược thực hiện trước, sau ñó kiểm tra <Biểu thức ñiều

kiện lặp>. � Nếu ñiều kiện sai thì thoát khỏi vòng lặp do …while. � Nếu ñiều kiện còn ñúng thì thực hiện lệnh rồi quay lại kiểm tra ñiều kiện

lần tiếp theo. − Trong vòng lặp do…while thì <lệnh> ñược thực hiện ít nhất 1 lần, ngay cả

khi ñiều kiện sai. − Vòng lặp dừng lại khi ñiều kiện sai. − Khối lệnh thực hiện công việc có thể rỗng, có thể làm thay ñổi ñiều kiện.

Page 39: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 39

Cú pháp:

Lưu ñồ:

Ví dụ : Viết ñoạn chương trình in dãy số nguyên từ 1 ñến 10. #include <iostream.h> #include<conio.h> void main () {

int i; clrscr(); cout<<"Day so tu 1 den 10 :"; i=1; do {

cout<<setw(3)<<i; i+=1;

} while (i<=10); getch();

}

Ví dụ : Viết chương trình nhập vào một số nguyên n. Tính tổng của các số nguyên từ 1 ñến n.

#include <iostream.h> #include<conio.h> void main () {

unsigned int n,i,tong; clrscr(); cout<<” Nhap vao so nguyen duong n:"; cin>>n; tong=0; i=1; do

do { <Lệnh>

} while (<Biểu thức ñiều kiện lặp >);

Page 40: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 40

{ tong+=i; i++;

} while (i<=n); cout<<” Tong tu 1 den ”<<n<<”=”<<tong; getch();

}

III.4.3. Vòng lặp for:

Chức năng chính của vòng lăp for là lặp lại một ñọan lệnh nào ñó ñến khi nào biểu thức ñiều kiện còn mang giá trị ñúng, vòng lặp for thường sử dụng trong những chương trình mà số lần lặp lại một ñọan lệnh nào ñó ñược biết trước.

Cú pháp:

L

Cách hoạt ñộng của vòng lặp for như sau:

− Biểu thức khởi tạo: ñược thực hiện, nó gán một giá trị khởi tạo ban ñầu cho biến ñiều khiển. Lệnh này ñược thực hiện chỉ một lần.

− Biểu thức ñiều kiện: ñược kiểm tra, nếu nó là ñúng vòng lặp tiếp tục còn nếu không vòng lặp kết thúc và lệnh ñược bỏ qua.

− Lệnh: ñược thực hiện khi ñiều kiện thỏa. Nó có thể là một lệnh ñơn hoặc là một khối lệnh ñược ñặt trong một cặp ngoặc nhọn {}.

− Các lệnh tác ñộng ñến biểu thức ñiều kiện: ñược thực hiện ñể tăng/giảm biến ñiều khiển và vòng lặp quay trở lại bước 2.

Lưu ñồ cú pháp:

for (biểu thức khởi tạo; biểu thứcñiều kiện; lệnh tác ñộng ñến btñiều kiện) <các lệnh>

Page 41: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 41

Lưu ý: Vòng lặp for thường ñược sử dụng trong các trường hợp mà có một biến ñược tăng hay giảm ở mỗi lần lặp.

Ví dụ: Viết chương trình tính tổng của các số nguyên từ 1 tới n. #include <iostream.h> #include<conio.h> void main () {

int i, n, sum; cout<<”Nhap so nguyen n:”; cin>>n; sum = 0; for (i = 1; i <= n; i++)

sum += i; cout<<”Tong cua “<<n<<”so nguyen la: ”<<sum;

getch(); }

− C++ cho phép biểu thức ñầu tiên trong vòng lặp for là một ñịnh nghĩa biến. Ví dụ trong vòng lặp trên thì I có thể ñược ñịnh nghĩa bên trong vòng lặp:

for (int i = 1; i <= n; ++i) sum += i;

− Trái với sự xuất hiện, phạm vi của I không ở trong thân của vòng lặp mà là chính vòng lặp.

− Bất kỳ biểu thức nào trong 3 biểu thức của vòng lặp for ñều có thể rỗng. Ví dụ, xóa biểu thức ñầu và biểu thức cuối cho chúng ta dạng giống như vòng lặp while:

for (; i != 0;) // tương ñương với: while (I != 0) {

Lệnh… }

− Xóa tất cả các biểu thức cho chúng ta một vòng lặp vô hạn. ðiều kiện của vòng lặp này ñược giả sử luôn luôn là ñúng.

for (;;) // vòng lặp vô hạn { Lệnh… }

III.5 CÁC LỆNH RẼ NHÁNH VÀ LỆNH NHẢY

III.5.1. Lệnh continue

Lệnh continue dừng lần lặp hiện tại của một vòng lặp và nhảy tới lần lặp kế tiếp. Nó áp dụng tức thì cho vòng lặp gần với lệnh continue. Không sử dụng lệnh continue bên ngoài vòng lặp.

Trong vòng lặp while và vòng lặp do-while, vòng lặp kế tiếp mở ñầu từ ñiều kiện lặp. Trong vòng lặp for, lần lặp kế tiếp khởi ñầu từ biểu thức thứ ba của vòng lặp.

Page 42: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 42

Ví dụ: một vòng lặp thực hiện ñọc một số, xử lý nó nhưng bỏ qua những số âm, và dừng khi số là 0, có thể diễn giải như sau:

do

{ cin >> num;

if (num < 0) continue; // xử lý số ở ñây …

} while (num != 0);

ðiều này tương ñương với:

do {

cin >> num; if (num >= 0) {

// xử lý số ở ñây … }

} while (num != 0);

− Một biến thể của vòng lặp này là ñể ñọc chính xác một số n lần (cho tới khi số ñó là 0) có thể ñược diễn giải như sau:

for (i=0; i<n; i++) {

cin >>num; if (num<0) continue; //làm cho nhảy tới: i++

// xử lý số ở ñây … }

Khi lệnh continue xuất hiện bên trong vòng lặp ñược lồng vào thì nó áp dụng trực tiếp cho vòng lặp gần nó chứ không áp dụng cho vòng lặp bên ngoài.

Ví dụ: trong một tập các vòng lặp ñược lồng nhau sau ñây, lệnh continue áp dụng cho vòng lặp for và không áp dụng cho vòng lặp while:

while (more)

{ for (i = 0; i < n; i++) {

cin >> num; if (num < 0)

continue; // làm cho nhảy tới: i++ // process num here...

} //etc...

}

III.5.2. Lệnh break

Lệnh break có thể xuất hiện bên trong vòng lặp (while, do, hay for) hoặc một lệnh switch. Nó gây ra bước nhảy ra bên ngoài những lệnh này và vì

Page 43: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 43

thế kết thúc chúng. Giống như lệnh continue, lệnh break chỉ áp dụng cho vòng lặp hoặc lệnh switch gần nó nhất. Không sử dụng lệnh break bên ngoài vòng lặp hay lệnh switch.

Ví dụ:

ðọc vào một mật khẩu người dùng nhưng không cho phép một số hữu hạn lần thử: for (i = 0; i < attempts; ++i) {

cout << "Please enter your password: "; cin >> password; if (Verify(password)) // kiểm tra mật khẩu ñúng hay sai

break; // thoát khỏi vòng lặp cout << "Incorrect!\n";

} Ở ñây phải giả sử rằng có một hàm Verify ñể kiểm tra một mật khẩu và trả về true nếu như mật khẩu ñúng và ngược lại là false.

Ví dụ:

Viết chương trình tính tổng các số nguyên ñược nhập từ bàn phím, chương trình ñược kết thúc khi nhập số âm.

#include <iostream.h> #include <conio.h> void main() { int so,tong=0; clrscr(); while (1) { cout <<"Nhap mot so nguyen: "; cin >>so; if (so<0) break; tong +=so; } cout<<"\nTong cac gia tri da nhap la: "<<tong; getch(); }

Chương trình trên nếu không dùng break có thể ñuợc viết lại như sau: do

{ cout <<"Nhap mot so nguyen: "; cin >>so; if (so>=0)

tong += so; }while (so>=0);

III.5.3. Lệnh goto

Lệnh goto cung cấp một hình thức nhảy tự do không có cấu trúc (không giống như lệnh break và continue) nên dễ làm gãy ñổ chương trình. Phần lớn các lập

Page 44: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 44

trình viên ngày nay tránh sử dụng nó ñể làm cho chương trình rõ ràng. Tuy nhiên, goto có một vài (dù cho hiếm) sử dụng chính ñáng. Cú pháp:

Goto Nhãn; trong ñó nhãn là một ñịnh danh (identify) ñược dùng ñể ñánh dấu ñích cần nhảy tới. Nhãn cần ñược theo sau bởi một dấu hai chấm (:) và xuất hiện trước một lệnh bên trong hàm như chính lệnh goto.

Ví dụ:

for (i = 0; i < attempts; ++i)

{ cout << "Please enter your password: "; cin >> password; if(Verify(password)) // check password for correctness

goto out; // drop out of the loop cout << "Incorrect!\n";

} out:

//etc...

III.5.4. Lệnh return

Lệnh return cho phép một hàm trả về một giá trị cho thành phần gọi nó. Cú pháp:

return biểu thức; − Trong ñó biểu thức chỉ rõ giá trị ñược trả về bởi hàm. Kiểu của giá trị

này phải hợp với kiểu của hàm. Trường hợp kiểu trả về của hàm là void, biểu thức sau lệnh return rỗng:

return; − Hàm mà ñược chúng ta thảo luận ñến thời ñiểm này chỉ có hàm main,

kiểu trả về của nó là kiểu int. Giá trị trả về của hàm main là những gì mà chương trình trả về cho hệ ñiều hành khi nó hoàn tất việc thực thi. Chẳng hạn dưới UNIX qui ước là trả về 0 từ hàm main khi chương trình thực thi không có lỗi. Ngược lại, một mã lỗi khác 0 ñược trả về.

Ví dụ:

int main (void) {

cout << "Hello World\n"; return 0;

} − Khi một hàm có giá trị trả về không là void (như trong ví dụ trên), nếu

không trả về một giá trị sẽ mang lại một cảnh báo trình biên dịch. Giá trị trả về thực sự sẽ không ñược ñịnh nghĩa trong trường hợp này (nghĩa là, nó sẽ là bất cứ giá trị nào ñược giữ trong vị trí bộ nhớ tương ứng của nó tại thời ñiểm ñó).

Page 45: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 45

BÀI TẬP

1. Nhập 1 số n>=0. Tính và xuất căn bậc hai của n.

HD: dùng hàm sqrt(a)= a

2. Nhập vào số giây bất kỳ t>=0. Tính và xuất ra dạng Giờ:Phút:Giây

Ví dụ: Nhậ p 3750 thì xuất ra 1:2:30 AM

Nhập 51100 thì xuất ra 2:11:40 PM

HD: hour=(t/3600)%24, minute=(t%3600)/60, second=(t%3600)%60

3. Nhập 3 số thực a, b, c. Tìm số lớn nhất. (Dùng if, không dùng if)

4. Nhập n. Kiểm tra n là số chẵn hay số lẻ.

5. Nhập 2 số a, b. Kiểm tra xem chúng có cùng dấu hay không.

6. Nhập vào hai số nguyên dương a, b. So sánh giá trị của chúng (lớn hơn, nhỏ hơn, bằng).

7. Giải và biện luận phương trình bậc 1: ax+b=0.

8. Giải và biện luận phương trình bậc 2: ax2+bx+c=0.

9. Nhập vào tháng t (với 1<=t<=12). Cho biết t thuộc quí mấy trong năm.

10.Nhập vào tháng t (với 1<=t<=12). Cho biết tháng t có bao nhiêu ngày. Riêng tháng 2 thì phải kiểm tra năm nhuận (Năm nhuận là năm chia hết cho 4 mà không chia hết cho 100, hoặc chia hết cho 400).

11.Nhập vào mộ t ngày (ngày, tháng, năm). Tìm ngày kế sau ngày vừa nhậ p (ngày/tháng/năm).

12.Nhập vào một ngày (ngày, tháng, năm). Tìm ngày kế trước ngày vừa nhập (ngày/tháng/năm).

13.Nhập vào một ngày (ngày, tháng, năm). Cho biết ngày ñó là ngày thứ bao nhiêu trong năm.

14*. Nhập vào một năm dương lịch. Hãy cho biết năm âm lịch. (vd: n=2007 => ðinh Hợi)

15*. Nhập một số n có tối ña 2 chữ số. Hãy cho biết cách ñọc ra dạng chữ.

(vd: n=35 => Ba mươi lăm, n=5 => năm).

16*. Nhập một số n có tối ña 3 chữ số. Hãy cho biết cách ñọc ra dạng chữ.

(vd: n=235 => Hai trăm ba mươi lăm, n=305 => Ba trăm lẻ năm)

17*. Nhập một số n bất kỳ. Hãy cho biết cách ñọc ra dạng chữ.

18.Nhập vào ñiểm Toán, Lý, Hoá. Hãy tính ðTB và Cho biết sinh viên ñó xếp loại gì (Xuất sắc, Giỏi, Khá, Trung bình, Yếu)..

19.Kiểm tra số nguyên dương n có phải là số chính phương hay không?

20.Viết chương trình nhập vào một số nguyên dương n với 1<=n<=7. Tùy theo n=1,2,...,7 hãy in tương ứng các từ (Sunday, Monsday, Tuesday,.... , Saturday) ra màn hình.

Page 46: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 46

21. Nhập vào số Kwh tiêu thụ ñiện. Tính tiền ñiện phải trả biết rằng cách thức tính tiền theo qui ñịnh như sau:

100 kwh ñịnh mức ñầu tiên có ñơn giá trung bình là 600ñ/kwh Các kwh từ 101 ñến 150 có ñơn giá là 700ñ/kwh Các kwh từ 151 ñến 200 có ñơn giá là 900ñ/kwh Các kwh từ 201 trở ñi có ñơn giá là 1100ñ/kwh

22. Nhập cạnh a>=0, b>=0, c>=0. Nếu a, b, c tạo thành tam giác thì hãy tính và xuất chu vi, diện tích hình tam giác. Ngược lại, thông báo “Không tạo thành tam giác”

HD: cv=a+b+c, p=cv/2 và dt= )(*)(*)(* cpbpapp −−−

23. Viết chương trình nhập từ bàn phím 2 số a, b và một ký tự ch.

Nếu: − ch là “+“ thì thực hiện phép tính a + b và in kết quả lên màn hình. − ch là “–“ thì thực hiện phép tính a - b và in kết quả lên màn hình. − ch là “*” thì thực hiện phép tính a * b và in kết quả lên màn hình. − ch là “/” thì thực hiện phép tính a / b và in kết quả lên màn hình.

24. Một số nguyên dương chia hết cho 3 nếu tổng các chữ số của nó chia hết cho 3. Viết chương trình nhập vào một số có 3 chữ số, kiểm tra số ñó có chia hết cho 3 dùng tính chất trên.( if )

25. Viết chương trình nhận vào giờ, phút, giây dạng (hh:mm:ss ), từ bàn phím. Cộng thêm một số giây vào và in ra kết quả dưới dạng ( hh:mm:ss ).

26. Kiểm tra một ký tự nhập vào thuộc tập hợp nào trong các tập ký tự sau:

− Các ký tự chữ hoa: 'A' ...'Z' − Các ký tự chữ thường: 'a' ... 'z' − Các ký tự chữ số : '0' ... '9' − Các ký tự khác.

27. Hệ thập lục phân dùng 16 ký số bao gồm các ký tự

0 .. 9 và A, B, C, D, E ,F. Các ký số A, B, C, D, E, F có giá trị tương ứng trong hệ thập phân như sau:

A 10 B 11 C 12 D 13 E 14 F 15

Hãy viết chương trình cho nhập vào ký tự biểu diễn một ký số của hệ thập lục phân và cho biết giá trị thập phân tương ứng. Trường hợp ký tự nhập vào không thuộc các ký số trên, ñưa ra thông báo lỗi: "Hệ thập lục phân không dùng ký số này"

28. Nhập n>=0. Tính S(n)=1+2+3+ … + n.

29. Nhập n>=0. Tính S(n)=2+4+ … + n.

30. Nhập n>=0. Tính S(n)=1+3+ … + n.

31. Nhập n>=0. Tính S(n)=12+22+32+ … + n2.

Page 47: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 47

32. Nhập n>=0. Tính S(n)=12+22+32+ … + n2.

33. Nhập n>=0. Tính n

nS1

...3

1

2

11)( ++++=

34. Nhập n>=0. Tính n

nS2

1...

4

1

2

1)( +++=

35. Nhập n>=0. Tính 12

1...

5

1

3

11)(

+++++=

nnS

36. Nhập n>=0. Tính )1(

1...

32

1

21

1)(

+×++

×+

×=

nnnS

37. Nhập n>=0. Tính 1

...3

2

2

1)(

++++=

n

nnS

38. Nhập n>=0. Tính 22

12...

4

3

2

1)(

+

++++=

n

nnS

39. Nhập n>=0. Tính T(n)=1×2×3× … ×n

40. Nhập n>=0. Tính S(n)=1+1×2+1×2×3+ … +1×2×3×…×n

41. Nhập x,n. Tính T(x,n)=xn

42. Nhập x,n. Tính n xnS =)(

43. Nhập x,n. Tính S(x,n)=x+x2+x3+ … +xn

44. Nhập x,n. Tính S(x,n)=x2+x4+x6+ … +x2n

45. Nhập x,n. Tính S(x,n)=x+x3+x5+ … +x2n+1

46. Nhập n. Tính n

nS+++

++++

++

+=...21

1...

321

1

21

11)(

47. Nhập x,n. Tính n

xxxxnxS

n

+++++

+++

++=

...21...

32121),(

32

48. Nhập x,n. Tính !

...!3!2

),(32

n

xxxxnxS

n

++++=

49. Nhập x,n. Tính !2

...!4!2

),(242

n

xxxxnxS

n

++++=

50. Nhập x,n. Tính )!12(

...!5!3

),(1253

+++++=

+

n

xxxxnxS

n

51. Nhập n. Tính 2...222)( ++++=nS , có n dấu căn lồng nhau.

52. Nhập n. Tính 12...)2()1()( +++−+−+= nnnnS , có n dấu căn lồng nhau.

53. Nhập n. Tính nnnS +−++++= )1(...321)( , có n dấu căn lồng nhau.

54. Liệt kê tất cả các ước số của số nguyên dương n.

55. Liệt kê tất cả các ước số lẻ của số nguyên dương n.

Page 48: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 48

56. Liệt kê tất cả các ước số chẵn của số nguyên dương n.

57. Tính tổng tất cả các ước số của số nguyên dương n.

58. Tính tích tất cả các ước số của số nguyên dương n.

59. ðếm số lượng các ước số của số nguyên dương n.

60. Tìm ước số lớn nhất của số nguyên dương n.

61. Kiểm tra n có phải là số nguyên tố hay không?

62. Liệt kê các số nguyên tố nhỏ hơn hay bằng số nguyên dương n.

63. Liệt kê các chữ số là số nguyên tố của số nguyên dương n.

64. Tính tồng các chữ số là số nguyên tố của số nguyên dương n.

65. Tính tích các chữ số là số nguyên tố của số nguyên dương n.

66. ðếm số lượng các chữ số chẵn của số nguyên dương n.

67. Tính tổng các chữ số chẵn của số nguyên dương n.

68. Tính tích các chữ số chẵn của số nguyên dương n.

69. ðếm số lượng các chữ số lẻ của số nguyên dương n.

70. Tính tổng các chữ số lẻ của số nguyên dương n.

71. Tính tích các chữ số lẻ của số nguyên dương n.

72. Tìm ước số chung lớn nhất của 2 số nguyên dương a, b.

73. Tìm Bội số chung lớn nhất của 2 số nguyên dương a, b.

74. Kiểm tra số nguyên dương n có phải là số ñối xứng hay không?

75. Kiểm tra số nguyên dương n có phải là số hoàn thiện (Pefect number) hay không? (Số hoàn thiện là số có tổng các ước số của nó (không kể nó) thì bằng chính nó. Vd: 6 có các ước số là 1,2,3 và 6=1+2+3 � 6 là số hoàn thiện)

76. Kiểm tra số nguyên dương n có phải là số thịnh vượng (Abundant number) hay không? (Số thịnh vượng là số có tổng các ước số của nó (không kể nó) thì lớn hơn nó. Vd: 12 có các ước số là 1,2,3,4,6 và 12<1+2+3+4+6 � 12 là số thịnh vượng)

77. Kiểm tra số nguyên dương n có phải là số không trọn vẹn (Deficient number) hay không? (Số không trọn vẹn là số có tổng các ước số của nó (không kể nó) thì nhỏ hơn nó. Vd: 9 có các ước số là 1,3 và 9>1+3 � 9 là số không trọn vẹn)

78. Kiểm tra số nguyên dương n có các chữ số toàn là chữ số chẵn hay không?

79. Kiểm tra số nguyên dương n có các chữ số toàn là chữ số lẻ hay không?

80. Kiểm tra số nguyên dương n có các chữ số tăng dần từ trái qua phải hay không?

81. Kiểm tra số nguyên dương n có các chữ số giảm dần từ trái qua phải hay không?

82. Nhập n>0. Tìm số nguyên dương m lớn nhất sao cho 1+2+3+…+m<n.

83. Nhập n>0. Tìm số nguyên dương m nhỏ nhất sao cho 1+2+3+…+m>n.

84. Xuất số ñảo của số nguyên dương n.

85. Xuất ra các ký tự từ A->Z, Z->A, a->z, z->a.

86. Xuất ra các số lẻ nhỏ hơn 50 trừ các số 11, 25, 37.

Page 49: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 49

87. Nhập n>0. Xuất ra bảng cửu chương n.

88. Hãy tìm số gà và số chó? biết:

Vừa gà vừa chó

bó lại cho tròn

ba mươi sáu con

một trăm chân chẵn.

89. Hãy tìm số trâu mỗi loại? biết:

Trăm trâu tăm cỏ Trâu ñứng ăn năm Trâu nằm ăn ba Trâu già ba con một bó

90. Xuất ra màn hình các hình có chiều cao h>0. ví dụ h=4 ta có các hình như sau:

91. Viết chương trình thực hiện trò chơi ñoán số như sau:

Máy lấy ra một số ngẫu nhiên n∈[1,100] là số của máy: Sốmáy (sử dụng hàm random).

- Người nhập vào một số (Sốnhập) + Nếu Sốnhập lớn hơn Sốmáy thì thông báo “Số bạn lớn hơn số máy”. + Nếu Sốnhập nhỏ hơn Sốmáy thì thông báo “Số bạn nhỏ hơn số máy”.

- Trò chơi kết thúc khi:

Page 50: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 50

+ Hoặc Bạn ñã ñoán trúng: thông báo “Ha ha bạn tài thật”. + Hoặc Bạn ñã ñoán sai 7 lần: thông báo “Bạn ñã thua rồi” và hiển thị Sốmáy.

92. Trò chơi lấy bì:

“Có M viên bi, hai người chơi lần lượt lấy ñi các viên bi sao cho số viên bi lấy ít nhất là 1 và nhiều nhất là 3, người nào mà lấy ñược viên bi cuối cùng thì người ñó bị thua”

- Giả sử bạn chơi với máy. Hãy viết chương trình mô phỏng trò chơi này sao cho máy có cơ hội thắng nhiều nhất.

- Người chơi cần nhập vào số viên bi M và chọn lượt lấy bi trước (máy lấy trước hay bạn lấy trước) sau ñó cứ thay phiên nhau lấy. Cuối cùng thì thông báo kết quả của ván chơi.

Page 51: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 51

CHƯƠNG IV: CHƯƠNG TRÌNH CON

IV.1 KHÁI NIỆM VỀ HÀM TRONG C++ Trong những chương trình lớn, có thể có những ñoạn chương trình viết lặp ñi lặp lại nhiều lần, ñể tránh sự lặp ñi lặp lại và mất thời gian khi viết chương trình, người ta thường phân chia chương trình thành nhiều module, mỗi module giải quyết một công việc nào ñó. Các module như vậy gọi là các chương trình con.

Một tiện lợi khác của việc sử dụng chương trình con là ta có thể dễ dàng kiểm tra xác ñịnh tính ñúng ñắn của nó trước khi ráp nối vào chương trình chính và do ñó việc xác ñịnh sai sót ñể tiến hành hiệu ñính trong chương trình chính sẽ thuận lợi hơn. Trong C/C++, chương trình con ñược gọi là hàm. Hàm có thể trả về kết quả thông qua tên hàm hay có thể không trả về kết quả.

Hàm có hai loại: hàm chuẩn và hàm tự ñịnh nghĩa. Trong chương này, chúng ta chú trọng ñến cách ñịnh nghĩa hàm và cách sử dụng các hàm ñó. Một hàm khi ñược ñịnh nghĩa thì có thể sử dụng ở bất kỳ vị trí nào trong chương trình. Một chương trình bắt ñầu thực thi bằng hàm main.

Ví dụ :

Viết chương trình nhập vào 2 số nguyên a,b và xuất ra màn hình số lớn nhất trong 2 số (sử dụng chương trình con)

#include <iostream.h> #include <conio.h> int max(int a, int b); void main() {

int a, b; cout<<” Nhap vao 2 so a, b "; cin>>a>>b; cout<<”so lon nhat la:”<<max(a, b); getch(); return;

} int max(int a, int b) {

return (a>b) ? a:b; }

IV.1.1. Hàm toán học:

C++ cung cấp một số hàm số học ñể có thể sử dụng trong chương trình. Khi sử dụng các hàm toán học ta cần khai báo thư viện <math.h> Muốn sử dụng các hàm toán học thì trong chương trình ta phải khai báo: #include <math.h> Cú pháp chung của một hàm là: functionName (arguments). Danh sách các hàm toán học thường dùng:

Page 52: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 52

IV.2 XÂY DỰNG HÀM

IV.2.1. Cấu trúc của một chương trình viết dưới dạng hàm

-Phần khai báo các thư viện

-Phần khai báo các hằng toàn cục

-Phần khai báo các biến toàn cục -Phần khai báo các nguyên mẫu hàm (prototype)

-Phần hàm main (sẽ gọi các hàm thực hiện)

-Phần ñịnh nghĩa các hàm ñã ñược khai báo prototype

IV.2.2. ðịnh nghĩa hàm

Cấu trúc của một hàm tự thiết kế:

Giải thích:

− Kiểu kết quả: là kiểu dữ liệu của kết quả trả về, có thể là : int, byte, char, float, void, … Một hàm có thể có hoặc không có kết quả trả về. Trong trường hợp hàm không có kết quả trả về ta nên sử dụng kiểu kết quả là void.

− Kiểu tham số: là kiểu dữ liệu của tham số. − Tham số: là tham số truyền dữ liệu vào cho hàm, một hàm có thể có hoặc

không có tham số. Tham số này gọi là tham số hình thức (formal variable), khi gọi hàm chúng ta phải truyền cho nó các tham số thực tế (actual variable). Nếu có nhiều tham số, mỗi tham số phân cách nhau dấu phẩy (,).

− Bên trong thân hàm (phần giới hạn bởi cặp dấu {}) là các khai báo cùng các câu lệnh xử lý. Các khai báo bên trong hàm ñược gọi là các khai báo cục bộ trong hàm và các khai báo này chỉ tồn tại bên trong hàm.

<kiểu kết quả> Tên hàm ([<kiểu tham số> <tham số>][,…]]) {

[Khai báo các biến cục bộ] [Các câu lệnh thực hiện bên trong hàm] [return [<Biểu thức>];]

}

Tên Hàm Công Dụng Kiểu dữ liệu trả về abs(x) Tính trị tuyệt ñối của x Int fabs() Double labs(x) long int pow(x1,x2) tính x1 lũy thừa x2 Double sqrt(x) tính căn bậc 2 của x Double sin(x) tính sin x (x tính bằng radian) Double cos(x) tính cos x (x tính bằng radian) Double tan(x) tính tan x (x tính bằng radian) Double log(x) ln(x) Double log10(x) logarit cơ số 10 của x Double exp(x) Ex Double

Page 53: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 53

− Khi ñịnh nghĩa hàm, ta thường sử dụng câu lệnh return ñể trả về kết quả thông qua tên hàm.

− Lệnh return dùng ñể thoát khỏi một hàm và có thể trả về một giá trị nào ñó. • return ; /*không trả về giá trị*/ • return <biểu thức>; /*Trả về giá trị của biểu thức*/ • return (<biểu thức>); /*Trả về giá trị của biểu thức*/

Lưu ý:

Nếu hàm có kết quả trả về, ta bắt buộc phải sử dụng câu lệnh return ñể trả về kết quả cho hàm.

Ví dụ : Viết hàm tìm ước chung lớn nhất của 2 số nguyên a, b. int uscln(int a, int b) { a=abs(a);

b=abs(b); while(a!=b)

{ if(a>b)

a-=b; else

b-=a; }

return a; //hoặc return b; }

IV.2.3. Sử dụng hàm

Một hàm khi ñịnh nghĩa thì chúng vẫn chưa ñược thực thi, hàm chỉ ñược thực thi khi trong chương trình có một lời gọi ñến hàm ñó.

Cú pháp gọi hàm:

-Cách 1:

<FunctionName>(List actual parameters);

Ví dụ: NhapCanh(a);

-Cách 2:

<Variable>=<FunctionName>(List actual parameters);

Ví dụ: dt=TinhDienTichTamGiac(a,b,c);

-Cách 3:

<Variable>=<FunName>(List actual parameters)Operator<Expression>;

Ví dụ: p=TinhChuViTamGiac(a,b,c)/2;

Ví dụ: Viết chương trình cho phép tìm ước số chung lớn nhất của hai số tự nhiên. #include<conio.h>

<Tên hàm>([Danh sách các tham số])

Danh sách các tham số thực ñược truyền cho hàm

Page 54: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 54

#include<iostream.h> //Phần khai báo nguyên mẫu hàm unsigned int uscln(unsigned int a, unsigned int b); //Phần hàm main void main() {

unsigned int a, b, USC; cout<<“Nhap a,b: ”; cin>>a>>b; USC = ucsln(a,b); cout<<“Uoc chung lon nhat la: ”, USC); getch();

} //Phần ñịnh nghĩa hàm unsigned int uscln(unsigned int a, unsigned int b) { a=abs(a);

b=abs(b); while(a!=b)

{ if(a>b)

a-=b; else

b-=a; }

return a; //hoặc return b; } Lưu ý: Việc gọi hàm là một phép toán, không phải là một phát biểu.

IV.2.4. Nguyên tắc hoạt ñộng của hàm

Trong chương trình, khi gặp một lời gọi hàm thì hàm bắt ñầu thực hiện bằng cách chuyển các lệnh thi hành ñến hàm ñược gọi. Quá trình diễn ra như sau: − Nếu hàm có tham số, trước tiên các tham số sẽ ñược gán giá trị thực tương

ứng. − Chương trình sẽ thực hiện tiếp các câu lệnh trong thân hàm bắt ñầu từ lệnh

ñầu tiên ñến câu lệnh cuối cùng. − Khi gặp lệnh return hoặc dấu } cuối cùng trong thân hàm, chương trình sẽ

thoát khỏi hàm ñể trở về chương trình gọi nó và thực hiện tiếp tục những câu lệnh của chương trình này.

IV.2.5. Truyền tham số cho hàm

IV.2.5.1. Tham số giá trị (pass value parameter):

Mặc ñịnh, việc truyền tham số cho hàm trong C/C++ là truyền theo giá trị, nghĩa là khi gọi hàm có các tham số, ta truyền các giá trị cho hàm.

Ví dụ:

Giả sử chúng ta gọi hàm addition như sau:

Page 55: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 55

int x=5, y=3, z;

z = addition ( x , y );

Trong trường hợp này khi gọi hàm addition thì các giá trị 5 and 3 ñược truyền cho hàm, không phải là bản thân các biến.

Khi thay ñổi giá trị của các biến a hay b bên trong hàm thì các biến x và y vẫn không thay ñổi, vì chỉ có giá trị của chúng ñược truyền mà thôi.

Page 56: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 56

Ví dụ

Viết chương trình in ra nhiều dòng, mỗi dòng 25 ký tự nào ñó. ðể ñơn giản ta viết một hàm, nhiệm vụ của hàm này là in ra trên một dòng 25 ký tự nào ñó. Hàm này có tên là InKyTu.

#include <iostream.h> #include <conio.h> void InKyTu(char ch); void main() {

char c = ‘A’; InKyTu(‘*’); // In ra 25 dau * InKyTu(‘+’); // In ra 25 dau + InKyTu(c); // In ra 25 chu c getch();

} void InKyTu(char ch) {

for(int i=1; i<=25; i++) cout<<ch;

cout<<“\n”; }

Ví dụ: #include <iostream.h> #include<conio.h> void Foo (int num); void main (void) { clrscr();

int x = 10; Foo(x); cout << "x = " << x << '\n'; getch();

} void Foo (int num) {

num = 0; cout << "num = " << num << '\n';

} Trong ví dụ trên, tham số duy nhất của hàm Foo là một tham số giá trị. Khi hàm ñược thực thi thì num ñược sử dụng như là một biến cục bộ bên trong hàm. Khi hàm ñược gọi và x ñược truyền tới nó, num nhận một bản sao chép giá trị của x. Kết quả là mặc dù num ñược ñặt về 0 bởi hàm nhưng vẫn không có gì tác ñộng lên x. Chương trình cho kết quả như sau:

num = 0; x = 10;

IV.2.5.2. Tham số tham chiếu (pass reference parameter):

Page 57: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 57

Xét trường hợp cần thao tác với một biến ngoài ở bên trong một hàm. Vì vậy cần phải truyền tham số dưới dạng tham chiếu (hay tham biến) như ở trong hàm duplicate trong ví dụ dưới ñây:

// passing parameters by reference #include <iostream.h> #include <conio.h> void duplicate (int& a, int& b, int& c); void main () {

clrscr(); int x=1, y=3, z=7; duplicate (x, y, z); cout <<"x="<<x<<", y="<<y<<", z="<<z; getch();

} void duplicate (int& a, int& b, int& c) {

a*=2; b*=2; c*=2;

} Trong ví dụ trên, khai báo của hàm duplicate, theo sau tên kiểu của mỗi tham số ñều là dấu và (&), ñể chứng tỏ rằng các tham số này ñược truyền theo tham biến.

Khi truyền tham số dưới dạng tham biến, ta ñang truyền bản thân biến ñó. Vì vậy, bên trong hàm nếu có bất kì sự thay ñổi giá trị nào ñược thực hiện với tham số ñó sẽ ảnh hưởng trực tiếp ñến giá trị của biến tương ứng với tham số ñó.

Trong ví dụ trên, ta ñã liên kết a, b và c với các tham số khi gọi hàm x, y và z và mọi sự thay ñổi với a bên trong hàm sẽ ảnh hưởng ñến giá trị của x và hoàn toàn tương tự với b và y, c và z.

IV.2.6. Phạm vi của biến (scope variables)

IV.2.6.1. Biến cục bộ (local variables):

Biến cục bộ là biến ñược khai báo trong thân của một hàm nào ñó, các biến này chỉ ñược hiểu bên trong phạm vi của hàm khai báo nó.

IV.2.6.2. Biến toàn cục (global variables):

Biến toàn cục là biến ñược khai báo bên ngoài các hàm, những biến này ñược dùng chung cho tất cả các hàm ñược khai báo sau nó.

Page 58: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 58

Ví dụ:

#include <iostream.h> #include <conio.h> int n1; void sub_fun(); void main() { int n2; clrscr(); n1=10; n2=20; cout <<"Trong ham main() n1= "<<n1<<endl //10 <<"Trong ham main() n2= "<<n2<<endl; //20 sub_fun(); cout <<"Trong ham main() sau khi goi sub_fun n1= "<<n1<<endl;//40

cout<<"Trong ham main() sau khi goi sub_fun n2= "<<n2<<endl; //20 getch();

} void sub_fun() { int n2; n2=30; cout <<"Trong ham sub_fun() n1= " <<n1<<endl //10 <<"Trong ham sub_fun() n2= " <<n2<<endl; //30 n1=40; } Trong ví dụ trên n1 là biến toàn cục, n2 là biến cục bộ có cả trong hàm main() và hàm sub_fun(). Hai dòng lệnh cout ñầu của hàm main sẽ in kết quả :

Trong ham main() n1= 10 Trong ham main() n2= 20 giá trị này là của n2 trong hàm main

Khi hàm sub_fun ñược gọi nó sẽ in kết quả: Trong ham sub_fun() n1= 10 Trong ham sub_fun() n2= 30 giá trị này là của n2 trong sub_fun

Hai dòng lệnh cout cuối của hàm main sẽ in kết quả: Trong ham main() sau khi goi sub_fun n1= 40 (n1 ñã bị ñổi trong hàm sub_fun) Trong ham main() sau khi goi sub_fun n2= 20 (n2 của hàm main)

Page 59: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 59

n1

main() n2

Lưu trữ n1

Lưu trữ n2 trong main

sub_fun() n2

Lưu trữ n2 trong sub_fun

Hình dưới minh hoạ việc lưu trữ và phạm vi của các biến trong chương trình trên:

− Các biến toàn cục không ñược khởi tạo, sẽ ñược khởi tạo tự ñộng là 0 nếu là kiểu số, và NULL nếu là kiểu ký tự.

− Các biến hoặc hàm toàn cục không ñược ñịnh nghĩa nhiều hơn một lần ở mức toàn cục.

− Biến hay hàm toàn cục có thể ñược truy xuất từ mọi nơi trong chương trình.

− Thời gian sống của một biến bị giới hạn bởi phạm vi của nó. Vì thế, các biến toàn cục tồn tại suốt thời gian thực hiện chương trình, trong khi các biến cục bộ chỉ tồn tại trong thời gian hàm khai báo nó thực thi.

− Không gian bộ nhớ cho các biến toàn cục ñược dành riêng trước khi sự thực hiện của chương trình bắt ñầu nhưng ngược lại không gian bộ nhớ cho các biến cục bộ ñược cấp phát ở thời ñiểm thực hiện chương trình.

IV.2.6.3. Toán tử phạm vi (scope resolution)

Phạm vi cục bộ ghi chồng lên phạm vi toàn cục nên một biến cục bộ có cùng tên với biến toàn cục làm cho biến toàn cục không thể truy xuất ñược tới phạm vi cục bộ.

Ví dụ:

#include <iostream.h> #include <conio.h> float n=42.8; void sub(); void main() { clrscr();

Page 60: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 60

float n=30.5; cout <<”Giá trị của n=“<<n<<endl; //30.5; sub(); getch(); } void sub() { cout <<”trong sub n= “<<n <<endl; //42.8 }

Trong trường hợp trên nếu muốn hàm main in ra giá trị của biến toàn cục thì phải sử dụng toán tử scope resolution :: ngay trước tên biến.

Ví dụ:

#include <iostream.h> #include <conio.h> float n=42.8; void sub(); void main() { float n=30.5;

cout<<”Giá trị của n=“<<::n<<endl; //42.8; sub(); getch(); } void sub(); { cout <<”trong sub n= “<<n <<endl; //42.8 }

Không nên lạm dụng biến toàn cục, vì nó sẽ phá vở sự an tòan mà C++ ñã cung cấp, ñó là sự ñộc lập của các hàm, nó cũng làm mất ñi sự cẩn thận cần thiết của người lập trình là phải xác ñịnh rõ kiểu dữ liệu của tham số, biến cục bộ, và giá trị trả về của hàm Ngoài ra giá trị của biến toàn cục có thể thay ñổi bởi bất cứ hàm nào khai báo sau nó, do ñó làm cho việc phát hiện những lỗi giải thuật có trong chương trình là rất khó.

IV.2.7. Lớp lưu trữ các biến

Ngoài việc mỗi biến phải có một kiểu dữ liệu và phạm vi có hiệu lực của nó, mỗi biến còn thuộc về một lớp lưu trữ nào ñó. Trong C++ có 4 lớp lưu trữ: auto, static, extern và register. Khi khai báo biến, phải chỉ rõ lớp lưu trữ của biến.

Ví dụ

auto int num; static int mile; register int volts; auto float yrs;

Page 61: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 61

IV.2.7.1. Lớp lưu trữ cục bộ

Biến cục bộ có thể lưu trữ trong 3 lớp:auto, static, register. − Nếu một biến khi khai báo mà không mô tả lớp lưu trữ thì xem như biến

này thuộc lớp auto. Các biến cục bộ thuộc lớp auto sẽ xuất hiện trong bộ nhớ khi hàm khai báo nó ñược gọi thực hiện và xóa khỏi bộ nhớ khi hàm thực hiện xong.

Ví dụ

#include <iostream.h> #include <conio.h> void sub(); void main() { clrscr(); for (int i=0; i<5; i++) sub(); getch(); } void sub() { int num=0; cout <<num<<" ";; num++; }// chương trình xuất ra màn hình 0 0 0 0 0

Giải thích: mỗi lần ñược gọi thực hiện sub() thì biến num sẽ ñược khởi tạo lại do ñó giá trị của biến num trước ñó không còn nữa − Một biến cục bộ static ñược tạo ra và khởi tạo giá ttrị một lần tại thời

ñiểm biên dịch, từ ñó nó tồn tại trong bộ nhớ với giá trị ñược tạo ra bởi lần gọi hàm (hàm khai báo nó) gần nhất

Ví dụ

#include <iostream.h> #include <conio.h> void sub(); void main() { clrscr(); for (int i=0; i<5; i++) sub(); getch(); } void sub() { static int num=1; cout <<num<<" ";; num++; }// chương trình xuất ra kết quả : 1 2 3 4 5

Page 62: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 62

− Nếu trong chương trình lúc khai báo ta không khởi tạo giá trị cho biến cục bộ static thì biến này sẽ ñược khởi tạo bằng 0

− Lớp lưu trữ biến cục bộ register cũng giống như biến cục bộ thuộc lớp auto, chỉ khác nơi lưu trữ, nơi lưu trữ tất cả các biến trừ biến register là RAM, biến register ñược lưu trữ trong vùng nhớ trực tiếp của CPU vì vậy việc truy xuất biến register nhanh hơn các biến khác. Tuy nhiên không phải bất kỳ máy nào cũng hổ trợ biến này, nếu có thì vùng nhớ dành lư trữ biến cũng nhỏ, vì vậy biến ñược khai báo register sẽ tự ñộng chuyển sang lớp auto nếu máy tính không hổ trợ.

IV.2.7.2. Các lớp lưu trữ biến toàn cục:

Biến tòan cục là những biến ñựơc khai báo bên ngoài hàm, các biến này tồn tại torng bộ nhớ từ khi chương trình bắt ñầu thực hiện cho ñến khi chương trình kết thúc.

Một biến toàn cục có thể thuộc lớp extern hoặc static, các lớp extern hoặc static chỉ ảnh hưởng ñến phạm vi mà không ảnh hưởng ñến thời gian tồn tại của biến.

Mục ñích của biến toàn cục extern là mở rộng việc sử dụng một biến toàn cục sang một tập tin chương trình khác (khi chương trình lưu trữ trên nhiều file)

Khi khai báo extern trước tên một biến thì bắt buộc biến này ñã ñược khai báo trước ở nơi khác trong chương trình và chỉ một lần mà thôi ñồng thời không có từ extern ở phía trước.

Lớp static dành cho biến toàn cục thì dùng ngăn chặn việc mở rộng phạm visử dụng của biến này ra một file khác.

Ví dụ: Có 2 chương trình lưu thành 2 file:

Theo hình minh họa, ta thấy nội dung chương trình ñược lưu trữ trênn 2 tập tin. Biến volts ở lần khai báo ñầu tiên trong file1 không có extern

File 1 File 2

int volts; float current; static double power; void main() { fun1(); fun2(); fun3(); fun4(); } extern double factor; void fun1(); { //Các lệnh của fun1 } void fun2() { //Các lệnh của fun2 }

double factor; extern int volts; void fun3(); { //Các lệnh của fun3 } void fun4() { //Các lệnh của fun4 }

Page 63: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 63

(ñây là quy ñịnh). ở lần khai báo thứ hai trong file2 có extern với mục ñích báo cho trình biên dịch ñây không phải là biến mới mà là biến ñã tồn tại trong bộ nhớ.

Page 64: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 64

BÀI TẬP

Ví dụ 1: Viết các chương trình dưới dạng hàm cho phép nhập vào 1 giá trị dương n. Tính và xuất ra màn hình căn bậc 2 của nó.

//Phần khai báo thư viện

#include<conio.h>

#include<iostream.h>

#include<math.h>

//Phần khai báo nguyên mẫu hàm (prototype)

float TinhCanBac2 (float x);

//Phần hàm main

void main()

{

clrscr();

float n,cn;

do

{

cout<<”Bạn hãy nhập một số nguyên dương n=”;

cin>>n;

}while(n<0);

cn=TinhCanBac2(n);

cout<<“Căn bậc hai của ”<<n<< “ là ”<<cn;

getch();

}

//Phần ñịnh nghĩa hàm

float TinhCanBac2(float x)

{

float cx;

cx=sqrt(x);

return cx;

}

Lưu ý:

- Biến cục bộ có thể trùng tên với biến toàn cục.

- Tham số hình thức có thể trùng tên với tham số thực.

Tham số hình thức dùng ñể khai báo và ñịnh nghĩa hàm

Lời gọi Hàm trong main

Truyền tham số thực n cho hàm, lúc này x chỉ là bản sao của n

Tham số hình thức dùng ñể khai báo và ñịnh nghĩa hàm

Trả về giá trị cho hàm

Khai báo biến cục bộ bên trong hàm

Khai báo biến cục bộ bên trong hàm main

Page 65: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 65

Ví dụ 2: Viết các chương trình dưới dạng hàm cho phép nhập vào 3 giá trị dương a,b,c. Tính và xuất ra màn hình diện tích của tam giác ABC tương ứng.

//Phần khai báo thư viện

#include<conio.h>

#include<iostream.h>

#include<math.h>

//Phần khai báo nguyên mẫu hàm (prototype)

void NhapCanh (char canh, float &x);

float TinhChuViTamGiac (float x, float y, float z);

float TinhDienTichTamgiac (float x, float y, float z);

void XuatKetQua (float x);

//Phần hàm main

void main()

{

clrscr();

float a,b,c,dt;

NhapCanh (‘a’, a);

NhapCanh (‘b’,b);

NhapCanh (‘c’,c);

dt=TinhDienTichTamGiac (a,b,c);

XuatKetQua (dt);

getch();

}

//Phần ñịnh nghĩa hàm void NhapCanh(char canh, float &x) { do

{ cout<<“Bạn hãy cho biết ñộ dài cạnh ”<<canh<<“=”; cin>>x; }while(x<=0);

} float TinhChuViTamGiac(float x, float y, float z) { float cv=0; if(x+y>z && x+z>y && y+z>x) cv=(x+y+z); return cv; }

float TinhDienTichTamgiac(float x, float y, float z)

Các biến cục bộ của hàm main

Các tham số hình thực ñược truyền cho các hàm

Những lời gọi Hàm trong main

x lúc này cũng chính là a, vì truyền tham số theo dạng tham chiếu (tham biến)

Các tham số hình thức dùng ñể khai báo và ñịnh nghĩa hàm

Khai báo tham số hình thức theo dạng tham chiếu (tham

Giá trị trả về cho hàm TinhChuViTamGiac

Page 66: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 66

{

float p,s;

p = TinhChuViTamGiac(x,y,z)/2;

s = sqrt(p*(p-x)*(p-y)*(p-z));

return s;

}

void XuatKetQua(float x) { if(x>0) cout<<“Diện tích tam giác là: ”<<x; else cout<<“Các giá trị vừa nhập không tạo thành tam giác” ; } Bài tập:

Viết lại tất cả bài tập chương 3 và 4 dưới dạng hàm.

Các biến cục bộ của hàm TinhDienTichTamGiac

Giá trị trả về cho hàm TinhDienTichTamGiac

Lấy kết quả của hàm ñể tính toán

Page 67: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 67

CHƯƠNG V: MẢNG (Array)

V.1 Mảng (Array) Mảng là một tập hợp các phần tử cố ñịnh có cùng một kiểu ñược ñặt liên tiếp trong bộ nhớ , gọi là kiểu phần tử. Kiểu phần tử có thể là các kiểu bất kỳ: ký tự, số, ký tự…. Mỗi phần tử ñược xác ñịnh bởi một chỉ số biểu thị vị trí của phần tử trong mảng. Nều mảng có n phần tử thì chỉ số của các phần tử có giá trị từ 0 ñến n-1.

Số lượng phần tử trong mảng ñược gọi là kích thước của mảng. Kích thước của mảng là cố ñịnh và phải ñược xác ñịnh trước; nó không thể thay ñổi trong suốt quá trình thực hiện chương trình. Có thể chia mảng làm 2 loại: mảng 1 chiều và mảng nhiều chiều

V.2 Mảng 1 chiều

V.2.1. Khai báo mảng

V.2.1.1. Khai báo mảng với số phần tử xác ñịnh (khai báo tường minh)

Cú pháp:

Ý nghĩa: − Tên mảng: ñây là một tên ñặt ñúng theo quy tắc ñịnh danh (identify).

Tên này cũng mang ý nghĩa là tên biến mảng. − Số phần tử: là một hằng số nguyên, cho biết số lượng phần tử tối ña

trong mảng (kích thước của mảng). − Kiểu: kiểu dữ liệu của mỗi phần tử trong mảng.

Ví dụ:

int a[10]; //Khai báo một mảng a gồm 10 phần tử có kiểu số nguyên − Biểu diễn mảng a[10] trong bộ nhớ:

V.2.1.2. Khai báo mảng với số phần tử không xác ñịnh (khai báo không tường minh)

Cú pháp:

Khi khai báo, không cho biết rõ số phần tử của mảng, kiểu khai báo này thường ñược áp dụng trong các trường hợp: vừa khai báo vừa gán giá trị, khai báo mảng là tham số hình thức của hàm.

<Kiểu> <Tên mảng ><[số phần tử]>

<Kiểu> <Tên mảng> <[ ]>

Page 68: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 68

V.2.1.3. Vừa khai báo vừa gán giá trị

Cú pháp:

Ví dụ:

char str[] = "HELLO"; int nums[]={5,10,15}; // không khai báo tường minh kích cỡ của mảng

− Nếu vừa khai báo vừa gán giá trị thì mặc nhiên C++ sẽ hiểu số phần tử của mảng là số giá trị mà chúng ta gán cho mảng trong cặp dấu {}.

− Sử dụng hàm sizeof() ñể lấy số phần tử của mảng như sau:

Số phần tử=sizeof(tên mảng)/ sizeof(kiểu)

V.2.1.4. Khai báo mảng là tham số hình thức của hàm:

− Trong một số trường hợp ta cần phải truyền một mảng tới một hàm như là một tham số. Trong C++, việc truyền theo tham số giá trị một khối nhớ là không hợp lệ, ngay cả khi nó ñược tổ chức thành một mảng. Tuy nhiên chúng ta lại ñược phép truyền ñịa chỉ của nó, việc này cũng tạo ra kết quả thực tế giống thao tác ở trên nhưng nhanh hơn và hiệu quả hơn.

− ðể có thể nhận mảng là tham số thì khi khai báo hàm ta chỉ ñịnh trong phần tham số kiểu dữ liệu của mảng, tên mảng và cặp ngoặc vuông trống.

Ví dụ 1:

void procedure(int arg[ ])//tham số kiểu "mảng của int" và có tên arg.

Ví dụ 2: // arrays as parameters #include <iostream.h> void printarray (int arg[], int length) {

for (int n=0; n<length; n++) cout << arg[n] << " "; cout << "\n";

} void main () {

int firstarray[] = {5, 10, 15}; int secondarray[] = {2, 4, 6, 8, 10}; printarray (firstarray,3); printarray (secondarray,5);

} Ví dụ 3:

#include <iostream.h> #include <conio.h>

<Kiểu> <Tên mảng> [ ]= {Các giá trị cách nhau bởi dấu phẩy}

Page 69: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 69

#include <iomanip.h> #include <stdlib.h> const int SIZE=5; void input(int arr[SIZE]); void main() { int i,a[SIZE]; clrscr(); randomize(); input(a); cout <<"\n Mang da nhap \n"; for (i=0; i<SIZE; i++) cout <<setw(3)<<a[i]; getch(); } void input(int arr[SIZE]) { int i; for (i=0; i<SIZE; i++) arr[i]=random(100); }

V.2.2. Truy xuất từng phần tử của mảng

Mỗi phần tử của mảng ñược truy xuất ñến thông qua Tên biến mảng theo sau là chỉ số nằm trong cặp dấu ngoặc vuông [ ].

Cú pháp:

Ví dụ M[0], M[2], M[1][5],…

− Chỉ số của phần tử mảng là một biểu thức có giá trị là kiểu số nguyên.

− Với cách truy xuất thì này thì có thể coi như là một biến có kiểu dữ liệu là kiểu ñược chỉ ra trong khai báo biến mảng.

Ví dụ :

Vừa khai báo vừa gán trị cho 1 mảng 1 chiều các số nguyên. In mảng số nguyên này lên màn hình.

#include <iostream.h> #include <conio.h> void main() {

int n,i,j,tam; int dayso[ ]={66, 65, 69, 68, 67, 70}; clrscr(); n=sizeof(dayso); //Lấy số phần tử cout<< " Noi dung cua mang "; for (i=0;i<n;i++) cout<<dayso[i];

}

<array_Name>[<index1>][<index2>][…]{<indexN>]

Page 70: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 70

Ví dụ

ðổi một số nguyên dương thập phân thành số nhị phân. Việc chuyển ñổi này ñược thực hiện bằng cách lấy số ñó chia liên tiếp cho 2 cho tới khi bằng 0 và lấy các số dư theo chiều ngược lại ñể tạo thành số nhị phân. Ta sẽ dùng mảng một chiều ñể lưu lại các số dư ñó. Chương trình cụ thể như sau:

#include<iostream.h> #include<conio.h> void main() {

unsigned int N; unsigned int Du; unsigned int NhiPhan[20],K=0,i; cout<<"Nhap vao so nguyen N= ";cin>>N; do {

Du=N % 2; NhiPhan[K]=Du;/*Lưu số dư vào mảng ở vị trí K*/ K++; /*Tăng K lên ñể lần kế lưu vào vị trí kế*/ N = N/2;

} while(N>0); Cout<<"Dang nhi phan la: "; for(i=K-1;i>=0;i--)

cout<<setw(3)<<NhiPhan[i]; getch();

}

Ví dụ

Nhập vào một dãy n số và sắp xếp các số theo thứ tự tăng.

Trước hết, ta ñưa phần tử thứ nhất so sánh với các phần tử còn lại, nếu nó lớn hơn một phần tử ñang so sánh thì ñổi chỗ hai phần tử cho nhau. Sau ñó tiếp tục so sánh phần tử thứ tiếp theo với các phần tử từ thứ ba trở ñi ... cứ tiếp tục như vậy cho ñến phần tử thứ n-1.

#include<iostream.h> #include<stdio.h> void Nhap(int a[ ],int N) {

int i; for(i=0; i< N; i++)

Cout<<"Phan tu thu “<<i<<=<<&a[i]); } void InMang(int a[ ], int N) {

int i; for (i=0; i<N;i++)

cout<<setw(4)<<a[i]; cout<<"\n";

Page 71: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 71

} void SapXep(int a[ ], int N) {

int t,i; for(i=0;i<N-1;i++)

for(int j=i+1;j<N;j++) if (a[i]>a[j]) {

t=a[i]; a[i]=a[j]; a[j]=t;

} } void main() {

int b[20], N; cout<<"So phan tu thuc te cua mang N= "; cin>>N; Nhap(b,N); cout<<"Mang vua nhap: " ; InMang(b,N); SapXep(b,N); // Gọi hàm sắp xếp Cout<<"Mang sau khi sap xep: "; InMang(b,N); getch();

}

V.3 Mảng nhiều chiều. Mảng nhiều chiều có thể ñược coi như mảng của mảng, một mảng hai chiều có thể ñược xem như là một bảng hai chiều gồm các phần tử có kiểu dữ liệu cụ thể và giống nhau.

V.3.1. Khai báo

V.3.1.1. Khai báo mảng 2 chiều tường minh

Cú pháp:

Ví dụ:

int a[3][4];

<Kiểu> <Tên mảng><[Số dòng]><[Số cột]>

Page 72: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 72

V.3.1.2. Khai báo mảng 2 chiều không tường minh

ðể khai báo mảng 2 chiều không tường minh, ta vẫn phải chỉ ra số phần tử của chiều thứ hai (chiều cuối cùng).

Cú pháp:

Cách khai báo này cũng ñược áp dụng trong trường hợp vừa khai báo, vừa gán trị hay ñặt mảng 2 chiều là tham số hình thức của hàm.

V.3.2. Truy xuất từng phần tử của mảng 2 chiều

ðể truy xuất một phần tử của mảng hai chiều dùng cú pháp: Ví dụ: int a [3][5];

Ví dụ :

#define WIDTH 5 #define HEIGHT 3 int arr [HEIGHT][WIDTH]; int n,m; void main () { for (n=0;n<HEIGHT;n++) for (m=0;m<WIDTH;m++) a[n][m]=(n+1)*(m+1); } kết quả:

V.3.3. Khai báo mảng 2 chiều như một tham số:

Trong một số trường hợp, cần truyền một mảng cho một hàm như là một tham số. Trong C++ không thể truyền toàn bộ một khối bộ nhớ bằng một giá trị như là một tham số ñến một hàm, nhưng ñược phép truyền ñịa chỉ của nó, ñiều này rất hiệu quả. ðể chấp nhận những mảng như là những tham số của hàm thì khi khai hàm phải chỉ rõ trong các tham số của nó loại phần tử của mảng

Tên mảng[Chỉ số 1][Chỉ số 2]

<Kiểu> <Tên mảng> <[ ]><[Số phần tử chiều 2]>

Page 73: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 73

Ví dụ: //arrays as parameters #include <iostream> using namespace std; void printarray (int arg[], int length) { for (int n=0; n<length; n++) cout << arg[n] << " "; cout << "\n"; } void main () { int firstarray[] = {5, 10, 15}; int secondarray[] = {2, 4, 6, 8, 10}; printarray (firstarray,3); printarray (secondarray,5);

}

Ví dụ : Viết chương trình cho phép nhập 2 ma trận a, b có m dòng n cột, thực hiện phép toán cộng hai ma trận a,b và in ma trận kết quả lên màn hình (sử dụng hàm)

#include<iostream.h> #include<conio.h> void Nhap(int a[][10],int M,int N) {

int i,j; for(i=0;i<M;i++)

for(j=0; j<N; j++) {

cout<<"Phan tu o dong ”<<i<<”cot: “<<j; cin>>a[i][j];

} } void InMaTran(int a[ ][10], int M, int N) {

int i,j; for(i=0;i<M;i++) {

for(j=0; j< N; j++) cout<<setw(3)<<a[i][j];

cout<<"\n"; }

} /* Cong 2 ma tran A & B ket qua la ma tran C*/ void CongMaTran(int a[ ][10],int b[][10],int M,int N,int c[ ][10]) {

int i,j; for(i=0;i<M;i++)

Page 74: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 74

for(j=0; j<N; j++) c[i][j]=a[i][j]+b[i][j];

} void main() {

int a[10][10], b[10][10], M, N; int c[10][10];/* Ma tran tong*/ cout<<"So dong M= "; cin>>M; cout<<"So cot M= "; cin>>N; cout<<"Nhap ma tran A: “<<endl; Nhap(a,M,N); cout<<"Nhap ma tran B"<<endl; Nhap(b,M,N); cout<<"Ma tran A: "<<endl; InMaTran(a,M,N); cout<<"Ma tran B: "<<endl; InMaTran(b,M,N); congMaTran(a,b,M,N,c); cout<<"Ma tran tong C: "<<endl; InMaTran(c,M,N); getch();

}

Ví dụ : Nhập vào một ma trận 2 chiều gồm các số thực, in ra tổng của các phần tử trên ñường chéo chính của ma trận này.

Nhận xét: ma trận a có M dòng, N cột thì các phần tử của ñường chéo chính là các phần tử có dạng: a[i][i] với i thuộc [0…min(M,N)-1].

#include<conio.h> #include<stdio.h> void main() {

float a[10][10], T=0; int M, N, i,j, Min; clrscr(); cout<<"Nhap so dong: "; cin>>M ; cout<<"Nhap so cot? ";cin>>N; for(i=0;i<M;i++)

for(j=0; j<N; j++) {

cout<<"Phan tu o dong “<<i<<”cot” <<j; cin>>a[i][j];

} cout<<"Ma tran vua nhap:"<<endl; for(i=0;i<M;i++) {

for(j=0; j< N; j++) cout<<setw(3)<<a[i][j];

cout<<endl;

Page 75: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 75

} Min=(M>N) ? N: M; /* Tìm giá trị nhỏ nhất của M & N*/ for(i=0;i<Min;i++)

T=T+a[i][i]; cout<<"Tong cac phan tu o duong cheo chinh la:” <<T; getch();

}

V.3.4. Các phương pháp tìm kiếm và sắp xếp trên mảng:

V.3.4.1. Tìm kiếm:

a) Tìm kiếm trên mảng một chiều: Xây dưng một hàm int search(int a[ ],int n, int x). Tìm một giá trị x trên mảng a có n phần tử. Kết quả của hàm trả về vị trí tìm thấy, hàm <0 khi không tìm thấy. b) Tìm kiếm trên mảng hai chiều: Xây dưng một hàm int search2(int a[][COLS},int n, int x). Tìm một giá trị x trên mảng a có n dòng và COLS cột . Kết quả của hàm trả về vị trí tìm thấy, hàm <0 khi không tìm thấy.

V.3.4.2. Sắp xếp:

a) Sắp xếp trên mảng một chiều: Viết hàm sort(a[ ],n) dể sắp xếp một mảng n phần tử theo thứ tự tăng.

b) Sắp xếp trên mảng một chiều: Nguyên tắc sắp xếp mảng hai chiều là ñưa toàn bộ giá trị của mảng hai chiều ra một mảng một chiều, tiếp theo sắp xếp trên mảng một chiều này và cuối cùng là ñưa các giá trị từ mảng một chiều vào mảng hai chiều. Viết hàm sort2(a[][COLS],n) dể sắp xếp một mảng n dòng ,COLS cột phần tử theo thứ tự tăng.

Ví dụ

#include <iostream.h> #include <conio.h> #include <iomanip.h> #include <stdlib.h> const int ROWS=5; const int COLS=5; void input(int a[][COLS],int); void output(int a[][COLS],int); void sort(int a[ROWS][COLS]); void main() { int i,j,a[ROWS][COLS]; clrscr(); randomize(); input(a,ROWS); cout <<"\n Mang da nhap \n"; output(a,ROWS); sort(a); cout<<"\nMang sau khi sap xep tang:\n";

Page 76: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 76

output(a,ROWS); getch(); } void sort(int a[ROWS][COLS]) { int i,j,tam; int b[ROWS*COLS]; for (i=0;i<ROWS;i++) for(j=0;j<COLS;j++) b[j+i*COLS]=a[i][j]; for (i=0;i<ROWS*COLS-1;i++) for (j=i+1;j<ROWS*COLS;j++) if (b[i]>b[j]) { tam=b[i]; b[i]=b[j]; b[j]=tam; } for (i=0;i<ROWS;i++) for(j=0;j<COLS;j++) a[i][j]=b[j+i*COLS]; }

Page 77: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 77

BÀI TẬP

1) Viết chương trình nhập vào một dãy n số thực a[0], a[1],..., a[n-1], sắp xếp dãy số theo thứ tự giảm dần. Xuất ra dãy số sau khi sắp xếp.

2) Viết chương trình sắp xếp một mảng theo thứ tự tăng dần sau khi ñã loại bỏ các phần tử trùng nhau.

3) Viết chương trình nhập vào một mảng, hãy xuất ra màn hình: - Phần tử lớn nhất của mảng. - Phần tử nhỏ nhất của mảng. - Tính tổng của các phần tử trong mảng .

4) Viết chương trình nhập vào một dãy các số theo thứ tự tăng, nếu nhập sai quy cách thì yêu cầu nhập lại. In dãy số sau khi ñã nhập xong.

5) Viết chương trình nhập vào một ma trận (mảng hai chiều) các số nguyên, gồm m hàng, n cột.In ma trận ñó lên màn hình.

6) Viết chương trình ñể chuyển ñổi vị trí từ dòng thành cột của một ma trận (ma trận chuyển vị) vuông 4 hàng 4 cột. Sau ñó viết cho ma trận tổng quát cấp m*n.

Ví dụ:

1 2 3 4 1 2 9 1 2 5 5 8 2 5 4 5 9 4 2 0 3 5 2 8 1 5 8 6 4 8 0 6

7) Viết chương trình nhập vào một mảng số tự nhiên. Hãy xuất ra màn hình: - Dòng 1 : gồm các số lẻ, tổng cộng có bao nhiêu số lẻ. - Dòng 2 : gồm các số chẵn, tổng cộng có bao nhiêu số chẵn. - Dòng 3 : gồm các số nguyên tố. - Dòng 4 : gồm các số không phải là số nguyên tố.

8) Viết chương trình tính tổng bình phương của các số âm trong một mảng các số nguyên.

9) Viết chương trình thực hiện việc ñảo một mảng một chiều.

Ví dụ : 1 2 3 4 5 7 9 10 ñảo thành 10 9 7 5 4 3 2 1 .

10) Viết chương trình nhập vào hai ma trận A và B có cấp m, n. In hai ma trận lên màn hình. Tổng hai ma trận A và B là ma trận C ñược tính bởi công thức:

cij= a

ij +b

ij ( i=0,1,2,...m-1; j=0,1,2...n-1)

Tính ma trận tổng C và in kết quả lên màn hình.

11) Viết chương trình nhập vào hai ma trận A có cấp m, k và B có cấp k, n. In hai ma trận lên màn hình. Tích hai ma trận A và B là ma trận C ñược tính bởi công thức:

cij= a

i1*b

1j + a

i2 *b

2j + a

i3 *b

3j + ... + a

ik *b

kj (i=0,1,2,...m-1;j=0,1,2...n-1)

Tính ma trận tích C và in kết quả lên màn hình.

12) Nhập số phần tử và các phần tử nguyên dương của mảng a. a) In các số nguyên tố có trong mảng a. b) Sắp xếp các số chẵn trong mảng theo thứ tự tăng dần.

13) Viết chương trình nhập vào mảng a a) Viết hàm kiểm tra mảng ñối xứng không? Nếu có trả về 1 ngược lại trả về 0.

Page 78: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 78

b) Nhập mảng b, kiểm tra mảng b có phải là mảng con của mảng a không? Nếu có trả về số lần mảng b xuất hiện trong mảng a.

14) Viết chương trình theo dạng hàm: nhập vào mảng nguyên a có n phần tử với : a) Các số nguyên tố (nếu có) trong mảng phải < 100. b) Không có phần tử trùng nhau trong mảng. c) Tính tổng các số nguyên tố trong mảng.

15) Viết chương trình thực hiện các bước sau: a) Nhập mảng thực. b) Sắp xếp mảng thực theo thứ tự tăng dần. c) In phần tử có số lần xuất hiện nhiều nhất trong mảng.

16) Nhập vào mảng a, b theo kiểu cấp phát ñộng. Với: a) Các phần tử của a và b không trùng nhau. b) Xếp theo thứ tự tăng dần hai mảng a, b. c) Nối hai mảng này lại thành một mảng duy nhất sao cho mảng vẫn tăng.

17) Nhập vào một mảng a. Thực hiện sắp xếp sau: a) Tất cả các số lẻ nằm phía trước dãy số, các số chẵn nằm phía sau dãy số, các số

0 nằm giữa. b) Nhập vào một số x, hãy tìm số nguyên tố trong a bé hơn và gần với x nhất.

18) Viết chương trình nhập vào mảng một chiều có n số nguyên dương. Hãy cho biết số nào trong mảng có giá trị gần với trung bình cộng của toàn mảng.

19) Nhập vào một mảng có n số nguyên dương khác nhau. Hãy in ra tất cả các phần tử trong mảng có giá trị nhỏ hơn giá trị lớn nhất và lớn hơn giá trị nhỏ nhất của mảng.

20) Viết chương trình nhập ngẫu nhiên một mảng có n số nguyên dương. Nhập vào một số nguyên dương k. Hãy tính trung bình cộng của các phần tử trong mảng có giá trị lớn hơn hay bằng k.

21) Nhập vào một dãy số nguyên dương ngẫu nhiên (random) có n phần tử. Viết chương trình in ra số lớn hơn số nhỏ nhất của dãy và nhỏ hơn hay bằng với mọi số còn lại (nghĩa là tìm số nhỏ thứ hai trong dãy). Nếu n phần tử ñều bằng nhau thì thông báo: không tồn tại số cần tìm.

22) Viết chương trình nhập vào mảng số nguyên có n phần tử. Hãy tìm số chẵn lớn nhất và số lẻ nhỏ nhất.

23) Hãy nhập dãy n số nguyên dương có giá trị trong khoảng từ 1->100. Sắp xếp lại dãy số trên theo chiều tăng dần và loại bỏ các phần tử trùng nhau (chỉ giữ lại một giá trị trong số ñó)

24) Hãy nhập dãy n số nguyên dương có giá trị trong khoảng từ 1->100. Sắp xếp lại dãy số trên theo chiều tăng dần. Nhập vào một số x nguyên dương. Chèn x vào dãy sao cho thứ tự của dãy không thay ñổi.

25) Hãy nhập dãy n số nguyên dương có giá trị trong khoảng từ 1 -> 100. In ra màn hình các số chẵn xuất hiện trong dãy theo thứ tự tăng dần.

26) Hãy nhập dãy n số nguyên dương có giá trị trong khoảng từ 1->100. In ra giá trị trung bình cộng của các số chẵn xuất hiện trong dãy.

27) Viết chương trình thực hiện các công việc sau: a) Nhập vào một ma trận các giá trị thực kích thước mxn, với n và m ñược nhập

từ bàn phím. b) Tính tổng các số dương có trong mảng.

28) Viết chương trình thực hiện các công việc sau: a) Nhập vào một ma trận các giá trị thực kích thước nxn, với n ñược nhập từ bàn

phím.

Page 79: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 79

b) Tìm tất cả các vị trí trong ma trận thỏa yêu cầu sau: giá trị của ma trận tại vị trí ñó là giá trị lớn nhất của ma trận.

29) Viết chương trình thực hiện công việc sau: a) Nhập vào số nguyên dương N. Cấp phát ñộng một mảng nguyên A có N phần

tử. Thực hiện việc nhập giá trị cho mảng này. b) Tìm số nguyên tố lớn nhất có trong mảng. Nếu không có phải có thông báo.

30) Viết chương trình nhập vào ma trận vuông A(NxN), với N nhập vào từ bàn phím. a) In ra tổng các giá trị trong tam giác vuông trên của ma trận A (kể cả các phần

tử trên ñường chéo của ma trận A) b) In ma trận tích AxA ra màn hình.

Page 80: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 80

CHƯƠNG VI: KIỂU CON TRỎ

VI.1 Giới thiệu dữ liệu kiểu dữ liệu: Các biến mà chúng ta ñã biết và sử dụng trước ñây ñều là biến có kích thước và kiểu dữ liệu xác ñịnh, gọi là các biến biến tĩnh. Khi khai báo biến tĩnh, một lượng ô nhớ cho các biến này sẽ ñược cấp phát mà không cần biết trong quá trình thực thi chương trình có sử dụng hết lượng ô nhớ này hay không. Mặt khác, các biến tĩnh dạng này sẽ tồn tại trong suốt thời gian thực thi chương trình dù có những biến mà chương trình chỉ sử dụng 1 lần.

Một số hạn chế có thể gặp phải khi sử dụng các biến tĩnh: − Cấp phát ô nhớ dư, gây ra lãng phí ô nhớ. − Cấp phát ô nhớ thiếu, chương trình thực thi bị lỗi.

ðể tránh những hạn chế trên, ngôn ngữ C++ cung cấp cho người lập trình một loại biến ñặc biệt ñó là biến con trỏ (pointer) với các ñặc ñiểm: − Chỉ phát sinh trong quá trình thực hiện chương trình − Khi chạy chương trình, kích thước của biến, vùng nhớ và ñịa chỉ vùng nhớ

ñược cấp phát cho biến có thể thay ñổi. − Sau khi sử dụng xong có thể giải phóng ñể tiết kiệm chỗ trong bộ nhớ. − Kích thước của biến con trỏ không phụ thuộc vào kiểu dữ liệu, luôn có kích

thước cố ñịnh là 2 byte (tùy thuộc vào hệ ñiểu hành).

VI.2 Khai báo và sử dụng biến con trỏ

VI.2.1. Khai báo biến con trỏ

Cú pháp: − Ý nghĩa: Khai báo một biến có tên là <Tên con trỏ> dùng ñể chứa ñịa chỉ

của các biến có kiểu là <Kiểu>.

Ví dụ :

int *pa ; // Khai báo biến con trỏ pa kiểu int. float *pf; // Khai báo biến con trỏ pf kiểu float

Mỗi biến ñầu trỏ tới một kiểu dữ liệu khác nhau nhưng cả hai ñều là con trỏ và chúng ñều chiếm một lượng bộ nhớ như nhau, nhưng dữ liệu mà chúng trỏ tới không chiếm lượng bộ nhớ như nhau, một kiểu int, một kiểu float. − Giá trị của một biến con trỏ là ñịa chỉ mà nó trỏ tới. − Nếu chưa muốn khai báo kiểu dữ liệu mà con trỏ pa ñang chỉ ñến, ta có thể

khai báo:

void *pa;

− Khi cần, ta cho con trỏ pa chỉ ñến kiểu dữ liệu muốn khai báo. Tác dụng của khai báo này là dành ra 2 bytes bộ nhớ ñể cấp phát cho biến con trỏ pa.

VI.2.2. Các thao tác trên con trỏ

VI.2.2.1. Gán ñịa chỉ của biến cho biến con trỏ (&)

<Kiểu> * <Tên con trỏ>

Page 81: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 81

Toán tử & dùng ñể ñịnh vị con trỏ ñến ñịa chỉ của một biến ñang làm việc. Cú pháp:

Ý nghĩa: Gán ñịa chỉ của biến <Tên biến> cho con trỏ <Tên biến con trỏ>.

Ví dụ:

int a=25, x, y; x= a; //Gán giá trị của biến a cho biến x, . y=&a; //gán ñịa chỉ của biến a cho con biến y

VI.2.2.2. Toán tử tham chiếu (*)

Toán tử (*) ñể truy cập ñến nội dung của ô nhớ mà con trỏ chỉ tới.

Cú pháp: − Với cách truy cập này thì *<Tên biến con trỏ> có thể coi là một biến có

kiểu ñược mô tả trong phần khai báo biến con trỏ.

Ví dụ:

a=*p ;

Giải thích: biến a chứa giá trị trong ô nhớ 1776 mà con trỏ p trỏ tới mang giá trị 25

a = p; // biến a mang giá trị trong ô nhớ p :1776 a = *p; // biến a mang giá trị của ô nhớ do p trỏ tới: 25

Ví dụ:

<Tên biến con trỏ>=&<Tên biến>

*<Tên biến con trỏ>

Page 82: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 82

// my first pointer #include <iostream.h> #include<conio.h> void main () {

int a = 5, b = 15; int *p; //biến con trỏ p kiểu int p = &a; // con trỏ p chứa ñịa chỉ của a *p = 10;//gán giá trị 10 cho ô nhớ do p trỏ tới p = &b;// con trỏ p chứa ñịa chỉ của a *p = 20;//gán giá trị 10 cho ô nhớ do p trỏ tới cout << "a =" << a << endl; cout<<”b =" << b; getch();

} // kết quả a=10; b=20

Ví dụ // more pointers #include <iostream.h> #include<conio.h> void main () { int a = 5, b = 15; int *p1, *p2; p1 = &a; // p1 = ñịa chỉ của value1 p2 = &b; // p2 = ñịa chỉ của value2 *p1 = 10; // giá trị trỏ bởi p1 = 10 *p2 = *p1; // giá trị trỏ bởi p2 = giá trị trỏ bởi p1 p1 = p2; // p1 = p2 (phép gán con trỏ) *p1 = 20; // giá trị trỏ bởi p1 = 20 cout << "a = " << a << endl;

cout<<"b = " << b; getch();

}

VI.2.3. Một số phép toán trên con trỏ

Việc thực hiện các phép tính số học với con trỏ hơi khác so với các kiểu dữ liệu số nguyên khác vì kết quả phụ của các phép tính phụ thuộc vào kích thước của kiểu dữ liệu mà biến con trỏ trỏ tới.

VI.2.3.1. Phép gán con trỏ: .

− Hai con trỏ cùng kiểu có thể gán cho nhau Ví dụ:

int a, *p, *a ; float *f; a = 5 ; p = &a ; a = p ; /* ñúng */

Page 83: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 83

f = p ; /* sai do khác kiểu */ − Ta cũng có thể ép kiểu con trỏ theo cú pháp:

Chẳng hạn, ví dụ trên ñược viết lại:

int a, *p, *a ; float *f; a = 5 ; p = &a ; q = p ; /* ñúng */ f = (float*)p; /* ðúng nhờ ép kiểu*/

VI.2.3.2. Cộng, trừ con trỏ với một số nguyên

− Ta có thể cộng (+), trừ (-) 1 con trỏ với 1 số nguyên N nào ñó; kết quả trả về là 1 con trỏ. Con trỏ này chỉ ñến vùng nhớ cách vùng nhớ của con trỏ hiện tại N phần tử. Ví dụ:

int *pa; pa = (int*) malloc(20); /* Cấp phát vùng nhớ 20 byte=10 số nguyên*/ int *pb, *pc; pb = pa + 7; pc = pb - 3;

− Phép trừ 2 con trỏ cùng kiểu sẽ trả về 1 giá trị nguyên (int). ðây chính là khoảng cách (số phần tử) giữa 2 con trỏ ñó. Ví dụ :

pc-pa=4. − Lưu ý: không thể cộng 2 con trỏ với nhau. − Ta cũng có thể áp dụng các phép toán tăng/giảm (++/--) một ngôi trên biến

con trỏ

Ví dụ :

char *mychar; short *myshort; long *mylong; và chúng lần lượt trỏ tới ô nhớ 1000, 2000 and 3000.

(<Kiểu kết quả>*)<Tên con trỏ>

Page 84: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 84

ðiều này ñúng với cả hai phép toán cộng và trừ ñối với con trỏ. Ta có thể thu ñược kết quả như trên nếu viết:

mychar = mychar + 1; myshort = myshort + 1; mylong = mylong + 1;

Lưu ý: cả hai toán tử tăng (++) và giảm (--) ñều có quyền ưu tiên lớn hơn toán tử tham chiếu (*), vì vậy biểu thức sau ñây có thể dẫn tới kết quả sai:

*p++; *p++ = *q++;

− Lệnh *p++ tương ñương với *(p++) : thực hiện là tăng p (ñịa chỉ ô nhớ mà nó trỏ tới chứ không phải là giá trị trỏ tới).

− Lệnh *p++ = *q++; cả hai toán tử tăng (++) ñều ñược thực hiện sau khi giá trị của *q ñược gán cho *p và sau ñó cả q và p ñều tăng lên 1. Lệnh này tương ñương với:

*p = *q; p++; q++;

Ví dụ :

#include <iostream.h> #include <conio.h> void main() { const int SIZE=5; int i, *point, a[SIZE]={98,87,76,65,54}; clrscr(); point=&a[0]; // point=grade for (i=0;i<SIZE;i++) cout<<*(a+i)<<" "; (a) cout<<endl; for (i=0;i<SIZE;i++) cout<<*(point+i)<<" "; (b) cout<<endl; for (i=0;i<SIZE;i++) cout<<*(point)++<<" "; (c) getch(); } Cả 3 ñoạn lệnh (a), (b), (c) ñều có công dụng in giá trị các phần tử trong mảng a.

Lưu ý:

− Cách ghi *(point+i) không làm thay ñối giá trị trong point − Cách ghi *point++ thì làm thay ñổi giá trị của point sau mỗi lần thực hiện.

Page 85: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 85

VI.2.4. Con trỏ và mảng.

Giữa mảng và con trỏ có một sự liên hệ rất chặt chẽ. Những phần tử của mảng ñược xác ñịnh bằng chỉ số trong mảng, nhưng chúng cũng có thể ñược xác ñịnh qua biến con trỏ.

Tên của một mảng tương ñương với ñịa chỉ phần tử ñầu tiên của nó, giống như một con trỏ tương ñương với ñịa chỉ của phần tử ñầu tiên mà nó trỏ tới, vì vậy thực tế chúng hoàn toàn như nhau.

Ví dụ:

int numbers [20]; int * p;

p = numbers;

Ở ñây p và numbers là tương ñương và chúng có cùng thuộc tính, sự khác biệt duy nhất là ta có thể gán một giá trị khác cho con trỏ p trong khi numbers luôn trỏ ñến phần tử ñầu tiên trong số 20 phần tử kiểu int mà nó ñã ñược ñịnh nghĩa, vì vậy numbers là một biến con trỏ hằng. Do ñó lệnh gán sau ñây là không hợp lệ:

numbers = p;

vì numbers là một mảng (con trỏ hằng) và không có giá trị nào có thể ñược gán cho các hằng.

Vì con trỏ cũng có mọi tính chất của một biến nên tất cả các biểu thức có con trỏ trong ví dụ dưới ñây là hoàn toàn hợp lệ:

Ví dụ:

// more pointers #include <iostream.h> void main () {

int numbers[5]; int * p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; for (int n=0; n<5; n++) cout << numbers[n] << ", ";

} Trong bài "mảng", dùng dấu ngoặc vuông ñể chỉ ra phần tử của mảng cần truy xuất ñến. Cặp ngoặc vuông này ñược coi như là toán tử offset và ý nghĩa của chúng không ñổi khi ñược dùng với biến con trỏ.

Ví dụ:

a[5] = 0; // a [offset of 5] = 0 *(a+5) = 0; // pointed by (a+5) = 0

Page 86: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 86

Hai dòng lệnh trên hoàn toàn tương ñương và hợp lệ với a là mảng hay là con trỏ.

VI.2.4.1. Truy cập các phần tử mảng theo dạng con trỏ

ðể truy cập các phần tử của mảng theo dạng con trỏ ta dùng cú pháp sau:

Ví dụ: Cho mảng 1 chiều a có 5 phần tử kiểu số nguyên, truy cập các phần tử theo kiểu mảng và theo kiểu con trỏ.

#include <iostream.h> #include <conio.h> /* Nhập mảng bình thường*/ void NhapMang(int a[ ], int N) {

int i; for(i=0;i<N;i++) {

cout<<"a["<<i<<"] ="; cin>>a[i];

} } /* Nhập mảng theo dạng con trỏ*/ void NhapContro(int a[ ], int N) {

int i; for(i=0;i<N;i++) {

cout<<"a["<<i<<" ]="; cin>>a+i;

} } void main() {

int a[20],N,i; clrscr(); cout<<"So phan tu N= "; cin>>N; NhapMang(a,N); /* NhapContro(a,N)*/ cout<<"Truy cap theo kieu mang: "; for(i=0;i<N;i++)

cout<<setw(3)<<a[i]; cout<<"Truy cap theo kieu con tro: "; for(i=0;i<N;i++)

cout<<setw(3)<<*(a+i); getch();

}

&<Tên mảng>[0] tương ñương với <Tên mảng> &<Tên mảng> [<Vị trí>] tương ñương với <Tên mảng> + <Vị trí> <Tên mảng>[<Vị trí>] tương ñương với *(<Tên mảng> + <Vị trí>)

Page 87: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 87

VI.2.4.2. Truy xuất từng phần tử ñang ñược quản lý bởi con trỏ theo dạng mảng

Cú pháp:

Trong ñó <Tên biến> là biến con trỏ, <Vị trí> là 1 biểu thức số nguyên. Ví dụ:

Có mảng a gồm các phần tử kiểu số nguyên, khi viết: a[3] ; //truy xuất ñến phần tử thứ 4 trong mảng a.

− Nếu sử dụng chỉ số thì máy tính sẽ dựa vào chỉ số này và ñịa chỉ bắt ñầu của vùng nhớ dành cho mảng ñể xác ñịnh ñịa chỉ của phần tử mà ta muốn truy xuất tới

− ðể truy xuất phần tử a[3] thì máy tính sẽ xác ñịnh ñịa chỉ của phần tử này như sau:

&a[3]= a[0] + (3*2) //giả sử kiểu int chiếm 2 byte trong bộ nhớ.

Theo cách trên ta cũng có thể dùng một con trỏ lưu ñịa chỉ bắt ñầu của một mảng sau ñó dựa vào cách làm của máy ñể truy xuất ñến một phần tử của mảng. Ví dụ :

#include <iostream.h> #include <conio.h> void main() { const int SIZE=5; int i, *addr, a[SIZE]={98,87,76,65,54}; clrscr(); addr=&a[0]; for (i=0;i<SIZE;i++) cout<<a[i]<<" "; (a) cout <<endl; for (i=0;i<SIZE;i++) cout<<*(addr+i)<<" "; (b) getch(); }

Trong chương trình trên cả hai ñoạn lệnh (a) và (b) ñều có công dụng in các giá trị của mảng lên màn hình.

<Tên biến>[<Vị trí>] tương ñương với *(<Tên biến> + <Vị trí>) &<Tên biến>[<Vị trí>] tương ñương với (<Tên biến> + <Vị trí>)

Page 88: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 88

addr=&a[0] // ñịa chỉ bắt ñầu của mảng ñược gán vào con trỏ addr. (addr+i) // lưu ñịa chỉ của phần tử thứ i trong mảng và *(addr+i) // giá trị của phần tử thứ i trong mảng.

Bảng ý nghĩa giữa các hình thức truy xuất trên:

ðịa chi của phần tử thứ i Giá trị của phần tử thứ i Phần tử thứ i

của mảng a

Sử dụng toán tử

tham chiếu &

Sử dụng con trỏ addr

Sử dụng chỉ số Sử dụng con trỏ

a

0 &a[0] addr a[0] *(addr) 1 &a[1] addr+1 a[1] *(addr+1) 2 &a[2] addr+2 a[2] *(addr+2) 3 &a[3] addr+3 a[3] *(addr+3) 4 &a[4] addr+4 a[4] *(addr+4)

Lưu ý : − *(addr+3) hoàn toàn có ý nghĩa khác với *addr+3. − *(addr+3)= giá trị phần tử a[3] − *addr+3= giá trị của phần tử grade[0]+3 Qua chương trình trên ta thấy hoàn toàn có thể truy xuất mảng thông qua một con trỏ. Tuy nhiên việc khai báo con trỏ addr ñể sử dụng trong việc này thật sự không cần thiết, bởi nó có thể ñược thay thế bởi tên mảng a. Trong C++ khi ta khai báo một mảng thì tên của mảng sẽ chứa ñịa chỉ khởi ñầu của mảng ñó và ta không thể thay ñổi ñịa chỉ chứa trong tên mảng này vì vậy tên mảng ñược gọi là một hằng con trỏ. Vì vậy ñoạn lệnh (b) của chương trình trên ñược viết lại như sau:

#include <iostream.h> #include <conio.h> void main() { const int SIZE=5; int i, a[SIZE]={98,87,76,65,54}; clrscr(); for (i=0;i<SIZE;i++) cout<<a[i]<<" "; (a) cout <<endl; for (i=0;i<SIZE;i++) cout<<*(a+i)<<" "; (b) getch(); }

VI.2.5. Truyền ñịa chỉ cho tham số bởi con trỏ:

Chúng ta ñã biết một phương pháp truyền ñịa chỉ cho tham số ñó là sử dụng tham chiếu. Tuy nhiên, phương pháp này có một nhược ñiểm là lời gọi hàm không cho ta biết là dữ liệu truyền cho hàm là truyền tham chiếu hay cho tham trị. Chỉ khi nào nhìn vào nguyên mẫu hoặc dòng tiêu ñề của hàm ta mới phát hiện ñược.

Page 89: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 89

Ví dụ như dựa vào lời gọi hàm swap(i,j) ta không thể biết i,j truyền cho tham số loại nào, mà chỉ biết khi nhìn vào dòng nguyên mẫu: void swap(int& , int&) hay dòng tiêu ñề void swap(int& x, int& y)

Ngược lại, phương pháp truyền ñịa chỉ cho tham số bằng con trỏ ñược thể hiện rỏ ràng trong cả nguyên mẫu lẫn lời gọi hàm.

Ví dụ: Hàm swap ñể ñổi giá trị của hai biến truyền cho nó, các tham số của hàm ñược khai báo theo dạng con trỏ và lời gọi hàm trong trường hợp này phải sử dụng toán tử & trước tên biến truyền cho hàm.

#include <iostream.h> #include <conio.h> void swap(int*, int*); void main() { int i=5,j=10; clrscr(); cout <<"\n Truoc khi goi ham swap\n" <<"i= "<<i<<" " <<"j= "<<j <<endl; //I=5 j=10 swap(&i,&j); cout <<"Sau khi goi ham swap\n" <<"i= "<<i<<" " <<"j= "<<j <<endl; //I=10 j=5 getch(); } void swap(int* x,int* y) { int tam; tam=*x; *x=*y; *y=tam; }

Hãy lưu ý các dòng in ñậm trong chương trình ñể thấy ñược cách sử dụng và khai báo con trỏ

VI.3 Bộ nhớ ñộng Cho ñến nay, trong các chương trình của chúng ta, tất cả những phần bộ nhớ chúng ta có thể sử dụng là các biến các mảng và các ñối tượng khác mà chúng ta ñã khai báo. Kích cỡ của chúng là cố ñịnh và không thể thay ñổi trong thời gian chương trình chạy.

Một số trường hợp ta cần một lượng bộ nhớ mà kích cỡ của nó chỉ có thể ñược xác ñịnh khi chương trình chạy, ví dụ như trong trường hợp chúng ta nhận thông tin từ người dùng ñể xác ñịnh lượng bộ nhớ cần thiết. Một vùng bộ nhớ khác gọi là heap ñược cung cấp. Heap ñược sử dụng cho việc cấp phát ñộng các khối bộ nhớ trong thời gian thực thi chương trình. Vì thế heap cũng ñược gọi là bộ nhớ ñộng (dynamic memory).

Có hai toán tử ñược sử dụng cho việc cấp phát và thu hồi các khối bộ nhớ trên heap: Toán tử new và delete

Page 90: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 90

VI.3.1. Toán tử new

Toán tử new nhận một kiểu như là một ñối số và ñược cấp phát một khối bộ nhớ cho một ñối tượng của kiểu ñó. Nó trả về một con trỏ tới khối ñã ñược cấp phát.

Cú pháp:

− Lệnh thứ nhất ñược dùng ñể cấp phát bộ nhớ chứa một phần tử có kiểu type. − Lệnh thứ hai ñược dùng ñể cấp phát một khối nhớ (một mảng) gồm các phần tử

kiểu type.

Ví dụ: int *ptr = new int; // cấp phát tương ứng một khối cho lưu trữ một số nguyên char *str = new char[10]; //khối ñủ lớn cho lưu trữ một mảng 10 ký tự Ví dụ:

int * bobby; bobby = new int [5];

Trong trường hợp này hệ ñiều hành dành chỗ cho 5 phần tử kiểu int trong bộ nhớ và trả về một con trỏ trỏ ñến ñầu của khối nhớ. Vì vậy lúc này bobby trỏ ñến một khối nhớ hợp lệ gồm 5 phần tử int.

Sự khác nhau giữa việc khai báo một mảng với việc cấp phát bộ nhớ cho một con trỏ:

− Khai báo một mảng :kích thước của một mảng phải là một hằng, ñiều này giới hạn kích thước của mảng ñến kích thước mà chúng ta chọn khi thiết kế chương trình

− Cấp phát bộ nhớ ñộng cho phép cấp phát bộ nhớ trong quá trình chạy với kích thước bất kì.

Bộ nhớ ñộng ñược quản lý bởi hệ ñiều hành và trong các môi trường ña nhiệm có thể chạy một lúc vài chương trình, có một khả năng có thể xảy ra là hết bộ nhớ ñể cấp phát. Nếu ñiều này xảy ra và hệ ñiều hành không thể cấp phát bộ nhớ như chúng ta yêu cầu với toán tử new, một con trỏ null (zero) sẽ ñược trả về. Vì vậy khi dùng bộ nhớ ñộng ta cần phải kiểm tra xem con trỏ trả về bởi toán tử new có bằng null hay không

int * bobby; bobby = new int [5]; if (bobby == NULL)

{ // error assigning memory. Take measures. };

pointer = new type

hoặc pointer = new type [elements]

Page 91: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 91

VI.3.2. Toán tử delete.

Vì bộ nhớ ñộng chỉ cần thiết trong một khoảng thời gian nhất ñịnh, khi nó không cần dùng ñến nữa thì nó sẽ ñược giải phóng ñể có thể cấp phát cho các nhu cầu khác trong tương lai. ðể thực hiện việc này ta dùng toán tử delete. Cú pháp

− Lệnh thứ nhất: dùng ñể giải phóng bộ nhớ ñược cấp phát cho một phần tử bởi

toán tử new. − Lệnh thứ hai dùng ñể giải phóng một khối nhớ gồm nhiều phần tử (mảng).

ñược cấp phát bởi toán tử new

Ví dụ:

// rememb-o-matic #include <iostream.h> #include <stdlib.h> void main () {

char input [100]; int i,n; long * l, tong = 0; cout << "How many numbers do you want to type in? "; cin.getline (input,100); i=atoi (input); l= new long[i]; if (l == NULL) exit (1); for (n=0; n<i; n++) {

cout << "Enter number: "; cin.getline (input,100); l[n]=atol (input); } cout << "You have entered: "; for (n=0; n<i; n++) cout << l[n] << ", "; delete[];

} Kết quả :

How many numbers do you want to type in? 5 Enter number : 75 Enter number : 436 Enter number : 1067 Enter number : 8 Enter number : 32 You have entered: 75, 436, 1067, 8, 32,

Ví dụ :

delete pointer; hoặc delete [ ] pointer;

Page 92: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 92

Viết chương trình tạo giá trị cho một mảng ñộng và in mảng lên màn hình. Số phần tử của mảng ñược nhập vào khi thực hiện chương trình. #include <iostream.h> #include <conio.h> #include <stdlib.h> void main(void) { long int num_arr,i; int* arr; clrscr(); cout <<"\n cho biet so phan tu muon su dung"; cin >>num_arr; if (num_arr>0) { arr=new int[num_arr]; if (arr!=NULL) { randomize(); for (i=0;i<num_arr;i++) arr[i]=random(100); for (i=0;i<num_arr;i++) cout <<*(arr+i)<<" "; delete(arr); } else cout <<"khong du bo nho"; } getch(); }

VI.3.2.1. NULL

Null là một hằng số ñược ñịnh nghĩa trong thư viện C++ dùng ñể biểu thị con trỏ null. Trong trường hợp hằng số này chưa ñịnh nghĩa bạn có thể tự ñịnh nghĩa nó:

Dùng 0 hay NULL khi kiểm tra con trỏ là như nhau nhưng việc dùng NULL với con trỏ ñược sử dụng rất rộng rãi và ñiều này ñược khuyến khích ñể giúp cho chương trình dễ ñọc hơn.

VI.3.2.2. Bộ nhớ ñộng trong ANSI-C

Toán tử new và delete là ñộc quyền C++ và chúng không có trong ngôn ngữ C. Trong ngôn ngữ C, ñể sử dụng bộ nhớ ñộng phải sử dụng thư viện stdlib.h. Cách này cũng hợp lệ trong C++ và nó vẫn còn ñược sử dụng trong một số chương trình. − Hàm malloc: ðây là một hàm tổng quát ñể cấp phát bộ nhớ ñộng cho con

trỏ. Cấu trúc của nó như sau:

#define NULL 0

void * malloc (size_t nbytes);

Page 93: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 93

trong ñó nbytes là số byte muốn gán cho con trỏ. Hàm này trả về một con trỏ kiểu void*, vì vậy phải chuyển ñổi kiểu sang kiểu của con trỏ ñích. Ví dụ:

char * ronny; ronny = (char *) malloc (10);

ðoạn mã này cấp phát cho con trỏ ronny một khối nhớ 10 byte. Khi muốn cấp phát một khối dữ liệu có kiểu khác char (lớn hơn 1 byte) thì phải nhân số phần tử mong muốn với kích thước của chúng. ðể lấy kích thước ta sử dụng toán tử sizeof, toán tử này trả về kích thước của một kiểu dữ liệu cụ thể.

int * bobby; bobby = (int *) malloc (5 * sizeof(int));

ðoạn mã này cấp phát cho bobby một khối nhớ gồm 5 số nguyên kiểu int, kích cỡ của kiểu dữ liệu này có thể bằng 2, 4 hay hơn tùy thuộc vào hệ thống mà chương trình ñược dịch. − Hàm calloc: calloc hoạt ñộng rất giống với malloc, sự khác nhau chủ yếu là

khai báo mẫu của nó: Trong khai báo sử dụng hai tham số thay vì một. Hai tham số này ñược nhân với nhau ñể có ñược kích thước tổng cộng của khối nhớ cần cấp phát. Thông thường tham số thứ nhất (nelements) là số phần tử và tham số thức hai (size) là kích thước của mỗi phần tử. Ví dụ:

int * bobby;

bobby = (int *) calloc (5, sizeof(int));

Một ñiểm khác nhau nữa giữa malloc và calloc là calloc khởi tạo tất cả các phần tử của nó về 0. − Hàm realloc: thay ñổi kích thước của khối nhớ ñã ñược cấp phát cho một

con trỏ. Tham số pointer nhận vào một con trỏ ñã ñược cấp phát bộ nhớ hay một con trỏ null. Tham số size chỉ ñịnh kích thước của khối nhớ mới. Hàm này sẽ cấp phát size byte bộ nhớ cho con trỏ. Nó có thể phải thay ñổi vị vị trí của khối nhớ ñể có thể ñủ chỗ cho kích thước mới của khối nhớ, trong trường hợp này nội dung hiện thời của khối nhớ ñược copy tới vị trí mới ñể ñảm bảo dữ liệu không bị mất. Con trỏ mới trỏ tới khối nhớ ñược hàm trả về. Nếu không thể thay ñổi kích thước của khối nhớ thì hàm sẽ trả về một con trỏ null nhưng tham số pointer và nội dung của nó sẽ không bị thay ñổi. − Hàm free: Hàm này giải phóng một khối nhớ ñộng ñã ñược cấp phát bởi

malloc, calloc hoặc realloc.

void * calloc (size_t nelements, size_t size);

void * realloc (void * pointer, size_t size);

void free (void * pointer);

Page 94: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 94

BÀI TẬP

1. Viết chương trình nhập vào một mảng a gồm n phần tử nguyên. Sắp xếp mảng

theo chiều giảm dần (lưu ý sử dụng tên mảng như con trỏ và sử dụng con trỏ).

2. Hãy dùng một vòng for ñể nhập vào một ma trận vuông cấp n với các phần tử thực và tìm phần tử Max của ma trận này.

3. Viết hàm hoán vị hai biến thực a, b bằng cách sử dụng con trỏ (ñối vào là hai con trỏ). Viết chương trình chính nhập hai số thực a, b. Sử dụng hàm trên ñể

ñổi chỗ a và b.

4. Viết hàm giải hệ phương trình bậc nhất với sáu ñối vào là a, b, c, d, e, f và 2 ñối

ra là x và y.

5. Viết hàm tính giá trị ña thức:

f(x) = a0xn + … + an-1x + an. với ñối vào là biến nguyên n và mảng thực a.

6. Viết hàm cộng hai ma trận vuông a và b cấp n (sử dụng con trỏ).

7. Viết chương trình tính tích phân của f(x) trên ñoạn [a, b] bằng công thức hình

thang. Theo ñó, tích phân của f(x) trên [a, b] bằng: h * s. Trong ñó:

h là ñộ dài khoảng phân hoạch ñoạn [a, b] thành n khoảng.

s là tổng tất cả các f(a+i*h) với i từ 1 tới n.

Sử dụng hàm trên ñể tính tích phân trong ñoạn [-1, 4] của:

f(x) = (ex-2sin(x2))/ (1+x4). (nghiên cứu cách ñưa con trỏ vào giải quyết bài toán).

Page 95: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 95

CHƯƠNG VII: CHUỖI KÝ TỰ

VII.1 KHÁI NIỆM Ký tự là một dãy gồm các ký tự hoặc một mảng các ký tự ñược kết thúc bằng ký tự ‘\0’ (còn ñược gọi là ký tự NULL trong bảng mã ASCII). Các hằng ký tự ñược ñặt trong cặp dấu nháy kép “”. Ví dụ :

Chuỗi “Chao ban” ñược trong bộ nhớ như sau:

C h a o b a n \0

VII.2 KHAI BÁO

VII.2.1. Khai báo theo mảng

Cú pháp:

Ví dụ:

char Ten[12]; Trong khai báo này, bộ nhớ sẽ cung cấp 12+1 bytes ñể lưu trữ nội dung của ký tự Ten; byte cuối cùng lưu trữ ký tự ‘\0’ ñể chấm dứt .

Ghi chú:

− Chiều dài tối ña của biến là một hằng nguyên nằm trong khoảng từ 1 ñến 255 bytes.

− Chiều dài tối ña không nên khai báo thừa ñể tránh lãng phí bộ nhớ, nhưng cũng không nên khai báo thiếu.

VII.2.2. Khai báo theo con trỏ

Cú pháp:

Ví dụ:

char *Ten;

Trong khai báo này, bộ nhớ sẽ dành 2 byte ñể lưu trữ ñịa chỉ của biến con trỏ Ten ñang chỉ ñến, chưa cung cấp nơi ñể lưu trữ dữ liệu.

VII.2.3. Vừa khai báo vừa gán giá trị

Cú pháp: Ví dụ:

#include<iostream.h> #include<conio.h>

char <Biến> [Chiều dài tối ña]

char *<Biến>

char <Biến>[ ]=<”Hằng ”>

Page 96: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 96

void main() {

char Chuoi[]="Mau nang hay la mau mat em” ; cout<<"Vua khai bao vua gan trị :”<<Chuoi ; getch();

}

Lưu ý: ñược khai báo là một mảng các ký tự nên các thao tác trên mảng có thể áp dụng ñối với ký tự.

VII.3 CÁC THAO TÁC TRÊN CHUỖI KÝ TỰ

VII.3.1. Nhập xuất

− ðể nhập dữ liệu kiểu ký tự hoặc chuỗi từ bàn phím ta dùng hàm get()

Cú pháp:

//Dùng ñể nhập một ký tự từ bàn phím

hoặc //chờ nhận ký tự từ bàn phím

− Nhập một chuỗi ký tự tối ña n-1 ký tự từ bàn phím dùng hàm getline()

Cú pháp:

Hàm cho phép nhập vào biến st (st là một mảng char) n-1 ký tự, nếu nhập hơn thì phần ký tự còn lại sẽ ñể trên vùng ñệm

Ta cũng có thể dùng cin ñể nhập ký tự hoặc chuỗi nhưng trong trường hợp này nó không cho phép nhập ký tự trắng hoặc chuỗi có ký tự trắng.

Ví dụ :

#include <iostream.h> #include <conio.h> void main() { const int MAX=10; char st[MAX];

cout <<"Nhap mot chuoi toi da “<<(MAX-1)<<” ky tu "; in.getline(st,MAX); cout <<”Chuoi vua nhap la :” <<a; getch();

}

Lưu ý:

− Khi nhập dữ liệu nếu chúng ta nhập quá số ký tự qui ñịnh (MAX-1) thì có thể ảnh hưởng ñến những lệnh nhập sau hoặc có thể làm ảnh hưởng ñến hoạt ñộng của máy tính.

cin.get(<biến >)

cin.get()

cin.getline(st,n)

Page 97: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 97

− ðể tránh tình trạng này thường sau khi nhập dữ liệu bằng cin, cin.get, cin.getline ta sử dụng hàm cin.ignore:

Cú pháp :

Công dụng của hàm là bỏ qua tối ña n trong vùng ñệm hoặc khi gặp phím enter (\n)thì kết thúc lệnh cin.

Hoặc

Ví dụ :

#include <iostream.h> #include <conio.h> #include <iomanip.h> #include <stdlib.h> void main() { const int MAX=5; char a[MAX],b[MAX],i; clrscr(); cout <<"nhap mot chuoi"; cin.getline(a,5); //(1) cin.ignore(100,'\n'); cout <<"nhap mot chuoi"; in.getline(b,5); //(2)

cout<<a<<” “<<b; getch(); }

− Nếu ta nhập cho chuỗi a với nội dung: abcdefg và chuỗi b với nội dung hijkm thì chương trình in lên màn hình abcd hijk

− Thông thường ta chọn n là một số >=127 (bởi ta chỉ có thể nhập từ bàn phím tối ña 127 ký tự vào biến)

VII.3.2. Truy xuất từng ký tự trong chuỗi:

Do chuỗi là một mảng ký tự vì vậy ta có thể truy xuất chuỗi bằng chỉ số như truy xuất mảng.

Ví dụ :

Viết chương trình nhập , trong ñó có một hàm số nhận ñược truyền thông qua tham số khi hàm ñược gọi. Hàm trả về số nguyên âm của này. ñược nhập từ bàn phím.

#include <iostream.h> #include <conio.h> #include <string.h> int vowels(char str[]); void main()

cin.ignore(int n, ‘\n’)

fflush(stdin)

Page 98: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 98

{ const int MAX=80; char st[MAX]; clrscr(); cout <<"nhap mot chuoi"; cin.getline(st,MAX); cin.ignore(100,'\n'); cout<<"So nguyen am la: "<<vowels(st); getch(); } int vowels(char str[]) { int count=0,i=0; while (str[i]!='\0') { switch(str[i]) { case 'a': case 'e': case 'i': case 'o': case 'u': count++; } i++; } return count; }

Lưu ý: Hàm vowels trong trường hợp này không cần khai báo tham số ñể nhận số phần tử ñang có trong vì ta có thể nhận biết thông qua ký tự kết thúc .

Ví dụ : Viết chương trình nhập giá trị cho một biến chuỗi bằng cin.get()

#include <iostream.h> #include <conio.h> #include <string.h> void main() { const int MAX=80; char st[MAX],c; int i=0; clrscr(); cout <<"nhap mot chuoi \n"; while (i<MAX &&(c=cin.get())!='\n') st[i++]=c; st[i]='\0'; cout<<"Chuoi vua nhap la: "<<st; getch(); }

Page 99: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 99

Ví dụ:

Xây dựng hàm có hai tham số ñể nhận hai chuỗi sau ñó copy nội dung chuỗi thứ hai sang chuỗi thứ nhất.

void strcopy(char st1[], char st2[]) { int i=0; while (st2[i] != ‘\0’) { st1[i]=st2[i]; i++; } st1[i]=’\0’; }

Chương trình trên có thể viết lại cô ñộng và hiệu quả hơn như sau: void strcopy(char st1[], char st2[]) { int i=0; while (st2[i] = st1[i]) i++; }

VII.4 CON TRỎ VÀ CÁC HÀM TRÊN CHUỖI:

VII.4.1. Con trỏ và chuỗi

Con trỏ ñặc biệt hữu ích trong việc xây dựng các hàm xử lý chuỗi. Khi sử dụng con trỏ ñể truy xuất chuỗi thay vì dùng chỉ số thì chương trình sẽ cô ñọng và hiệu quả hơn.

Ví dụ: Viết lại hàm strcopy bằng cách sử dụng con trỏ.

void strcopy(char st1[], char st2[]) { while (*st1++ = *st2++); }

Ví dụ:

Viết một chương trình ñầy ñủ có sử dụng hàm strcopy ñược thể hiện như sau:

#include <iostream.h> #include <conio.h> #include <string.h> void strcopy(char st1[], char st2[]); void main() { const int MAX=80; char str2[MAX],c,str1[MAX]; int i=0; clrscr(); cout <<"nhap mot chuoi \n"; cin.getline(str2,MAX); cin.ignore(100,'\n');

Page 100: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 100

strcopy(str1,str2); cout<<"\n"<<str1; getch(); } void strcopy(char st1[], char st2[]) { while (*st1++=*st2++); }

VII.4.2. Các hàm thao tác trên chuỗi:

− ðể sử dụng các hàm thao tác với chuỗi ta khai báo thư viện string.h − Danh sách các hàm thao tác với chuỗi thông dụng:

Tên hàm Công dụng Ví dụ

Strcpy(string_var, string_exp) Copy nội dung của chuỗi string_exp (biểu thức chuỗi) sang chuỗi string_var (biến chuỗi)

strcpy(st,”abcd”)

strcat(string_var, string_exp) Ghép nội dung của chuỗi str_exp vào cuối chuỗi string_var

strcat(test,”abcd”)

strlen(str_exp) Trả về chiều dài thực của chuỗi, không tính ký tự ‘\0’

strlen(“Hello”)

strcmp(str_exp1,str_exp2) So sánh chuỗi str_exp1 và str_exp2, kết quả của hàm là:

số âm nếu str_exp1<str_exp2 số =0 nếu str_exp1=str_exp2 số dương nếu str_exp1<str_exp2

strcmp(“Anh”,”Lan”)

strncpy(str_var,str_exp,n) Copy n ký tự của string_exp sang str_var. Nếu str_exp vượt quá n ký tự thì ký tự ‘\0’ sẽ không ñược chèn vào cuối chuỗi str_var

strncpy(str1,str2,5)

strncmp(str_exp1,str_exp2,n) so sánh n ký tự ñầu của hai chuỗi str_exp1 và str_exp2. Kết quả trả về của hàm giống như hàm strcmp

strncmp(“Hey”,”Head”,2)

strchr(str_exp,char_exp) Trả về ñịa chỉ của ký tự ñầu tiên trong chuỗi str_exp giống với char_exp, hàm có kết quả NULL nếu char_exp không có trong str_exp

strchr(“Hello”,’e’)

Ví dụ :

#include <iostream.h> #include <conio.h> #include <string.h> #include <stdlib.h> void main() {

const int MAX=80; char str2[MAX],c,str1[MAX]; int n; clrscr(); cout <<"Nhap chuoi thu 1: ";

Page 101: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 101

cin.getline(str1,MAX); if (strlen(str1)>=MAX-1)

cin.ignore(100,'\n'); cout <<"Nhap chuoi thu 2: "; cin.getline(str2,MAX); n= strcmp(str1,str2); if (n<0)

cout <<str1 <<" nho hon " <<str2<<endl; else

if (n= =0) cout <<str1 <<" == " <<str2<<endl;

else cout <<str1 <<" lon hon " <<str2<<endl;

cout <<"Chieu dai chuoi thu 1 la: "<<strlen(str1)<<endl ; cout<<"Chieu dai chuoi thu 2 la: "<<strlen(str2)<<endl; strcat(str1,str2); //Sau khi noi chieu dai k0 duoc vuot qua pham vi

cout<<"Sau khi noi str2 vao str1 \n"<<"chuoi 1 la: "<<str1<<endl; strcpy(str1,str2); cout <<"Sau khi copy noi dung str2 vao str1 \n"

cout<<"chuoi 1 la: "<<str1<<endl; getch(); } − Các hàm thao tác trên ký tự trong thư viện ctype.h:

Tên hàm Công dụng Ví dụ

int isalpha(char_exp) kết quả của hàm có giá trị khác 0 khi char_exp là một chữ cái

isalpha(‘x’)

int isupper(char_exp) kết quả của hàm có giá trị khác 0 khi char_exp là một chữ cái hoa

isupper(‘a’)

int islower(char_exp) Trả về chiều dài thực của chuỗi, không tính ký tự ‘\0’

islower(‘a’)

int isdigit(char_exp) kết quả của hàm có giá trị khác 0 khi char_exp là một ký số

isdigit(‘a’)

int isascii(char_exp) kết quả của hàm có giá trị khác 0 nếu char_exp là một ký tự có mã ascii <128

isascii(‘a’)

int isspace(char_exp) kết quả của hàm có giá trị khác 0 khi char_exp là một khoảng trắng

isspace(‘ ’)

int isprint(char_exp) kết quả của hàm có giá trị khác 0 khi char_exp là một ký tự có thể in ñược

isprint(‘a’)

int iscntrl(char_exp) kết quả của hàm có giá trị khác 0 khi char_exp là một ký tự ñiều khiển

iscntrl(‘a’)

int ispunCt(char_exp) kết quả của hàm có giá trị khác 0 khi char_exp là một ký tự dấu

ispunct(‘!’)

int toupper(char_exp) Kết quả của hàm là ký tự hoa tương ứng với char_exp

toupper(‘a’)

int tolower(char_exp) Kết quả của hàm là ký tự thường tương ứng với char_exp

tolower(‘a’)

Page 102: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 102

Ví dụ

Viết chương trình in lên màn hình cho biết các ñặc tính ASCII, ký tự ñiều khiển, ký tự in ñược, ký tự dấu, của 256 ký tư trong bảng mã

#include <iostream.h> #include <conio.h> #include <ctype.h> #include <iomanip.h> void main() { const int MAX=80; int i; clrscr(); for (i=0;i<=255;i++) { if (i%22==0) {

getch(); clrscr(); cout<<setw(3)<<"MaKT"<<setw(8)<<"KT ASCII"

<<setw(8)<<"KT DK"<<setw(8)<<"KT IN"<<setw(8) <<"KT DAU"<<setw(8)<<"KY TU"<<endl;

} cout<<setw(3)<<i<<setw(8)<<isascii(char(i))<<setw(10)

<<iscntrl(char(i))<<setw(7)<<isprint(char(i))<<setw(8) <<ispunct(char(i));

if (isprint(char(i))) cout<<setw(7)<<char(i);

cout <<endl; } getch(); } − Các hàm chuyển ñổi chuỗi trong thư viện stdlib.h:

int atoi(str_exp) Chuyển một chuỗi sang số nguyên. Việc chuyển ñổi sẽ dừng khi gặp ký tự không phải là ký số

atoi(‘123a45’)

double atof(char_exp) Chuyển một chuỗi sang số double. Việc chuyển ñổi sẽ dừng khi gặp ký tự không thể chuyển sang dạng double ñược

char* itoa(int value, char *st, int radix)

Chuyển già trị số nguyên sang dạng chuởi và gán vào vùng nhớ mà con trỏ st ñang trỏ ñến. st là một con trỏ kiểu ký tự

Ví dụ:

Viết chương trình gồm hai hàm kiểm tra việc nhập số nguyên và số thực

#include <iostream.h> #include <conio.h>

Page 103: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 103

#include <stdlib.h> #include <ctype.h> int test_int(char*); int test_float(char *st); void main() { const int MAX=10; char str2[MAX]; int n; double x; clrscr(); cout <<"nhap mot so nguyen \n"; cin.getline(str2,MAX); if (strlen(str2)>=MAX-1) cin.ignore(100,'\n'); if (test_int(str2)) { n=atoi(str2); cout<<'\n'<<n<<endl; } else cout <<"Nhap sai"; cout <<"nhap mot so double \n"; cin.getline(str2,MAX); if (test_float (str2)) { x=atof(str2); cout<<'\n'<<x<<endl; } else cout <<"Nhap sai"; getch(); } int test_int(char *st) { while (isdigit(*(st))) st++; return !int(*(st)); } int test_float(char *st) { while (isdigit(*(st))|| *(st)=='.' ) st++; return !int(*(st)); }

Page 104: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 104

BÀI TẬP 1. Viết chương trình nhập một ký tự từ bàn phím, xuất ra màn hình mã ASCII của từng ký tự có trong .

2. Viết chương trình nhập một chuỗi ký tự từ bàn phím, xuất ra màn hình ñảo ngược của ñó. Ví dụ ñảo của “abcd egh” là “hge dcba”.

3. Viết chương trình nhập một chuỗi ký tự và kiểm tra xem chuỗi ñó có ñối xứng không.

Ví dụ : ABCDEDCBA là ñối xứng.

4. Nhập vào một chuỗi ký tự bất kỳ, hãy ñếm số lần xuất hiện của mỗi loại ký tự. 5. Viết chương trình nhập vào một chuỗi ký tự.

a) In ra màn hình từ bên trái nhất và phần còn lại của . Ví dụ: “Nguyễn Văn Minh” in ra thành:

Nguyễn

Văn Minh

b) In ra màn hình từ bên phải nhất và phần còn lại của . Ví dụ: “Nguyễn Văn Minh” in ra thành:

Minh

Nguyễn Văn 6. Viết chương trình nhập vào một chuỗi rồi xuất chuỗi ñó ra màn hình dưới dạng mỗi từ một dòng.

Ví dụ: “Nguyễn Văn Minh”

In ra :

Nguyễn Văn

Minh

7. Viết chương trình nhập vào một chuỗi, in ra ñảo ngược của chuỗi ñó theo từng từ.

Ví dụ : “Nguyễn Văn Minh” ñảo thành “Minh Văn Nguyễn”

8. Viết chương trình ñổi số tiền từ số thành chữ. 9. Viết chương trình nhập vào họ và tên của một người, cắt bỏ các khoảng trống không cần thiết (nếu có), tách tên ra khỏi họ và tên, in tên lên màn hình. Chú ý ñến trường hợp cả họ và tên chỉ có một từ.

10. Viết chương trình nhập vào họ và tên của một người, cắt bỏ các khoảng trắng bên phải, trái và các khoảng trắng không có nghĩa trong . In ra màn hình toàn bộ họ tên người ñó dưới dạng chữ hoa, chữ thường.

11. Viết chương trình nhập vào một danh sách họ và tên của n người theo kiểu chữ thường, ñổi các chữ cái ñầu của họ, tên và chữ lót của mỗi người thành chữ hoa. In kết quả lên màn hình.

12. Viết chương trình nhập vào một danh sách họ và tên của n người, tách tên từng người ra khỏi họ và tên rồi sắp xếp danh sách tên theo thứ tự từ ñiển. In danh sách họ và tên sau khi ñã sắp xếp.

Page 105: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 105

CHƯƠNG VIII: ðỆ QUY

VIII.1 ðịnh nghĩa Một hàm ñược gọi là ñệ quy nếu bên trong thân hàm có lệnh gọi ñến chính nó.

Ví dụ:

ðịnh nghĩa giai thừa của một số nguyên dương n như sau:

n!=1* 2 * 3 *…* (n-1) *n = (n-1)! *n (với 0!=1)

Như vậy, ñể tính n! ta thấy nếu n=0 thì n!=1 ngược lại thì n!=n * (n-1)! Với ñịnh nghĩa trên thì hàm ñệ quy tính n! ñược viết:

#include <iostream.h> #include <conio.h>

/*Hàm tính n! bằng ñệ quy*/

unsigned int giaithua_dequy(int n) {

if (n= =0) return 1;

else return n*giaithua_dequy(n-1);

}

/*Hàm tính n! không ñệ quy*/

unsigned int giaithua_khongdequy(int n) {

unsigned int kq,i; kq=1; for (i=2;i<=n;i++)

kq=kq*i; return kq;

} void main() {

int n; clrscr(); cout<<” Nhap so n can tinh giai thua "; cin>>n ; cout<<"Goi ham de quy: "<<giaithua_dequy(n); cout<<"Goi ham khong de quy: "<<giaithua_khongdequy(n); getch();

}

VIII.2 Phân loại ñệ quy: Các hàm ñệ quy thường gặp có thể thuộc một trong bốn loại hàm ñệ quy ðệ quy tuyến tính, ñệ quy nhị phân, ñệ quy phi tuyến, ñệ quy tương hỗ.

Page 106: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 106

VIII.2.1. ðệ quy tuyến tính

Chương trình con ñệ quy tuyến tính là chương trình con ñệ quy trực tiếp ñơn giản nhất có dạng : Cú pháp:

Giải thích: P ≡ { NẾU thỏa <ñiều kiện dừng >

thì thực hiện S ; ngược lại { thực hiện S*; gọi P} } Với S , S* là các thao tác không ñệ quy .

Ví dụ:

Hàm FAC(n) tính số hạng n của dãy n! + Dạng hàm trong ngôn ngữ mã giả :

{ Nếu n = 0 thì FAC = 1 ; /* trường hợp neo */ Ngược lại FAC = n*FAC(n-1) }

+ Dạng hàm trong ngôn ngữ C++ : int FAC( int n ) {

if ( n == 0 ) return 1 ;

else return ( n * FAC(n-1 )) ;

}

Ví dụ:

Chương trình con tính USCLN của 2 số dựa vào thuật toán Euclide :

+ Dạng hàm trên ngôn ngữ toán học :

USCLN(m , n ) = USCLN(n , m mod n ) khi n ≠ 0 USCLN(m , 0) = m

+ Dạng hàm trong ngôn ngữ mã giả :

Nếu n = 0 thì USCLN = m Ngược lại USCLN = USCLN( n , m mod n ) ;

+Dạng hàm trong C++ :

int USCLN( int m , int n ) {

KDL TenHam(<Danh sách tham số>) { if(<ðiều kiện dừng>)

{ … return <Giá trị trả về>; } … …TenHam(<Danh sách tham số>); …

}

Page 107: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 107

if(n == 0 ) return (m) ;

else return ( USCLN( n , m mod n)) ;

} Ví dụ:

Tính S(n)=1+2+3+…+n

long int TongSn(int n) { if(n==0)

return 0; return

(TongSn(n-1)+n); }

VIII.2.2. ðệ quy nhị phân

Chương trình con ñệ quy nhị phân là chương trình con ñệ quy trực tiếp có dạng:

P ≡ { NẾU thỏa ñiều kiện dừng thì thực hiện S ; Ngược lại { thực hiện S* ; gọi P ; gọi P }

} Với S , S* là các thao tác không ñệ quy

Cú pháp: Ví dụ:

Tính số hạng thứ n của dãy Fibonaci ñược ñịnh nghĩa như sau:

f(0)=f(1)=1 f(n)=f(n-1)+f(n-2), n>1 long int Fibonaci(int n) { if(n= =0 || n= =1)

return 1; return

(Fibonaci(n-1)+Fibonaci(n-2)); }

KDL TenHam(<Danh sách tham số>) { if(<ðiều kiện dừng>)

{ … return <Giá trị trả về>; } … …TenHam(<Danh sách tham số>); … …TenHam(<Danh sách tham số>);

}

Page 108: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 108

VIII.2.3. ðệ quy phi tuyến

Chương trình con ñệ quy phi tuyến là chương trình con ñệ quy trực tiếp mà lời gọi ñệ quy ñược thực hiện bên trong vòng lặp . P ≡ { for giá tri ñầu to giá trị cuối do

thực hiện S ; if ( thỏa ñiều kiện dừng ) then thực hiện S* else gọi P } //Với S , S* là các thao tác không ñệ quy Cú pháp:

Ví dụ: Tìm số hạng thứ n của dãy:

x(0)=0 x(n)=n2x(0)+(n-1)2x(0)+(n-1)2x(0)+ +22x(n-2)+12x(n-1) long int TinhXn(int n) { if(n==0)

return 1; long int s=0; for(int i=1; i<=n; i++) s+=i*i*TinhXn(n-i); return s; }

KDL TenHam(<Danh sách tham số>) { for(int i=1; i<=n; i++) {

… if(<ðiều kiện dừng>)

{ …

} else {

… TenHam(<Danh sách tham số>); …

} }

}

Page 109: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 109

VIII.2.4. ðệ quy hỗ tương

Cú pháp: Ví dụ:

Tìm số hạng thứ n của dãy sau: x(0)=1 y(0)=0 x(n)=x(n-1)+y(n-1) khi n>0 y(n)=3*x(n-1)-2*y(n-1) khi n>0 long int TinhYn(int n); long int TinhXn(int n) {

if(n==0) return 1;

return TinhXn(n-1)+TinhYn(n-1); } long int TinhYn(int n) {

if(n==0) return 0;

return (3*TinhXn(n-1)-2*TinhYn(n-1)); }

VIII.3 ðặc ñiểm cần lưu ý khi viết hàm ñệ quy Hàm ñệ quy phải có 2 phần: − Phần dừng hay phải có trường hợp nguyên tố. Trong ví dụ ở trên thì

trường hợp n=0 là trường hợp nguyên tố. − Phần ñệ quy: là phần có gọi lại hàm ñang ñược ñịnh nghĩa. Trong ví

dụ trên thì phần ñệ quy là n>0 thì n! = n * (n-1)! Sử dụng hàm ñệ quy trong chương trình sẽ làm chương trình dễ ñọc, dễ hiểu và vấn ñề ñược nêu bật rõ ràng hơn. Tuy nhiên trong ña số trường hợp thì hàm ñệ quy tốn bộ nhớ nhiều hơn và tốc ñộ thực hiện chương trình chậm hơn không ñệ quy.

KDL TenHam2(<Danh sách tham số>); KDL TenHam1(<Danh sách tham số>) { …

TenHam2(<Danh sách tham số>); …

} KDL TenHam2(<Danh sách tham số>) { …

TenHam1(<Danh sách tham số>); …

}

Page 110: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 110

Tùy từng bài có cụ thể mà người lập trình quyết ñịnh có nên dùng ñệ quy hay không (có những trường hợp không dùng ñệ quy thì không giải quyết ñược bài toán).

Page 111: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 111

BÀI TẬP 1. Nhập n>=0. Tính S(n)=2+4+ … + (n+2). 2. Nhập n>=0. Tính S(n)=1+3+ … + (n+1). 3. Nhập n>=0. Tính S(n)=12+22+32+ … + n2. 4. Nhập n>=0. Tính S(n)=12-22+32-42 … +(-1)n-1n2.

5. Nhập n>=0. Tính n

nS1

...3

1

2

11)( ++++=

6. Nhập n>=0. Tính n

nS2

1...

4

1

2

1)( +++=

7. Nhập n>=0. Tính 12

1...

5

1

3

11)(

+++++=

nnS

8. Nhập n>=0. Tính )1(

1...

32

1

21

1)(

+×++

×+

×=

nnnS

9. Nhập n>=0. Tính 1

...3

2

2

1)(

++++=n

nnS

10. Nhập n>=0. Tính 22

12...

4

3

2

1)(

+

++++=

n

nnS

11. Tính T(n)=1*2*3*…*n 12. Nhập n>=0. Tính S(n)=1+1×2+1×2×3+ … +1×2×3×…×n 13. Nhập x,n. Tính T(x,n)=xn 14. Nhập x,n. Tính S(x,n)=x+x2+x3+ … +xn 15. Nhập x,n. Tính S(x,n)=x2+x4+x6+ … +x2n 16. Nhập x,n. Tính S(x,n)=x+x3+x5+ … +x2n+1

17. Nhập n. Tính n

nS+++

++++

++

+=...21

1...

321

1

21

11)(

18. Nhập x,n. Tính n

xxxxnxS

n

+++++

+++

++=

...21...

32121),(

32

19. Nhập x,n. Tính !

...!3!2

),(32

n

xxxxnxS

n

++++=

20. Nhập x,n. Tính !2

...!4!2

),(242

n

xxxxnxS

n

++++=

21. Nhập x,n. Tính )!12(

...!5!3

),(1253

+++++=

+

n

xxxxnxS

n

22. Nhập n. Tính 2...222)( ++++=nS , có n dấu căn lồng nhau.

23. Nhập n. Tính 12...)2()1()( +++−+−+= nnnnS, có n dấu căn lồng nhau.

24. Nhập n. Tính nnnS +−++++= )1(...321)( , có n dấu căn lồng nhau. 25. Hãy ñếm số lượng chữ số của số nguyên dương n. 26. Hãy ñếm tính tổng các chữ số của số nguyên dương n. 27. Hãy ñếm tính tích các chữ số của số nguyên dương n. 28. Hãy ñếm số lượng chữ số lẻ của số nguyên dương n. 29. Hãy ñếm tính tổng các chữ số lẻ của số nguyên dương n. 30. Hãy ñếm tính tích các chữ số lẻ của số nguyên dương n. 31. Hãy ñếm số lượng chữ số chẵn của số nguyên dương n. 32. Hãy ñếm tính tổng các chữ số chẵn của số nguyên dương n.

Page 112: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 112

33. Hãy ñếm tính tích các chữ số chẵn của số nguyên dương n. 34. Có 3 cột ñánh số 1, 2 và 3. ðầu tiên cột 1 có n ñĩa ñược xếp sao cho ñĩa lớn nằm

bên dưới và hai cột còn lại không chứa ñĩa nào. Yêu cầu: Chuyển tất cả các ñĩa từ cột 1 sang cột 3, ñược phép sử dụng cột 2 làm trung gian, mỗi lần chỉ chuyển một ñĩa và phải tuân thủ nguyên tắc ñĩa lớn hơn nằm bên dưới.

35. Cho tập hợp A có n phần tử ñược ñánh số từ 1, 2, 3, …, n. Một hoán vị của tập hợp A là một dãy a1, a2, …, an. Trong ñó ai∈A và chúng ñôi một khác nhau. Hãy viết hàm xuất ra tất cả các hoán vị của A.

36. (Bài toán 8 hậu) Cho bàn cờ vua kích thước 8×8. Hãy sắp 8 quân hậu vào bàn cờ sao cho không có bất kỳ 2 quân hậu nào có thể ăn nhau.

37. (Bài toán mã ñi tuần) Cho bàn cờ vua kích thước 8×8. Hãy di chuyển quân mã trên khắp bàn cờ sao cho mỗi ô ñi qua ñúng 1 lần.

38. Cho mảng 1 chiều có n số nguyên. Viết hàm ñệ qui xuất mảng. 39. Cho mảng 1 chiều có n số nguyên. Viết hàm ñệ qui xuất mảng ngược. 40. Cho mảng 1 chiều có n số thực. Viết hàm ñệ qui ñếm số lượng các giá trị nguyên

dương có trong mảng. 41. Cho mảng 1 chiều có n số nguyên. Viết hàm ñệ qui ñếm số lượng các giá trị phân

biệt có trong mảng. 42. Cho mảng 1 chiều có n số thực. Viết hàm ñệ qui tính tổng các giá trị có trong

mảng. 43. Cho mảng 1 chiều có n số thực. Viết hàm ñệ qui tính tổng các giá trị dương có

trong mảng. 44. Cho mảng 1 chiều có n số thực. Viết hàm ñệ qui tính tổng các giá trị âm có trong

mảng. 45. Cho mảng 1 chiều có n số thực. Viết hàm ñệ qui tính tổng các giá trị chẵn có trong

mảng. 46. Cho mảng 1 chiều có n số thực. Viết hàm ñệ qui tính tổng các giá trị lẻ có trong

mảng. 47. Cho mảng 1 chiều có n số thực. Viết hàm ñệ qui tính tổng các giá trị lớn hơn giá trị

ñứng trước có trong mảng. 48. Cho mảng 1 chiều có n số thực. Viết hàm ñệ qui kiểm tra mảng có thoả tính chất

“toàn giá trị âm”. 49. Cho mảng 1 chiều có n số thực. Viết hàm ñệ qui kiểm tra mảng có thoả tính chất

“toàn giá trị dương”. 50. Cho mảng 1 chiều có n số thực. Viết hàm ñệ qui tìm giá trị lớn nhất có trong mảng. 51. Cho mảng 1 chiều có n số thực. Viết hàm ñệ qui tìm vị trí của giá trị lớn nhất có

trong mảng. 52. Cho mảng 1 chiều có n số thực. Viết hàm ñệ qui sắp xếp các giá trị của mảng theo

thứ tự tăng dần. 53. Cho mảng 1 chiều có n số thực. Viết hàm ñệ qui sắp xếp các giá trị của mảng theo

thứ tự giảm dần. 54. Cho mảng 1 chiều có n số thực. Viết hàm ñệ qui sắp xếp các giá trị chẵn của mảng

theo thứ tự tăng dần còn các giá trị lẻ vẫn giữ nguyên vị trí của nó. 55. Cho mảng 1 chiều có n số thực. Viết hàm ñệ qui sắp xếp các giá trị lẻ của mảng

theo thứ tự giảm dần còn các giá trị chẵn vẫn giữ nguyên vị trí của nó.

Page 113: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 113

CHƯƠNG IX: KIỂU CẤU TRÚC (STRUCTURE)

IX.1 KIỂU CẤU TRÚC

IX.1.1. Khái niệm

Kiểu cấu trúc (coøn goïi kieåu caáu truùc laø kieåu record) là kiểu dữ liệu bao gồm nhiều thành phần có kiểu khác nhau, mỗi thành phần ñược gọi là một trường (field)

Sự khác biệt giữa kiểu cấu trúc và kiểu mảng là: các phần tử của mảng là cùng kiểu còn các phần tử của kiểu cấu trúc có thể có kiểu khác nhau.

IX.1.2. ðịnh nghĩa kiểu cấu trúc

Cú pháp:

Ví dụ:

Mỗi sinh viên cần ñược quản lý bởi các thông tin: mã số sinh viên, họ tên, ngày tháng năm sinh, giới tính, ñịa chỉ thường trú. Ta có thể khai báo một struct gồm các thông tin trên.

Ví dụ: struct products { char name [30]; float price; };

IX.1.3. Khai báo biến cấu trúc

Cú pháp:

Ví dụ:

products apple; products orange, melon;

struct <Tên cấu trúc> {

<Kiểu> <Trường 1> ; <Kiểu> <Trường 2> ; …….. <Kiểu> <Trường n> ;

};

struct <Tên cấu trúc> {

<Kiểu> <Trường 1> ; <Kiểu> <Trường 2> ; …….. <Kiểu> <Trường n> ;

}danh sách tên biến cấu trúc;

Page 114: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 114

− Chúng ta ñã ñịnh nghĩa cấu trúc products với hai trường: name và price, mỗi trường có một kiểu khác nhau.

− Chúng ta cũng ñã sử dụng tên của kiểu cấu trúc products ñể khai báo ba ñối tượng có kiểu ñó : apple, orange và melon.

− Sau khi ñược khai báo, products trở thành một tên kiểu hợp lệ giống các kiểu cơ bản như int, char hay short.

− Trường tuỳ chọn <danh sách tên biến cấu trúc> có thể nằm ở cuối của phần khai báo cấu trúc, dùng ñể khai báo trực tiếp ñối tượng có kiểu cấu trúc.

Ví dụ:

ðể khai báo các ñối tượng apple, orange và melon trong ví dụ trên, ta cũng có thể làm theo cách sau:

struct products {

char name [30]; float price;

} apple, orange, melon;

IX.2 CÁC THAO TÁC TRÊN BIẾN KIỂU CẤU TRÚC

IX.2.1. Truy xuất ñến từng trường của biến cấu trúc

Cú pháp:

− Khi sử dụng cách truy xuất này thì các thao tác trên <Biến cấu trúc>.<Tên trường> giống như các thao tác trên các biến của kiểu dữ liệu của <Tên trường>

Ví dụ:

Viết chương trình cho phép ñọc dữ liệu từ bàn phím cho biến mẩu tin SinhVien và in biến mẩu tin ñó lên màn hình:

#include<iostream.h> #include<conio.h> #include<string.h>

struct SinhVien {

char MSSV[10]; char HoTen[40]; unsigned int NamSinh ; char DiaChi[40];

}; /* Hàm in lên màn hình 1 mẩu tin SinhVien*/ void InSV(SinhVien sv) {

cout<<"MSSV: “<<sv.MSSV<<endl; cout<<”Ho va ten: “<<sv.HoTen<<endl;

<Biến cấu trúc>.<Tên trường>

Page 115: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 115

cout<<“ Nam Sinh:”<<sv.NamSinh <<endl; cout<<”Dia Chi: “<<sv.DiaChi;

} void main() {

SinhVien SV, s; cout<<"Nhap MSSV: "; cin>>SV.MSSV; cout<<"Nhap Ho va ten: "; cin>>SV.HoTen; cout<<"Nam sinh: "; cin>>SV.NamSinh; cout<<"Dia chi: "; cout>>SV.DiaChi; InSV(SV); getch();

}

IX.2.2. Khởi tạo giá trị cho biến cấu trúc

Việc khởi tạo giá trị cho biến cấu trúc ñược thực hiện trong lúc khai báo biến cấu trúc. Các trường của cấu trúc ñược khởi tạo ñặt giữa 2 dấu { }, chúng ñược phân cách nhau bởi dấu phẩy (,).

Ví dụ: struct NgayThang {

unsigned char Ngay; unsigned char Thang; unsigned int Nam;

};

Khởi tạo biến cấu trúc NgaySinh: NgayThang NgaySinh ={29, 8, 1986};

IX.2.3. Mảng cấu trúc:

Khi cần lưu trữ thông tin của nhiều ñối tượng, thì biến cấu trúc là một công cụ rất thuận lợi.

Ví dụ:

Cần lưu trữ thông tin họ tên, ñiểm môn toán, ñiểm môn hóa, ñiểm môn lý của các thí sinh trong một kỳ thi. ðể làm công việc trên, thay vì phải sử dụng 3 mảng một chiều ñể lưu trữ ta có thể dùng một mảng một chiều kiểu cấu trúc ñể lưu trữ các thông tin này

Khi ñó mỗi phần tử của mảng là một biến kiểu cấu trúc. Ta có thể khai báo một mảng cấu trúc như sau: struct danhsach{ int sbd;

char hoten[25]; float toan,ly,hoa; }; danhsach bangdiem[50];

Ví dụ:

Viết chương trình cho phép nhập và in bảng ñiểm của thí sinh lên màn hình.

Page 116: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 116

#include <iostream.h> #include <conio.h> #include <string.h> #include <iomanip.h> const int MAXNAME=25,NUMREC=3;

struct danhsach { int sbd; char hoten[MAXNAME]; float toan,ly,hoa; }; void main() { danhsach bangdiem[NUMREC]; int i; clrscr(); cout <<"NHAP BANG DIEM CUA SINH VIEN\n"; for (i=0;i<NUMREC;i++) {

cout <<"So bao danh: "; cin>> bangdiem[i].sbd; cin.ignore(100,'\n'); cout <<"Ho va ten: "; cin.getline(bangdiem[i].hoten,MAXNAME); if(strlen(bangdiem[i].hoten)>=MAXNAME-1)

cin.ignore(100,'\n'); cout <<"Diem toan: "; cin >> bangdiem[i].toan; cout <<"Diem ly: "; cin >> bangdiem[i].ly; cout <<"Diem hoa "; cin >> bangdiem[i].hoa;

} clrscr(); cout <<" ------BANG DIEM CUA SINH VIEN-----\n"; cout <<"So bao danh Ho ten Diem toan Diem ly Diem hoa\n"; for (i=0;i<NUMREC;i++) { cout <<setw(5)<<bangdiem[i].sbd<<setw(20) <<bangdiem[i].hoten<<setw(10) <<bangdiem[i].toan<<setw(12) <<bangdiem[i].ly<<setw(14) << bangdiem[i].hoa<<endl; } getch(); }

Ví dụ:

// array of structures #include <iostream.h> #include <stdlib.h> #define N_MOVIES 5

Page 117: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 117

struct movies_t { char title [50]; int year; } films [N_MOVIES]; void printmovie (movies_t movie); void main () { char buffer [50]; int n; for (n=0; n<N_MOVIES; n++) { cout << "Enter title: "; cin.getline (films[n].title,50); cout << "Enter year: "; cin.getline (buffer,50); films[n].year = atoi (buffer); } cout << "\nYou have entered these movies:\n";

for (n=0; n<N_MOVIES; n++) printmovie (films[n]);

} void printmovie (movies_t movie) { cout << movie.title; cout << " (" << movie.year << ")\n";

} //Kết quả:

Enter title: Alien Enter year: 1979 Enter title: Blade Runner Enter year: 1982 Enter title: Matrix Enter year: 1999 Enter title: Rear Window Enter year: 1954 Enter title: Taxi Driver Enter year: 1975 You have entered these movies: Alien (1979) Blade Runner (1982) Matrix (1999) Rear Window (1954) Taxi Driver (1975)

IX.2.4. Tham số kiểu cấu trúc:

Việc truyền và nhận tham số kiểu cấu trúc cũng tương tự như cách truyền và nhận tham số của các loại dữ liệu vô hướng.

Page 118: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 118

Có ba hình thức truyền nhận tham số: − Tham trị − Tham chiếu. − Dùng con trỏ.

Ví dụ: Viết chương trình cho phép nhập và in bảng ñiểm của thí sinh lên màn hình, bằng cách xây dựng hai hàm input và output ñể nhập và in bảng ñiểm của sinh viên. Trong ñó hàm input sử dụng tham chiếu kiểu danhsach còn hàm output thì dùng tham trị kiểu danhsach

#include <iostream.h> #include <conio.h> #include <string.h> #include <iomanip.h> const int MAXNAME=25,NUMREC=3; struct danhsach { int sbd; char hoten[MAXNAME]; float toan,ly,hoa; }; void input(danhsach&); void output(danhsach); void main() { danhsach bangdiem[NUMREC]; int i; clrscr(); cout <<"NHAP BANG DIEM CUA SINH VIEN\n"; for (i=0;i<NUMREC;i++) input(bangdiem[i]); clrscr(); cout <<" ------BANG DIEM CUA SINH VIEN-----\n"; cout <<"So bdanh Ho ten Diem toan Diem ly Diem hoa\n"; for (i=0;i<NUMREC;i++) output(bangdiem[i]); getch(); } void input(danhsach& bd) { cout <<"So bao danh: "; cin>> bd.sbd; cin.ignore(100,'\n'); cout <<"Ho va ten: "; cin.getline(bd.hoten,MAXNAME); if (strlen(bd.hoten)>=MAXNAME-1) cin.ignore(100,'\n'); cout <<"Diem toan: "; cin >> bd.toan; cout <<"Diem ly: "; cin >> bd.ly; cout <<"Diem hoa "; cin >> bd.hoa; } void output(danhsach bd) {

Page 119: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 119

cout <<setw(5)<<bd.sbd<<setw(20)<<bd.hoten<<setw(10) <<bd.toan<<setw(12)<<bd.ly<<setw(14)<<bd.hoa<<endl; }

/*Thủ tục input khi sử dụng con trỏ:*/

void input(danhsach *); //dòng nguyên mẫu for (i=0;i<NUMREC;i++) input(&bangdiem[i]); //lời gọi hàm trong main void input(danhsach *bd) //nội dung hàm input { cout <<"So bao danh: "; cin>> (*bd). sbd; //luu y (*bd).sbd cin.ignore(100,'\n'); cout <<"Ho va ten: "; cin.getline((*bd).hoten,MAXNAME); if (strlen((*bd).hoten)>=MAXNAME-1) cin.ignore(100,'\n'); cout <<"Diem toan: "; cin >> (*bd).toan; cout <<"Diem ly: "; cin >> (*bd).ly; cout <<"Diem hoa "; cin >> (*bd).hoa; }

IX.3 UNION: Union là một loại dữ liệu có ñặc ñiểm sử dụng cùng một vùng nhớ cho nhiều biến. Các biến có thể khác loại dữ liệu. Tuy nhiên tại một thời ñiểm chỉ sử dụng ñược một trong những biến dùng chung vùng nhớ này.

Ta có thể xem một unoin như một cấu trúc nhưng các trường của nó có chung vùng nhớ. Loại này ñược sử dụng cho các biến ít dùng trong chương trình và các biến này không sử dụng cùng lúc với nhau nhằm tiết kiệm bộ nhớ.

Cú pháp

Ví dụ: union { char key; int num; double price; } val; //biến val có kiểu union

union datetime //datetime là một kiểu dữ liệu union

{ long int days;

union {

<Kiểu> <Trường 1> ; <Kiểu> <Trường 2> ; …….. <Kiểu> <Trường n> ;

} tên biến;

Page 120: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 120

double time; }; datetime first,second; // first, second là hai biến kiểu datetime

Ta cũng có thể ñịnh nghĩa kiểu dữ liệu union và struct lồng vào nhau. Hãy xét ví dụ sau:

Ví dụ

Viết chương trình có thể tính diện tích của hình chữ nhật, hình tròn, hình thang. Khi chương trình thực hiện người sử dụng sẽ cho biết loại hình muốn tính diện tích. #include <iostream.h> #include <conio.h> #include <ctype.h> union dagiac { char loai; struct { float dai,rong;} cn; struct {float bankinh; } tr; struct {float daylon,daynho,cao;} th; }; void main() { dagiac dg; clrscr(); cout <<"Cho biet loai hinh muon tinh dien tich(c(chu nhat)/t(thang)/r(tron)"; cin >>dg.loai; switch (toupper(dg.loai)) { case 'C': cout <<"Cho biet chieu dai: ";cin >>dg.cn.dai;

cout <<"Cho biet chieu rong: ";cin >>dg.cn.rong; cout <<"Dien tich la: "<<(dg.cn.dai*dg.cn.rong); break;

case 'T': cout <<"Cho biet day lon: "; cin >>dg.th.daylon; cout <<"Cho biet day nho: "; cin >>dg.th.daynho;

cout <<"Cho biet chieu cao: ";cin >>dg.th.cao; cout <<"Dien tich la: " <<((dg.th.daylon+dg.th.daynho)*dg.th.cao/2);

break; case 'R': cout <<"Cho biet ban kinh: "; cin >>dg.tr.bankinh;

cout <<"Dien tich la: "<<(dg.tr.bankinh*dg.tr.bankinh*3.14); break;

default: cout <<"Du lieu khong chin xac"; } getch(); }

Page 121: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 121

BÀI TẬP 1. Cho cấu trúc NHANVIEN như sau:

- MaNV: kiểu số nguyên có giá trị trong khoảng 0…65535

- Họtên: kiểu chuỗi. - ðịachỉ: kiểu chuỗi.

- CBQL: có giá trị 1 nếu nhân viên này là cán bộ quản lý.

Viết chương trình thực hiện: (a) Nhập vào thông tin của một nhân viên. (b) Nhập vào thông tin của n nhân viên và n ñược nhập từ bàn phím. In ra họ tên của các nhân viên là cán bộ quản lý. 2. Cho cấu trúc NHANVIEN như sau:

- MaNV: kiểu số nguyên có giá trị trong khoảng 0…65535

- Họtên: kiểu chuỗi.

- ðịachỉ: kiểu chuỗi.

- CBQL: có giá trị 1 nếu nhân viên này là cán bộ quản lý.

Viết chương trình thực hiện: (a) Nhập vào thông tin của một nhân viên.

(b) Nhập vào thông tin của n nhân viên và n ñược nhập từ bàn phím. Xóa các nhân viên không là cán bộ quản lý ra khỏi danh sách.

3 Cho cấu trúc NHANVIEN như sau:

- MaNV: kiểu số nguyên có giá trị trong khoảng 0…65535 - Họtên: kiểu chuỗi.

- ðịachỉ: kiểu chuỗi. - CBQL: có giá trị 1 nếu nhân viên này là cán bộ quản lý.

Viết chương trình thực hiện: (a) Nhập vào thông tin của một nhân viên.

(b) Nhập vào thông tin của n nhân viên và n ñược nhập từ bàn phím. Nhập thêm thông tin của một nhân viên và nhập một số nguyên k. Thực hiện việc chèn nhân viên mới vào danh sách tại vị trí k.

Page 122: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 122

PHỤ LỤC I. CHẠY CHƯƠNG TRÌNH TỪNG BƯỚC.

- Chạy từng bước 1 chương trình là thi hành từng dòng lệnh của chương trình. Có 2 cách chạy chương trình từng bước:

- Chạy từng dòng lệnh và ñi vào bên trong hàm _ Phím tắt F7 - Mỗi lần nhấn F7 sẽ thực hiện lệnh tại dòng có vệt sáng và di chuyển vệt sáng

ñến dòng kế tiếp. Khi dòng lệnh là 1 lời gọi ñến 1 hàm thì vệt sáng sẽ dời ñến dòng lệnh ñầu tiên trong hàm ñó.

- Sử dụng phím tắt này khi cần chạy chương trình từng bước ñể phát hiện lỗi chi tiết bên trong 1 hàm.

- Chạy từng dòng lệnh và thực hiện lời gọi hàm mà không ñi vào bên trong hàm ñó_ Phím tắt F8.

- Mỗi lần nhấn F8 sẽ thực hiện lệnh tại dòng có vệt sáng và di chuyển vệt sáng ñến dòng kế tiếp. Khi dòng lệnh là 1 lời gọi ñến 1 hàm thì vệt sáng sẽ dời ñến dòng lệnh kế tiếp theo lời gọi hàm ñó, mà không ñi vào chi tiết từng lệnh trong hàm.

- Sử dụng phím này khi cần chạy từng bước mà không cần chạy chi tiết bên trong 1 hàm vì biết chắc chắn hàm ñó không có lỗi.

II. CHẠY CHƯƠNG TRÌNH ðẾN VỊ TRÍ CON TRỎ _ SỬ DỤNG PHÍM TẮT F4

Khi cần thi hành một ñoạn lệnh mà không cần phải nhấn phím (F7/F8) ñể chạy từng lệnh ta sử dụng chức năng chạy chương trình ñế khi gặp dòng lệnh nơi con trỏ soạnn thảo ñang ñứng. Khi biết chắc 1 ñoạn lệnh không có lỗi, ta di chuyển con trỏ soạn thảo ñến nơi "nghi ngờ" có lỗi và nhấn F4; chương trình sẽ ñược thực hiện cho ñến dòng lệnh có con trỏ soạn thảo. Sau ñó ta tiếp tục sử dụng phím F7/F8 ñể debug.

III. ðIỂM DỪNG_PHÍM TẮT CTRL+F8

ðiểm dừng là nơi chương trình sẽ dừng lại khi thỏa mãn ñiều kiện ñi kèm với ñiểm dừng ñó. Có 2 loại ñiểm dừng: - ðiểm dừng vô ñiều kiện:

Chương trình sẽ dừng khi gặp lệnh có ñiểm dừng này mà không kiểm tra một ñiều kiện gì. ðể tạo ñiểm dừng loại này ta di chuyển con trỏ ñến dòng lệnh cần dừng rồi nhấn tổ hợp phím Ctrl+F8. Một vệt sáng màu ñỏ sẽ xuất hiện báo cho biết ñây là 1 ñiểm dừng.

- ðiểm dừng có ñiều kiện Chương trình sẽ dừng lại khi gặp lệnh có ñiểm dừng mà ñiều kiện ñi kèm với ñiểm dừng ñó ñược thỏa. ðể tạo ñiểm dừng loại này, có 2 cách: Cách1: Tạo ñiểm dừng vô ñiều kiện rồi ñiều chỉnh nó trong menu Debug/Breakpoint -> danh sách các ñiểm dừng, chọn ñiểm dừng cần hiệu chỉnh rồi nhấn Edit, hiệu chỉnh xong nhấn Modify. Cách 2: Vào thẳng menu Debug/Breakpoint/Edit, rồi tạo xong nhấn New. Trong khi tạo ñiểm dừng có một tham số Pass Count cho phép chỉ ñịnh số lần bỏ qua không dừng khi gặp ñúng ñiều kiện ñó. Ví dụ:

Page 123: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 123

Tại dòng lệnh sau ta ñặt ñiểm dừng với Condition là i = 4, Pass Count = 2: ……………………………. I = (10*k)%5; Chương trình dừng tại câu lệnh này khi giá trị i = 4 ñã xãy ra 2 lần ……………………………. Khi chương trình chạy qua dòng lệnh này ñầu tiên, nếu ñiều kiện i=4 thỏa mãn, chương trình vẫn không dừng, lần thứ 2 vẫn không dừng và chỉ dừng lại ở lần thứ 3. Nghĩa là i=4 ñã xãy ra 3 lần. Sử dụng ñiểm dừng khi cần "bắt" chương trình dừng tại ñầu ñoạn code "nghi ngờ" có lỗi ñể debug. Ghi chú: ðể bỏ ñiểm dừng, di chuyển con trỏ soạn thảo ñến dòng có vệt ñỏ và nhấn Ctrl+F8

IV. XEM GIÁ TRỊ CỦA BIẾN/BIỂU THỨC TRONG KHI CHẠY CHƯƠNG TRÌNH _ PHÍM CTRL+F7

Trong quá trình chạy từng bước 1 chương trình sử dụng các phím: F7/F8/F4/ðiểm dừng, ta có thể ñặt các biến/ biểu thức vào cửa sổ Watch ñể tiện theo dõi giá trị của chúng. Có hai cách ñể thêm một biến/biểu thức vào cửa sổ Watch: Cách 1: Di chuyển con trỏ soạn thảo ñến biến/biểu thức và nhấn Ctrl+F7. Nếu cần theo dõi biến, nhấn Enter. Nếu cần theo dõi biểu thức, nhấn nhiều lần phím -> và <- ñể chọn biểu thức hoặc tự thay ñổi biểu thức rồi nhấn Enter.

Cách 2: ðứng trong cửa sổ Watch nhấn Insert ñể thêm 1 biến/biểu thức, nhập biến/biểu thức có trong cửa sổ bằng phím Enter/Delete. ðịnh dạng cho biến/biểu thức: Công thức: Expression,[repeat]<<format characters>> Trong ñó:

Expression: có thể là biến hoặc biểu thức. Repeat: số lần lặp – áp dụng cho dữ liệu dạng mảng. Format characters: ñịnh dạng các dạng sau ñây: C: ký tự D : số nguyên. F(n): số thực, n là số chữ số sau dấu thập phân (không bắt buộc phải có) H/X: số nguyên dạng thập lục. M: hiện giá trị trong bộ nhớ từng byte một. P : hiện dạng con trỏ far segment:offset R : hiện các thành phần của một struct, union. S : hiện ký tự ñiều khiển (mã ASCII 0..31) dạng ‘\n’

Ví dụ: Có các khai báo như sau: int k, a[20]; struct SV {

char HoTen[40]; int MSSV;

Page 124: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 124

}sv[100];

khi ñó, trong cửa sổ Watch nhập vào: a,10h: hiện giá trị 10 phần tử ñầu tiên của mảng ở dạng Hexa. sv[1],r: hiện tên và giá trị tương ứng của từng thành phần trong struct SV của

sv[1].

V. XEM GIÁ TRỊ CỦA BIẾN/BIỂU THỨC – THAY ðỔI GIÁ TRỊ CỦA BIẾN TRONG KHI CHẠY (PHÍM TẮT CTRL+F4.)

Nếu cần xem giá trị của một biến/biểu thức trong khi chạy từng bước một chương trình, hoặc tính toán giá trị một biểu thức trong lúc viết chương trình, thậm chí thay ñổi giá trị biến một cách thủ công trong lúc chạy từng bước một chương trình ta sử dụng của sổ Evaluate and Modify thông qua phím tắt Ctrl+F4. Có 2 cách ñể nhập biến/biểu thức vào cửa sổ Evaluate and Modify:

Cách 1: Di chuyển con trỏ soạn thảo ñến biến/biểu thức và nhấn Ctrl+F4. Nếu chấp nhận biến ñó, nhấn Enter. Nếu cần theo dõi biểu thức, nhấn nhiều lần phím -> và <- ñể chọn biểu thức.

Cách 2: Nhấn Ctrl+F4 ở ñâu cũng ñược, rồi nhập biến/biểu thức vào. Muốn ñịnh dạng kết quả xuất hiện của biến/biểu thức thì xem phần ñịnh dạng trong mục 4.

VI. THEO VẾT MỘT BIẾN/LỚP – PHÍM TẮT ALT+F4(CHỈ CÓ TRONG BORLAND C++3.1)

Trong môi trường BC++3.1 có một công cụ rất tốt ñể debug khi viết các chương trình có sử dụng con trỏ (danh sách liên kết, cây…), các ñối tượng trong lập trình hướng ñối tượng.

Có 2 cách ñể sử dụng chức năng này (chú ý chỉ dùng trong khi ñang chạy từng bước một chương trình): Cách 1: Di chuyển con trỏ soạn thảo ñến biến nhấn Alt+F4. Nếu chấp nhận

biến/lớp ñó, nhấn Enter. Cách 2: nhấn Alt+F4 ở ñâu cũng ñược, rồi nhập tên biến/lớp vào.

Trong cửa sổ Inspect, ta sẽ có toàn bộ thông tin về biến/lớp, có thể thay ñổi giá trị như ở cửa sổ Evaluate and Modify bằng cách nhấn Alt+M. Dùng các phím di chuyển như Tab,->,<- ñể chọn ñối tượng trong cửa sổ, và nhấn Enter ñể "Inspect" ñối tượng ñó nếu dòng trạng thái cuối màn hình có: Inspect. Nhấn Alt+I ñể giới hạn khoảng cần xem (thường áp dụng với mảng, con trỏ): vị trí bắt ñầu, số phần tử.

VII. NGĂN XẾP CÁC LỜI GỌI HÀM CALL STACK_PHÍM TẮT CTRL+F3

Trong lúc chạy từng bước một chương trình, nhất là các chương trình có nhiều lời gọi hàm lồng nhau, các chương trình có ñệ quy, ñể biết chương trình ñang chạy trong hàm nào ta nhấn Ctrl+F3 ñể vào cửa sổ Call Stack. Trong cửa sổ này các lời gọi hàm ñược hiển thị theo dạng ngăn xếp, hàm gọi lâu nhất sẽ ở dưới cùng, hàm hiện hành sẽ ở trên cùng, các tham số truyền vào cho hàm cũng ñược hiển thị ở ñây.

VIII. NGẮT QUÁ TRÌNH CHẠY TỪNG BƯỚC_PHÍM TẮT CTRL+F2

Page 125: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 125

Ta nhấn tổ hợp phím này trong lúc chạy từng bước 1 chương trình ñể ngắt debug và trở về trạng thái soạn thảo (vệt sáng biến mất)

CÁC PHÍM TẮT TIỆN DỤNG: - Undo thao tác trước hoặc làm lại thao tác trước khi undo_Phím

Alt+Backspace/Alt+Shift+ Backspace Chức năng này rất quan trọng, giúp ta lấy lại những ñoạn code trước ñó mà do vô tình hay cố ý ñã thay ñổi, thêm bớt, thậm chí xóa ñi. Ta chỉ cần nhấn Alt+Backspace liên tục cho ñến khi ñoạn code cần tìm hiện ra. Nếu cần làm lại thao tác ñã thực hiện trước khi nhấn Alt+ Backspace ta nhấn Alt+Shift+ Backspace.

- Kiểm tra ñã ñủ dấu: {,},[, ],(,) hay chưa: Phím Ctrl+Q+] hoặc Ctrl+Q+[ ðây là phím rất tiện dụng ñể phát hiện các lỗi thiếu các dấu ngoặc tương ứng. Di chuyển con trỏ soạn thảo ñến một trong các loại dấu ngoặc trên rồi nhấn một trong 2 tổ hợp phím, nếu con trỏ soạn thảo: Không di chuyển -> thiếu dấu ngoặc tương ứng hoặc thừa dấu tại vị trí con

trỏ ñang ñứng. Di chuyển ñến một dấu ngoặc, nhưng sai -> thiếu dấu ngoặc tương ứng.

Lưu ý: chức năng này chỉ có trong BC++3.1 trở ñi. - Tìm kiếm/Tìm kiếm và thay thế/Lặp lại thao tác tìm kiếm trước ñó: Phím

Ctrl+Q+F/ Ctrl+Q+A/ Ctrl+L ðể tìm một ñoạn text trong chương trình, ta nhấn Ctrl+Q+F (thao tác nhập tương tự cửa sổ Evaluate and Modify). Sau ñó chọn thêm một số thông số:

[] Case – sensitive : có phân biệt chữ hoa/ chữ thường. [] Whole words only: tìm ñoạn text ñứng ñộc lập. () Global: tìm toàn bộ văn bản. () Selected text: tìm trong khối văn bản ñánh dấu. () From cursor: tìm từ vị trí con trỏ soạn thảo. () Entire scope: tìm từ ñầu ñến cuối. () Forward : tìm xuôi. () Backward: tìm ngược.

ðể tìm và thay thế ta nhấn Ctrl+Q+A, nhập các thông tin như phần trên, thêm vào ñoạn text sẽ thay thế ñoạn text tìm thấy, chỉ ñịnh thông số:

[] Prompt on replace: nhắc thay thế mỗi khi tìm thấy. ðể tìm và thay thế tất cả chọn Change All thay vì chọn OK. ðể lặp lại thao tác Tìm/Tìm thay thế lần cuối cùng ta nhấn Ctrl+L.

- ðến thông báo lỗi trước ñó hoặc kế tiếp. Phím Alt+F7/ Alt+F8 Sau khi dịch có lỗi, ta dùng 2 phím này ñể duyệt qua từng lỗi mà không cần dịch lại. Lưu ý nếu gặp các lỗi phát sinh do ảnh hưởng lẫn nhau thì nên dịch lại ñể nhận thông báo lỗi mới. - Xem cửa sổ kết quả_Phím Alt+F5. Nhấn phím này ñể xem kết quả xuất ra ở màn hình DOS. Xem xong nhấn Enter ñể trở về màn hình soạn thảo. Nếu muốn hiện cửa sổ này trong môi trường soạn thảo nhấn Alt+W rồi nhấn O. - Danh sách các cửa sổ: Phím Alt+0 Hiện danh sách các cửa sổ ñang mở ñể chọn cửa sổ làm việc (active). Trong danh sách này có cả các file ñã ñóng. Chú ý, thường có những file ñược mở từ ổ A: mà không ñóng, hay gây ra thông báo lỗi ñĩa mềm -> vào ñây xoá những cửa sổ ñó ñi. - Sắp xếp hiện hết các cửa sổ. Phím Alt+W, rồi nhấn T. Tất cả các cửa sổ sẽ ñược hiện lên màn hình.

Page 126: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 126

- Ngắt chương trình bị lặp/treo. Phím Ctrl+Break, rồi nhấn Enter 2 lần. Khi chương trình bị lặp không lối thoát, hoặc bị treo ta nhấn Ctrl+Break sau ñó nhấn Enter 2 lần ñể trở về màn hình soạn thảo. - Chọn cửa sổ làm việc. Phím Alt+n(n=1…9) Mỗi cửa sổ ñều ñược ñánh một con số ở góc trên bên phải (tất nhiên ngoại trừ các cửa sổ ñược mở lần thứ 10 trở lên vì chỉ có 9 con số). Ở một thời ñiểm chỉ có một cửa sổ gọi là cửa sổ làm việc (active) – ñó là cửa sổ có ñường biên là nét ñôi ===. Các cửa sổ không active sẽ ñược vẽ bằng nét ñơn _____. ðể chọn cửa sổ thứ 5 ta nhấn Alt+5. - Di chuyển và thay ñổi kích thước cửa sổ. Phím Ctrl+F5 ðể di chuyển cửa sổ làm việc ta nhấn Ctrl+F5, dùng các phím dịch chuyển ñể di chuyển cửa sổ, xong thì nhấn Enter ñể trở lại chế ñộ soạn thảo. Nếu nhấn Shift+phím dịch chuyển thì sẽ có dãn cửa sổ. - ðánh dấu/sao chép/cắt/dán khối. Phím Shift + Dịch chuyển/Ctrl+Insert/Shift

+ Delete/Shift+Insert. ðánh dấu khối: nhấn giữ Shift, dùng các phím dịch chuyển: ->, <-, Home,

End, PgUp, PgDn (Có thể kết hợp với Ctrl) ñể xác ñịnh khối văn bản. Sao chép: sau khi ñánh dấu nhấn Ctrl+Insert ñể chép khối văn bản vào

ClipBoard của BC. Cắt: sau khi ñánh dấu khối nhấn Shift + Delete ñể cắt khối văn bản vào

ClipBoard của BC, khối văn bản sẽ bị xóa luôn khỏi màn hình. Dán: nhấn Shift+Insert ñể chép khối văn bản trong ClipBoard vào cửa sổ văn

bản tại dấu nháy.

Page 127: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 127

BẢNG MÃ ASCII

Dec. Oct. Hex Char Dec. Oct. Hex Char Dec. Oct. Hex Char

0 0 0 NUL 43 53 2b + 86 126 56 V

1 1 1 SOH 44 54 2c , 87 127 57 W

2 2 2 STX 45 55 2d - 88 130 58 X

3 3 3 ETX 46 56 2e . 89 131 59 Y

4 4 4 EOT 47 57 2f / 90 132 5a Z

5 5 5 ENQ 48 60 30 0 91 133 5b [

6 6 6 ACK 49 61 31 1 92 134 5c \

7 7 7 BEL 50 62 32 2 93 135 5d ]

8 10 8 BS 51 63 33 3 94 136 5e ^

9 11 9 TAB 52 64 34 4 95 137 5f _

10 12 a LF 53 65 35 5 96 140 60 `

11 13 b VT 54 66 36 6 97 141 61 a

12 14 c FF 55 67 37 7 98 142 62 b

13 15 d CR 56 70 38 8 99 143 63 c

14 16 e SO 57 71 39 9 100 144 64 d

15 17 f SI 58 72 3a : 101 145 65 e

16 20 10 DLE 59 73 3b ; 102 146 66 f

17 21 11 DC1 60 74 3c < 103 147 67 g

18 22 12 DC2 61 75 3d = 104 150 68 h

19 23 13 DC3 62 76 3a > 105 151 69 i

20 24 14 DC4 63 77 3f ? 106 152 6a j

21 25 15 NAK 64 100 40 @ 107 153 6b k

22 26 16 SYN 65 101 41 A 108 154 6c l

23 27 17 ETB 66 102 42 B 109 155 6d m

Page 128: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 128

24 30 18 CAN 67 103 43 C 110 156 6e n

25 31 19 EM 68 104 44 D 111 157 6f o

26 32 1a SUB 69 105 45 E 112 160 70 p

27 33 1b ESC 70 106 46 F 113 161 71 q

28 34 1c FS 71 107 47 G 114 162 72 r

29 35 1d GS 72 110 48 H 115 163 73 s

30 36 1e RS 73 111 49 I 116 164 74 t

31 37 1f US 74 112 4a J 117 165 75 u

32 40 20 SP 75 113 4b K 118 166 76 v

33 41 21 ! 76 114 4c L 119 167 77 w

34 42 22 " 77 115 4d M 120 170 78 x

35 43 23 # 78 116 4e N 121 171 79 y

36 44 24 $ 79 117 4f O 122 172 7a z

37 45 25 % 80 120 50 P 123 173 7b {

38 46 26 & 81 121 51 Q 124 174 7c |

39 47 27 ‘ 82 122 52 R 125 175 7d }

40 50 28 ( 83 123 53 S 126 176 7e ~

41 51 29 ) 84 124 54 T 127 177 7f DEL

42 52 2a * 85 125 55 U

Page 129: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 129

MỤC LỤC CHƯƠNG I: TỔNG QUAN VỀ NGÔN NGỮ C++................................................ 1

I.1 CÁC KHÁI NIỆM CƠ BẢN ........................................................................ 1 I.1.1. Lập trình................................................................................................ 1 I.1.2. Một chương trình C++ ñơn giản ............................................................ 1 I.1.3. Các chú thích......................................................................................... 2

I.2 BIẾN – KIỂU DỮ LIỆU – HẰNG ............................................................... 3 I.2.1. Identifiers (ðịnh danh) .......................................................................... 3 I.2.2. Keyword (Từ khóa) ............................................................................... 3 I.2.3. Các kiểu dữ liệu..................................................................................... 4 I.2.4. Khai báo biến ........................................................................................ 5 I.2.5. Khởi tạo các biến................................................................................... 6 I.2.6. Phạm vi hoạt ñộng của các biến............................................................. 6 I.2.7. Các hằng số (Constants): ....................................................................... 7 I.2.8. ðịnh nghĩa các hằng (#define) ............................................................... 9 I.2.9. Khai báo các hằng (const)...................................................................... 9

I.3 Các lệnh xuất nhập chuẩn ............................................................................. 9 I.3.1. Lệnh xuất (cout) .................................................................................... 9 I.3.2. Nhập dữ liệu (cin)................................................................................ 11 I.3.3. Lệnh nhập trong ngôn ngữ C: hàm scanf (ñọc thêm)............................ 11 I.3.4. Lệnh xuất trong ngôn ngữ C: hàm printf (ñọc thêm) ............................ 12 I.3.5. ðịnh dạng kết quả xuất:....................................................................... 13

I.4 Cấu trúc của một chương trình C++............................................................ 14 I.4.1. Tiền xử lý và biên dịch ........................................................................ 14 I.4.2. Cấu trúc một chương trình C++........................................................... 14 I.4.3. Các tập tin thư viện thông dụng ........................................................... 15

CHƯƠNG II: BIỂU THỨC.................................................................................... 17 II.1 GIỚI THIỆU .............................................................................................. 17 II.2 TOÁN TỬ.................................................................................................. 17

II.2.1. Toán tử gán (assignment operator): ..................................................... 17 II.2.2. Các toán tử số học (number operator) .................................................. 18 II.2.3. Các toán tử gán phức hợp (complex operator) ..................................... 18 II.2.4. Tóan tử tăng và giảm (increase/descrease operator) ............................. 19 II.2.5. Toán tử quan hệ (relation operator): .................................................... 19 II.2.6. Toán tử logic (logic operator): ............................................................. 20 II.2.7. Toán tử ñiều kiện (condition operator):................................................ 20 II.2.8. Toán tử lấy kích thước (size operator) ................................................. 20 II.2.9. Toán tử BITWISE (Bit operator) ......................................................... 21 II.2.10. Toán tử con trỏ & và * (pointer operator)......................................... 22

II.3 CHUYỂN ðỔI KIỂU DỮ LIỆU: ............................................................... 22 II.4 ðỘ ƯU TIÊN CỦA CÁC TOÁN TỬ:........................................................ 23

CHƯƠNG III: CẤU TRÚC ðIỀU KHIỂN .......................................................... 29 III.1 GIỚI THIỆU .............................................................................................. 29 III.2 CẤU TRÚC RẼ NHÁNH........................................................................... 29 III.3 CẤU TRÚC LỰA CHỌN (switch):............................................................ 33 III.4 CẤU TRÚC LẶP (reiterate structure)......................................................... 36

III.4.1. Vòng lặp while................................................................................. 36 III.4.2. Vòng lặp do… while........................................................................ 38

Page 130: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 130

III.4.3. Vòng lặp for:.................................................................................... 40 III.5 CÁC LỆNH RẼ NHÁNH VÀ LỆNH NHẢY............................................. 41

III.5.1. Lệnh continue .................................................................................. 41 III.5.2. Lệnh break....................................................................................... 42 III.5.3. Lệnh goto......................................................................................... 43 III.5.4. Lệnh return ...................................................................................... 44

CHƯƠNG IV: CHƯƠNG TRÌNH CON .............................................................. 51 IV.1 KHÁI NIỆM VỀ HÀM TRONG C++..................................................... 51

IV.1.1. Hàm toán học:.................................................................................. 51 IV.2 XÂY DỰNG HÀM................................................................................. 52

IV.2.1. ðịnh nghĩa hàm ............................................................................... 52 IV.2.2. Sử dụng hàm.................................................................................... 53 IV.2.3. Nguyên tắc hoạt ñộng của hàm ........................................................ 54 IV.2.4. Truyền tham số cho hàm.................................................................. 54 IV.2.5. Phạm vi của biến (scope variables) .................................................. 57 IV.2.6. Lớp lưu trữ các biến......................................................................... 60

CHƯƠNG V: MẢNG......................................................................................... 67 V.1 Mảng (Array) ............................................................................................. 67 V.2 Mảng 1 chiều.............................................................................................. 67

V.2.1. Khai báo mảng .................................................................................... 67 V.2.2. Truy xuất từng phần tử của mảng ........................................................ 69

V.3 Mảng nhiều chiều. ...................................................................................... 71 V.3.1. Khai báo.............................................................................................. 71 V.3.2. Truy xuất từng phần tử của mảng 2 chiều ............................................ 72 V.3.3. Khai báo mảng 2 chiều như một tham số: ............................................ 72 V.3.4. Các phương pháp tìm kiếm và sắp xếp trên mảng:............................... 75

CHƯƠNG VI: KIỂU CON TRỎ.......................................................................... 80 VI.1 Giới thiệu dữ liệu kiểu dữ liệu:................................................................ 80 VI.2 Khai báo và sử dụng biến con trỏ ............................................................ 80

VI.2.1. Khai báo biến con trỏ....................................................................... 80 VI.2.2. Các thao tác trên con trỏ .................................................................. 80 VI.2.3. Một số phép toán trên con trỏ........................................................... 82 VI.2.4. Con trỏ và mảng............................................................................... 85 VI.2.5. Truyền ñịa chỉ cho tham số bởi con trỏ: ........................................... 88

VI.3 Bộ nhớ ñộng ........................................................................................... 89 VI.3.1. Toán tử new..................................................................................... 90 VI.3.2. Toán tử delete. ................................................................................. 91

CHƯƠNG VII: CHUỖI KÝ TỰ............................................................................ 95 VII.1 KHÁI NIỆM........................................................................................... 95 VII.2 KHAI BÁO............................................................................................. 95

VII.2.1. Khai báo theo mảng ......................................................................... 95 VII.2.2. Khai báo theo con trỏ....................................................................... 95 VII.2.3. Vừa khai báo vừa gán giá trị ............................................................ 95

VII.3 CÁC THAO TÁC TRÊN CHUỖI KÝ TỰ.............................................. 96 VII.3.1. Nhập xuất ........................................................................................ 96 VII.3.2. Truy xuất từng ký tự trong chuỗi: .................................................... 97

VII.4 CON TRỎ VÀ CÁC HÀM TRÊN CHUỖI:............................................ 99 VII.4.1. Con trỏ và chuỗi .............................................................................. 99 VII.4.2. Các hàm thao tác trên chuỗi: .......................................................... 100

Page 131: CHƯƠNG I: TNG QUAN VỀ NGÔN NGỮ C++ · Ngôn ngữ máy rất khó hiểu ñối với lập trình viên vì thế họ không thể sử dụng trực tiếp ngôn ngữ máy

Giáo trình Phương pháp lập trình Trung tâm Công Nghệ Thông Tin

Tổ tin học Cơ sở 131

CHƯƠNG VIII: ðỆ QUY.................................................................................... 105 VIII.1 ðịnh nghĩa ............................................................................................ 105 VIII.2 Phân loại ñệ quy:................................................................................... 105

VIII.2.1. ðệ quy tuyến tính........................................................................... 106 VIII.2.2. ðệ quy nhị phân............................................................................. 107 VIII.2.3. ðệ quy phi tuyến............................................................................ 108 VIII.2.4. ðệ quy hỗ tương ............................................................................ 109

VIII.3 ðặc ñiểm cần lưu ý khi viết hàm ñệ quy................................................ 109 CHƯƠNG IX: KIỂU CẤU TRÚC (STRUCTURE) ........................................... 113

IX.1 KIỂU CẤU TRÚC................................................................................ 113 IX.1.1. Khái niệm ...................................................................................... 113 IX.1.2. ðịnh nghĩa kiểu cấu trúc ................................................................ 113 IX.1.3. Khai báo biến cấu trúc ................................................................... 113

IX.2 CÁC THAO TÁC TRÊN BIẾN KIỂU CẤU TRÚC ............................. 114 IX.2.1. Truy xuất ñến từng trường của biến cấu trúc .................................. 114 IX.2.2. Khởi tạo giá trị cho biến cấu trúc ................................................... 115 IX.2.3. Mảng cấu trúc: ............................................................................... 115 IX.2.4. Tham số kiểu cấu trúc: ................................................................... 117

IX.3 UNION:................................................................................................ 119