10/30/2015

NHẬP MÔN LẬP TRÌNH

G V : T H S . L Ê T H Ị N G Ọ C H Ạ N H

1

10/30/2015

Bài giảng nhập môn lập trình

NỘI DUNG HỌC PHẦN

 Tổng quan  Các kiểu dữ liệu  Nhập, xuất dữ liệu  Các cấu trúc điều khiển  Hàm  Mảng  Chuỗi ký tự

10/30/2015

2

Bài giảng nhập môn lập trình

1

10/30/2015

ĐÁNH GIÁ MÔN HỌC

 Thang điểm 10 theo tỉ lệ như sau:

Chuyên cần : thi giữa kỳ : thi cuối kỳ

1: 3 : 6

10/30/2015

3

Bài giảng nhập môn lập trình

TỔNG QUAN

10/30/2015

4

 Khái niệm chương trình – lập trình  Cấu trúc của một chương trình đơn giản  Khái niệm thuật toán – biểu diễn thuật toán  Khái niệm ngôn ngữ lập trình  Ngôn ngữ lập trình C

Bài giảng nhập môn lập trình

2

10/30/2015

KHÁI NIỆM CHƯƠNG TRÌNH

 Chương trình (program) là một dãy các chỉ thị (instruction) điều khiển sự hoạt động của máy tính nhằm giải quyết một công việc nào đó.

10/30/2015

5

Bài giảng nhập môn lập trình

CẤU TRÚC CHƯƠNG TRÌNH

 Một số lưu ý: • Phần ghi chú được trình biên dịch bỏ qua

• Phân biệt chữ hoa và chữ thường

• Mỗi câu lệnh được kết thúc bằng dấu “;”

• Chuỗi ký tự phải

10/30/2015

6

được đặt trong cặp nháy kép “”

Bài giảng nhập môn lập trình

3

10/30/2015

7

10/30/2015

Bài giảng nhập môn lập trình

BIẾN - VARIABLE

 Chứa dữ liệu, có thể thay đổi giá trị trong chương

trình

 Muốn sử dụng phải được khai báo trước  Tên biến: gồm chữ cái, ký số, số, dấu nối(_),

không được bắt đầu bằng ký số.

 Biến được khai báo trong khối được gọi là biến cục bộ; không thuộc khối nào được gọi là biến toàn cục.

 Có tác dụng trong toàn khối kể từ lúc khai báo.

10/30/2015

8

Bài giảng nhập môn lập trình

4

10/30/2015

LỆNH XUẤT - PRINTF

 Xuất dữ liệu ra màn hình

 Các ký tự hằng được in nguyên văn  Các ký tự định dạng được thay bằng giá trị của biểu thức tương ứng

 %d: ký tự định dạng số nguyên kiểu int  Các ký tự điều khiển: \n (xuống dòng); \t(dấu tab); \\(dấu \); \”(dấu “; …

10/30/2015

9

 Thư viện: stdio.h

Bài giảng nhập môn lập trình

LỆNH NHẬP - SCANF

 Nhập dữ liệu từ bàn phím

 Trong chuỗi định dạng chỉ có ký tự định dạng và khoảng trắng.

10/30/2015

10

 Dữ liệu phải được nhập vào các biến  Trước tên biến phải có dấu & (toán tử địa chỉ).  Thư viện: stdio.h

Bài giảng nhập môn lập trình

5

10/30/2015

KIỂU DỮ LIỆU CƠ SỞ TRONG C

Tên kiểu Kích thước Miền giá trị

Char 1 byte -128 đến 127

Unsign char 1 byte 0 đến 255

int 2 byte -32738 đến 32767

Unsign int 2 byte 0 đến 65335

Unsign long

4 byte

Long 4 byte -232 đến 231 - 1

0 đến 232 - 1 3.4E-38 đến 3.4E38

Float 4 byte

double 8 byte 1.7E-308 đến 1.7E308

11

10 byte 3.4E-4932 đến 1.1E4932 Long double 10/30/2015

Bài giảng nhập môn lập trình

HẰNG - CONSTANT

const int days_int_week = 7

10/30/2015

12

 Chứa dữ liệu không thể thay đổi trong chương trình  Muốn sử dụng phải khai báo  Phải có kiểu  Hằng số có chứa “. “ hoặc “e” có kiểu doube  Hằng số kiểu float kết thúc bởi “F”  Hằng số kiểu long double kết thúc bởi “L”  Hằng số không có các kí tự trên có kiểu int  Khai báo hằng long int phải thêm vào cuối “L”

Bài giảng nhập môn lập trình

6

10/30/2015

VÍ DỤ VỀ HẰNG

10/30/2015

13

Bài giảng nhập môn lập trình

HẰNG XỬ LÝ TRƯỚC BIÊN DỊCH

10/30/2015

14

 Các hằng có thể được xác lập trước khi biên dịch  Bản chất là tìm kiếm và thay thế

Bài giảng nhập môn lập trình

7

10/30/2015

TOÁN TỬ TRONG C

10/30/2015

15

 Các phép toán số học  Ép kiểu  Các toán tử trên bit  Các toán tử so sánh  Phép gán  Toán tử sizeof  Biểu thức điều kiện

Bài giảng nhập môn lập trình

TOÁN TỬ SỐ HỌC

+ Cộng

- Trừ

Nhân *

Chia /

 Ngôn ngữ lập trình C hỗ trợ các phép toán số học: 

 Lưu ý:

• “/” cho kết quả phụ thuộc vào kiểu của toán hạng • “%” không thực hiện được với các số thực

10/30/2015

16

% Chia lấy dư

Bài giảng nhập môn lập trình

8

10/30/2015

VÍ DỤ VỀ TOÁN TỬ CHIA “/”

 Trình biên dịch dựa vào kiểu của các toán hạng để quyết

10/30/2015

17

định phép chia tương ứng

Bài giảng nhập môn lập trình

ÉP KIỂU

10/30/2015

18

 Ép kiểu làm thay đổi tạm thời kiểu của một biến trong biểu thức.

Bài giảng nhập môn lập trình

9

10/30/2015

PHÉP TĂNG/GIẢM 1

 NNLT C có 02 toán tử đặc biệt hỗ trợ việc tăng (giảm) giá trị của một biến thay đổi 1 đơn vị: ++ (tăng 1); -- (giảm 1)

10/30/2015

19

 Các toán tử này có thể đặt ở trước hoặc sau biến:

Bài giảng nhập môn lập trình

PHÉP TĂNG/GIẢM 1

10/30/2015

20

Bài giảng nhập môn lập trình

10

10/30/2015

KIỂU LUẬN LÝ TRONG C

10/30/2015

21

 Trong C không có kiểu luận lý (thể hiện giá trị ĐÚNG – SAI), thay vào đó, các biểu thức so sánh cho kết quả là số: • Giá trị 0 ứng với kết quả SAI • Các giá trị khác đều được xem là ĐÚNG

Bài giảng nhập môn lập trình

CÁC TOÁN TỬ SO SÁNH

 NNLT C hỗ trợ các phép so sánh

< Bé hơn

<= Bé hơn hoặc bằng

> Lớn hơn

>= Lớn hơn hoặc bằng

== Bằng

!= Không bằng

 Tất cả đều cho kết quả 1 khi so sánh đúng và 0 trong trường hợp

ngược lại

10/30/2015

22

Bài giảng nhập môn lập trình

11

10/30/2015

TOÁN TỬ LUẬN LÝ

 NNLT C hỗ trợ các toán tử luận lý:

&& Và (and)

|| Hoặc (or)

! Phủ định (not)

 Tất cả đều cho kết quả 1 hoặc 0 tương ứng trường hợp

10/30/2015

23

ĐÚNG hoặc SAI

Bài giảng nhập môn lập trình

TOÁN TỬ LUẬN LÝ

 Lưu ý: khi sử dụng toán tử luận lý, nếu không có các dấu

10/30/2015

24

(), các phép toán được thực hiện từ trái sang phải.

Bài giảng nhập môn lập trình

12

10/30/2015

PHÉP GÁN

10/30/2015

25

 Có thể sử dụng liên tiếp nhiều phép gán.  Giá trị được gán sẽ sẵn sàng cho lệnh kế tiếp.

Bài giảng nhập môn lập trình

PHÉP GÁN

10/30/2015

26

 Chú ý:  Vế trái phép gán luôn phải là biến.  Phân biệt giữa phép so sánh “==” và phép gán “=”.

Bài giảng nhập môn lập trình

13

10/30/2015

MỘT SỐ PHÉP GÁN ĐẶC BIỆT

 Phép gán kết hợp toán tử khác:

biến op=biểu thức

hoặc biến = biến op (biểu thức )

+= -= *= /= %=

10/30/2015

27

&= |= ^= <<= >>=

Bài giảng nhập môn lập trình

TOÁN TỬ SIZEOF

sizeof (obj)

10/30/2015

28

 Cho biết kích thước của đối tượng theo đơn vị byte

Bài giảng nhập môn lập trình

14

10/30/2015

BIỂU THỨC CHỌN THEO ĐIỀU KIỆN

(điều kiện)?BT1:BT2

 Biểu thức nhận giá trị BT1 nếu điều kiện ĐÚNG, các

trường hợp khác nhận giá trị BT2.

10/30/2015

29

 Có thể định nghĩa sẵn một macro để tìm số lớn: #define max(x, y) ((x>y) ((x>y) ? x:y)

Bài giảng nhập môn lập trình

ĐỘ ƯU TIÊN CỦA TOÁN TỬ

 Thứ tự thực hiện các toán tử trong một biểu thức phụ thuộc vào độ ưu tiên của chúng.  Có 15 mức ưu tiên.  Thông thường, toán tử một ngôi có độ ưu tiên cao hơn toán tử hai ngôi.

 Các cặp dấu ngoặc đơn () thường

10/30/2015

30

được dùng để chỉ rõ thứ tự các toán tử.

Bài giảng nhập môn lập trình

15

10/30/2015

BẢNG THỨ TỰ ƯU TIÊN CÁC TOÁN TỬ

10/30/2015

31

Bài giảng nhập môn lập trình

CẤU TRÚC ĐIỀU KHIỂN

G V : T H S . L Ê T H Ị N G Ọ C H Ạ N H

32

10/30/2015

Bài giảng nhập môn lập trình

16

10/30/2015

NỘI DUNG

Lệnh rẽ nhánh: if – else Lệnh rẽ nhiều nhánh: switch Vòng lặp: while, do…while, for Các từ khóa: break và continue

10/30/2015

33

Bài giảng nhập môn lập trình

LỆNH RẼ NHÁNH IF

 Cú pháp: if (điều kiện)

C;

10/30/2015

34

Điều kiện: biểu thức cho kết quả số, phải được đặt trong cặp ngoặc đơn () C: phải là câu lệnh, nếu nhiều hơn 1 lệnh, các lệnh phải được đặt trong cặp ngoặc nhọn { }

Bài giảng nhập môn lập trình

17

10/30/2015

LỆNH RẼ NHÁNH IF - ELSE

C;

if (điều kiện) else

Ce ;

 Cú pháp:  Phần lệnh else có thể thêm vào trong câu lệnh if để chỉ các

10/30/2015

35

lệnh thực hiện nếu điều kiện bằng 0 (FALSE)

Bài giảng nhập môn lập trình

NHIỀU LỆNH IF LỒNG NHAU

10/30/2015

36

 else kết nối với lệnh if gần nhất

Bài giảng nhập môn lập trình

18

10/30/2015

CẤU TRÚC NHIỀU CHỌN LỰA SWITCH

 Biểu thức: cho kết quả

số nguyên;  Ci: dãy lệnh

case giá trị:C1; break; case giá trị:C2; break; .... case giá trị:Cn; break; default: Ce;

 Cú pháp: switch(biểu thức) { }

10/30/2015

37

Bài giảng nhập môn lập trình

VÍ DỤ - SWITCH

10/30/2015

38

Bài giảng nhập môn lập trình

19

10/30/2015

SƠ ĐỒ HOẠT ĐỘNG CẤU TRÚC SWITCH

10/30/2015

39

Bài giảng nhập môn lập trình

LỆNH LẶP WHILE

while(điều kiện) C;

10/30/2015

40

 Cú pháp:  Điều kiện: biểu thức cho kết quả SỐ  C: (các) lệnh được thực hiện nếu điều kiện ĐÚNG  While thực hiện lệnh C ít nhất 0 lần.

Bài giảng nhập môn lập trình

20

10/30/2015

LỆNH LẶP DO - WHILE

 Cú pháp:

 Điều kiện: biểu thức cho kết quả SỐ  C: là (các) câu lệnh được thực hiện nếu điều kiện ĐÚNG  do – while thực hiện lệnh C ít nhất 1 lần.

10/30/2015

41

do C; while(điều kiện);

Bài giảng nhập môn lập trình

LỆNH LẶP FOR

10/30/2015

42

for(khởi động; điều kiện lặp; điều khiển) C;  Ví dụ: for(int i=0; i<5; i++) printf("%d",i);

Bài giảng nhập môn lập trình

21

10/30/2015

LỆNH LẶP FOR

printf("sine of %.1lf is %.2lf\n",angle,

10/30/2015

43

 C không giới hạn độ lớn bước lặp trong for.  Ví dụ: double angle; for(angle = 0.0; angle < 3.14159; angle += 0.2) sin(angle));

Bài giảng nhập môn lập trình

BREAK

 Từ khóa break chỉ việc thoát ngay lập tức khỏi cấu trúc

10/30/2015

44

điều khiển.

Bài giảng nhập môn lập trình

22

10/30/2015

CONTINUE

 Từ khóa continue chỉ bước nhanh đến bước lặp kế, bất kể

10/30/2015

45

phía sau đó còn nhiều lệnh cần lặp.

Bài giảng nhập môn lập trình

BÀI TẬP

A = (x2 + x + 1)n + (x2 – x +2)n

10/30/2015

46

Bài 1: Nhập vào một số nguyên n và một số thực x. Tính và in ra biểu thức sau: Bài 2: Viết chương trình minh họa các phép toán với các kiểu dữ liệu cơ sở đã học. Bài 3: Viết chương trình nhập vào 2 số nguyên. Xuất ra số lớn nhất và số nhỏ nhất trong 2 số đã nhập. Bài 4: Biện luận phương trình bậc 2. Bài 5: Viết chương trình nhập vào một số nguyên dương từ 1 đến 7. Tương ứng giá trị n, xuất ra ngày trong tuần ứng với giá trị đó.

Bài giảng nhập môn lập trình

23

10/30/2015

HÀM

G V : T H S . L Ê T H Ị N G Ọ C H Ạ N H

47

10/30/2015

Bài giảng nhập môn lập trình

NỘI DUNG

 Khái niệm và cú pháp Tầm vực Tham số và lời gọi hàm

10/30/2015

48

Bài giảng nhập môn lập trình

24

10/30/2015

ĐẶT VẤN ĐỀ

 Viết chương trình tính S = a! + b! + c! với a, b, c là 3 số

10/30/2015

49

nguyên dương nhập từ bàn phím

Bài giảng nhập môn lập trình

ĐẶT VẤN ĐỀ

10/30/2015

50

 3 đoạn lệnh nhập a, b, c dương

Bài giảng nhập môn lập trình

25

10/30/2015

ĐẶT VẤN ĐỀ

10/30/2015

51

 3 đoạn lệnh tính s!=a1, s2=b!, s3=c!

Bài giảng nhập môn lập trình

ĐẶT VẤN ĐỀ

 Giải pháp: viết 1 lần và sử dụng nhiều lần  Đoạn lệnh nhập tổng quát, với n thay bằng a, b, c

10/30/2015

52

 Đoạn lênh tính giai thừa tổng quát, với n bằng a, b, c

Bài giảng nhập môn lập trình

26

10/30/2015

KHÁI NIỆM

 Một đoạn chương trình có tên, đầu vào và đầu ra.  Có chức năng giải quyết một số vấn đề chuyên biệt cho chương trình chính.

 Được gọi nhiều lần với các tham số khác nhau.  Được sử dụng khi có nhu cầu:

10/30/2015

53

• Tái sử dụng. • Sửa lỗi và cải tiến

Bài giảng nhập môn lập trình

CÚ PHÁP

[return ;]

([]) { } Trong đó: : kiểu bất kỳ của C (char, int, long, float,…). Nếu không trả về thì là void. : theo quy tắc đặt tên định danh. : tham số hình thức đầu vào giống khai báo biến, cách nhau bằng dấu “,” : trả về cho hàm qua lệnh return.

10/30/2015

54

Bài giảng nhập môn lập trình

27

10/30/2015

CÁC BƯỚC VIẾT HÀM

 Cần xác định các thông tin sau đây:

10/30/2015

55

• Tên hàm. • Hàm sẽ thực hiện công việc gì. • Các đầu vào (nếu có). • Đầu ra (nếu có).

Bài giảng nhập môn lập trình

HÀM

 Ví dụ 1

10/30/2015

56

• Tên hàm: XuatTong • Công việc: tính và xuất tổng 2 số nguyên • Đầu vào: hai số nguyên x và y • Đầu ra: không có

Bài giảng nhập môn lập trình

28

10/30/2015

HÀM

 Ví dụ 2:

10/30/2015

57

• Tên hàm: TinhTong • Công việc: tính và trả về tổng 2 số nguyên • Đầu vào: hai số nguyên x và y • Đầu ra: một số nguyên có giá trị x + y

Bài giảng nhập môn lập trình

CHƯƠNG TRÌNH CON

10/30/2015

58

 Ví dụ 3: • Tên hàm: NhapXuatTong • Công việc: nhập và xuất tổng 2 số nguyên • Đầu vào: không có • Đầu ra: không có

Bài giảng nhập môn lập trình

29

10/30/2015

TẦM VỰC

 Khái niệm:

• Là phạm vi hiệu quả của biến và hàm. • Biến:

10/30/2015

59

• Toàn cục: khai báo trong ngoài tất cả các hàm (kể cả hàm main) và có tác dụng lên toàn bộ chương trình. • Cục bộ: khai báo trong hàm hoặc khối { } và chỉ có tác dụng trong bản thân hàm hoặc khối đó (kể cả khối con nó). Biến cục bộ sẽ bị xóa khỏi bộ nhớ khi kết thúc khối khai báo nó.

Bài giảng nhập môn lập trình

10/30/2015

60

Bài giảng nhập môn lập trình

30

10/30/2015

MỘT SỐ LƯU Ý

10/30/2015

61

Thông thường người ta thường đặt phần tiêu đề hàm/nguyên mẫu hàm (prototype) trên hàm main và phần định nghĩa hàm dưới hàm main.

Bài giảng nhập môn lập trình

CÁCH TRUYỀN CÁC ĐỐI SỐ

 Truyền Giá trị (Call by Value)

• Truyền đối số cho hàm ở dạng giá trị. • Có thể truyền hằng, biến, biểu thức nhưng hàm chỉ sẽ nhận giá trị.

10/30/2015

62

• Được sử dụng khi không có nhu cầu thay đổi giá trị của tham số sau khi thực hiện hàm.

Bài giảng nhập môn lập trình

31

10/30/2015

CÁCH TRUYỀN CÁC ĐỐI SỐ

 Truyền Địa chỉ (Call by Address)

khi thực hiện hàm.

10/30/2015

63

• Truyền đối số cho hàm ở dạng địa chỉ (con trỏ). • Không được truyền giá trị cho tham số này. • Được sử dụng khi có nhu cầu thay đổi giá trị của tham số sau

Bài giảng nhập môn lập trình

CÁCH TRUYỀN CÁC ĐỐI SỐ

 Truyền Tham chiếu (Call by Reference) (C++)

• Không được truyền giá trị cho tham số này. • Được sử dụng khi có nhu cầu thay đổi giá trị của tham số sau

• Truyền đối số cho hàm ở dạng địa chỉ (con trỏ). Được bắt đầu bằng & trong khai báo.

10/30/2015

64

khi thực hiện hàm.

Bài giảng nhập môn lập trình

32

10/30/2015

LƯU Ý KHI TRUYỀN THAM SỐ

10/30/2015

65

 Trong một hàm, các tham số có thể truyền theo nhiều cách.

Bài giảng nhập môn lập trình

LƯU Ý KHI TRUYỀN THAM SỐ

10/30/2015

66

 Sử dụng tham chiếu là một cách để trả về giá trị cho chương trình.

Bài giảng nhập môn lập trình

33

10/30/2015

LỜI GỌI HÀM

 Cách thực hiện:

• Gọi tên của hàm đồng thời truyền các đối số (hằng, biến, biểu thức) cho các tham số theo đúng thứ tự đã được khai báo trong hàm.

• Các biến hoặc trị này cách nhau bằng dấu “,” • Các đối số này được được đặt trong cặp dấu ngoặc đơn ( )

10/30/2015

67

(<đối số 1>,… , <đối số n>);

Bài giảng nhập môn lập trình

LỜI GỌI HÀM

// Các hàm được khai báo ở đây

void main() {

int n = 9; XuatTong(1, 2); XuatTong(1, n); TinhTong(1, 2); int tong = TinhTong(1, 2); TruyenGiaTri(1); TruyenGiaTri(n); TruyenDiaChi(1); TruyenDiaChi(&n); TruyenThamChieu(1); TruyenThamChieu(n);

68

Bài giảng nhập môn lập trình

10/30/2015 }

34

10/30/2015

LỜI GỌI CHƯƠNG TRÌNH CON

10/30/2015

69

Bài giảng nhập môn lập trình

BÀI TẬP

10/30/2015

70

Viết hàm nhận vào một số nguyên dương n và thực hiện các yêu cầu sau (mỗi câu một hàm riêng): a. Có phải là số chính phương. b. Có phải là số nguyên tố. c. Tổng các chữ số lẻ. d. Tổng các chữ số nguyên tố. e. Tổng các chữ số chính phương.

Bài giảng nhập môn lập trình

35

10/30/2015

MẢNG

G V : T H S . L Ê T H Ị N G Ọ C H Ạ N H

71

10/30/2015

Bài giảng nhập môn lập trình

NỘI DUNG

Khái niệm

1

Khai báo

2

Truy xuất dữ liệu kiểu mảng

3

Một số bài toán trên mảng 1 chiều

10/30/2015

72

4

Bài giảng nhập môn lập trình

36

10/30/2015

ĐẶT VẤN ĐỀ

 Ví dụ

• Chương trình cần lưu trữ 3 số nguyên? => Khai báo 3 biến int a1, a2, a3; • Chương trình cần lưu trữ 100 số nguyên? => Khai báo 100 biến kiểu số nguyên! • Người dùng muốn nhập n số nguyên? => Không thực hiện được!

 Giải pháp

• Kiểu dữ liệu mới cho phép lưu trữ một dãy các số

nguyên và dễ dàng truy xuất.

10/30/2015

73

KTLT - Mảng một chiều

DỮ LIỆU KIỂU MẢNG

• Là một kiểu dữ liệu có cấu trúc do người lập trình định nghĩa. • Biểu diễn một dãy các biến có cùng kiểu. Ví dụ: dãy các số nguyên,

dãy các ký tự…

• Kích thước được xác định ngay khi khai báo và không bao giờ thay

đổi.

• NNLT C luôn chỉ định một khối nhớ liên tục cho một biến kiểu mảng.

10/30/2015

74

 Khái niệm

KTLT - Mảng một chiều

37

10/30/2015

KHAI BÁO BIẾN MẢNG (TƯỜNG MINH)

 Tường minh

[]; [][]…[]; • , …, : số lượng phần tử của mỗi chiều.

• Phải xác định cụ thể (hằng) khi khai báo. • Mảng nhiều chiều: = N1*N2*…*Nn • Bộ nhớ sử dụng = *sizeof() • Bộ nhớ sử dụng phải ít hơn 64KB (65535 Bytes) • Một dãy liên tục có chỉ số từ 0 đến -1

10/30/2015

75

 Lưu ý

KTLT - Mảng một chiều

KHAI BÁO BIẾN MẢNG (TƯỜNG MINH)

 Ví dụ

int Mang1Chieu[10];

0

1

2

3

4

5

6

7

8

9

Mang1Chieu

int Mang2Chieu[3][4];

0

1

2

3

4

5

6

7

8

9

10 11

0

Mang2Chieu

1

2

10/30/2015

76

KTLT - Mảng một chiều

38

10/30/2015

KHAI BÁO BIẾN MẢNG (KHÔNG TƯỜNG MINH)

• Không tường minh (thông qua khai báo kiểu)

 Cú pháp

typedef []; typedef []…[]; ;  Ví dụ

typedef int Mang1Chieu[10]; typedef int Mang2Chieu[3][4]; Mang1Chieu m1, m2, m3; Mang2Chieu m4, m5;

10/30/2015

77

KTLT - Mảng một chiều

SỐ PHẦN TỬ CỦA MẢNG

 Phải xác định cụ thể số phần tử ngay lúc khai báo, không được sử dụng biến hoặc hằng thường

 Nên sử dụng chỉ thị tiền xử lý #define để định nghĩa số

phần tử mảng int n1 = 10; int a[n1]; const int n2 = 20; int b[n2];

#define n1 10 #define n2 20 int a[n1]; int b[n1][n2];

//  int a[10]; //  int b[10][20];

10/30/2015

78

KTLT - Mảng một chiều

39

10/30/2015

KHỞI TẠO GIÁ TRỊ CHO MẢNG LÚC KHAI BÁO

 Gồm các cách sau

• Khởi tạo giá trị cho mọi phần tử của mảng

int a[4] = {2912, 1706, 1506, 1904};

0

1

2

3

a

1706

1506

1904

2912

• Khởi tạo giá trị cho một số phần tử đầu mảng

int a[4] = {2912, 1706};

0

1

2

3

a

2912

1706

0

0

10/30/2015

79

KTLT - Mảng một chiều

KHỞI TẠO GIÁ TRỊ CHO MẢNG LÚC KHAI BÁO

 Gồm các cách sau

• Khởi tạo giá trị 0 cho mọi phần tử của mảng

int a[4] = {0};

0

1

2

3

a

0

0

0

0

• Tự động xác định số lượng phần tử

int a[] = {2912, 1706, 1506, 1904};

0

1

2

3

a

2912

1706

1506

1904

10/30/2015

80

KTLT - Mảng một chiều

40

10/30/2015

TRUY XUẤT ĐẾN MỘT PHẦN TỬ

 Thông qua chỉ số

[][]…[]  Ví dụ

• Cho mảng như sau

0

1

2

3

• Các truy xuất int a[4];

 Hợp lệ: a[0], a[1], a[2], a[3]  Không hợp lệ: a[-1], a[4], a[5], … => Cho kết thường không như mong muốn!

10/30/2015

81

KTLT - Mảng một chiều

GÁN DỮ LIỆU KIỂU MẢNG

 Không được sử dụng phép gán thông thường mà phải gán trực tiếp giữa các phần tử tương ứng

 Ví dụ

= ; //sai [] = ;

// Sai

#define MAX 3 typedef int MangSo[MAX]; MangSo a = {1, 2, 3}, b; b = a; for (int i = 0; i < 3; i++) b[i] = a[i];

10/30/2015

82

KTLT - Mảng một chiều

41

10/30/2015

MỘT SỐ LỖI THƯỜNG GẶP

 Khai báo không chỉ rõ số lượng phần tử • int a[]; => int a[100];  Số lượng phần tử liên quan đến biến hoặc hằng

 Khởi tạo cách biệt với khai báo

• int n1 = 10; int a[n1]; => int a[10]; • const int n2 = 10; int a[n2]; => int a[10];

• int a[4]; a = {2912, 1706, 1506, 1904}; => int a[4] = {2912, 1706, 1506, 1904};  Chỉ số mảng không hợp lệ

10/30/2015

83

• int a[4]; • a[-1] = 1; a[10] = 0;

KTLT - Mảng một chiều

TRUYỀN MẢNG CHO HÀM

• Tham số kiểu mảng trong khai báo hàm giống như khai báo biến

mảng

• Tham số kiểu mảng truyền cho hàm chính là địa chỉ của phần tử đầu

tiên của mảng  Có thể bỏ số lượng phần tử hoặc sử dụng con trỏ.  Mảng có thể thay đổi nội dung sau khi thực hiện hàm.

 Truyền mảng cho hàm

void SapXepTang(int a[100]);

void SapXepTang(int a[]); void SapXepTang(int *a);

10/30/2015

84

KTLT - Mảng một chiều

42

10/30/2015

TRUYỀN MẢNG CHO HÀM

• Số lượng phần tử thực sự truyền qua biến khác

 Truyền mảng cho hàm

 Lời gọi hàm

void SapXepTang(int a[100], int n); void SapXepTang(int a[], int n); void SapXepTang(int *a, int n);

int a[100], n; NhapMang(a, n); XuatMang(a, n);

void NhapMang(int a[], int &n); void XuatMang(int a[], int n); void main() { } 10/30/2015

85

KTLT - Mảng một chiều

MỘT SỐ BÀI TOÁN CƠ BẢN

• Nhập mảng • Xuất mảng • Tìm kiếm một phần tử trong mảng • Kiểm tra tính chất của mảng • Tách mảng / Gộp mảng • Tìm giá trị nhỏ nhất/lớn nhất của mảng • Sắp xếp mảng giảm dần/tăng dần • Thêm/Xóa/Sửa một phần tử vào mảng

10/30/2015

86

 Viết hàm thực hiện từng yêu cầu sau

KTLT - Mảng một chiều

43

10/30/2015

MỘT SỐ QUY ƯỚC

 Số lượng phần tử

#define MAX 100

• Hàm void HoanVi(int &x, int &y): hoán vị giá trị của hai số nguyên. • Hàm int LaSNT(int n): kiểm tra một số có phải là số nguyên tố. Trả

về 1 nếu n là số nguyên tố, ngược lại trả về 0.

10/30/2015

87

 Các hàm

KTLT - Mảng một chiều

THỦ TỤC HOANVI & HÀM LASNT

int tam = x; x = y; y = tam;

int i, dem = 0; for (i = 1; i <= n; i++) if (n%i == 0)

dem++;

return 1;

if (dem == 2) else return 0;

void HoanVi(int &x, int &y) { } int LaSNT(int n) { } 10/30/2015

88

KTLT - Mảng một chiều

44

10/30/2015

NHẬP MẢNG

 Yêu cầu

• Cho phép nhập mảng a, số lượng phần tử n

 Ý tưởng

• Cho trước một mảng có số lượng phần tử là MAX. • Nhập số lượng phần tử thực sự n của mảng. • Nhập từng phần tử cho mảng từ chỉ số 0 đến n – 1.

0

1

2

MAX - 1

3

4 n - 1

10/30/2015

89

KTLT - Mảng một chiều

HÀM NHẬP MẢNG

printf(“Nhap so luong phan tu n: ”); scanf(“%d”, &n);

printf(“Nhap phan tu thu %d: ”, i); scanf(“%d”, &a[i]);

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

void NhapMang(int a[], int &n) { }

10/30/2015

90

KTLT - Mảng một chiều

45

10/30/2015

XUẤT MẢNG

 Yêu cầu

• Cho trước mảng a, số lượng phần tử n. Hãy xuất nội dung mảng a ra màn hình.

 Ý tưởng

• Xuất giá trị từng phần tử của mảng từ chỉ số 0 đến n-1.

n - 1

0

1

2

MAX - 1

10/30/2015

91

KTLT - Mảng một chiều

HÀM XUẤT MẢNG

printf(“Noi dung cua mang la: ”);

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

printf(“%d ”, a[i]);

printf(“\n”);

void XuatMang(int a[], int n) { }

10/30/2015

92

KTLT - Mảng một chiều

46

10/30/2015

TÌM KIẾM MỘT PHẦN TỬ TRONG MẢNG

 Yêu cầu

• Tìm xem phần tử x có nằm trong mảng a kích thước n hay không? Nếu có thì nó nằm ở vị trí đầu tiên nào.

 Ý tưởng

thì trả về vị trí đó. Nếu kô tìm được thì trả về -1.

• Xét từng phần của mảng a. Nếu phần tử đang xét bằng x

vị trí = 1

x

n - 1

0

1

2

MAX - 1

a

x

b

x

10/30/2015

93

KTLT - Mảng một chiều

HÀM TÌM KIẾM (DÙNG WHILE)

int vt = 0;

vt++;

return vt;

while (vt < n && a[vt] != x) if (vt < n) else

return -1;

int TimKiem(int a[], int n, int x) { }

10/30/2015

94

KTLT - Mảng một chiều

47

HÀM TÌM KIẾM (DÙNG FOR)

10/30/2015

for (int vt = 0; vt < n; vt++)

if (a[vt] == x)

return vt;

return -1;

int TimKiem(int a[], int n, int x) { }

10/30/2015

95

KTLT - Mảng một chiều

KIỂM TRA TÍNH CHẤT CỦA MẢNG

 Yêu cầu

 Ý tưởng

• Cho trước mảng a, số lượng phần tử n. Mảng a có phải là mảng toàn các số nguyên tố hay không?

• Cách 1: Đếm số lượng số ngtố của mảng. Nếu số lượng này bằng đúng n thì mảng toàn ngtố.

• Cách 2: Đếm số lượng số không phải ngtố của mảng. Nếu số lượng này bằng 0 thì mảng toàn ngtố.

10/30/2015

96

• Cách 3: Tìm xem có phần tử nào không phải số ngtố không. Nếu có thì mảng không toàn số ngtố.

KTLT - Mảng một chiều

48

10/30/2015

HÀM KIỂM TRA (CÁCH 1)

int dem = 0;

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

if (LaSNT(a[i]) == 1) // có thể bỏ == 1

dem++;

return 1;

if (dem == n) return 0;

int KiemTra_C1(int a[], int n) { }

10/30/2015

97

KTLT - Mảng một chiều

HÀM KIỂM TRA (CÁCH 2)

int dem = 0;

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

dem++;

if (LaSNT(a[i]) == 0) // Có thể sử dụng !

return 1;

if (dem == 0) return 0;

int KiemTra_C2(int a[], int n) { }

10/30/2015

98

KTLT - Mảng một chiều

49

10/30/2015

HÀM KIỂM TRA (CÁCH 3)

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

if (LaSNT(a[i]) == 0) return 0;

return 1;

int KiemTra_C3(int a[], int n) { }

10/30/2015

99

KTLT - Mảng một chiều

TÁCH CÁC PHẦN TỬ THỎA ĐIỀU KIỆN

 Yêu cầu

 Ý tưởng

• Cho trước mảng a, số lượng phần tử na. Tách các số nguyên tố có trong mảng a vào mảng b.

• Duyệt từ phần tử của mảng a, nếu đó là số nguyên tố thì

10/30/2015

100

đưa vào mảng b.

KTLT - Mảng một chiều

50

10/30/2015

HÀM TÁCH SỐ NGUYÊN TỐ

b[nb] = a[i]; nb++;

nb = 0; for (int i = 0; i < na; i++)

if (LaSNT(a[i]) == 1) { }

void TachSNT(int a[], int na, int b[], int &nb) { }

10/30/2015

101

KTLT - Mảng một chiều

TÁCH MẢNG THÀNH 2 MẢNG CON

 Yêu cầu

• Cho trước mảng a, số lượng phần tử na. Tách mảng a

thành 2 mảng b (chứa số nguyên tố) và mảng c (các số còn lại).

 Ý tưởng

• Cách 1: viết 1 hàm tách các số nguyên tố từ mảng a sang mảng b và 1 hàm tách các số không phải nguyên tố từ mảng a sang mảng c.

• Cách 2: Duyệt từ phần tử của mảng a, nếu đó là số nguyên

10/30/2015

102

tố thì đưa vào mảng b, ngược lại đưa vào mảng c.

KTLT - Mảng một chiều

51

10/30/2015

HÀM TÁCH 2 MẢNG

int b[], int &nb, int c[], int &nc)

nb = 0; nc = 0;

b[nb] = a[i]; nb++;

for (int i = 0; i < na; i++)

if (LaSNT(a[i]) == 1) { } else { }

c[nc] = a[i]; nc++;

void TachSNT2(int a[], int na, { } 10/30/2015

103

KTLT - Mảng một chiều

GỘP 2 MẢNG THÀNH MỘT MẢNG

 Yêu cầu

• Cho trước mảng a, số lượng phần tử na và mảng b số

lượng phần tử nb. Gộp 2 mảng trên theo tứ tự đó thành mảng c, số lượng phần tử nc.

 Ý tưởng

10/30/2015

104

• Chuyển các phần tử của mảng a sang mảng c => nc = na • Tiếp tục đưa các phần tử của mảng b sang mảng c => nc = nc + nb

KTLT - Mảng một chiều

52

10/30/2015

HÀM GỘP MẢNG

int c[], int &nc)

nc = 0;

c[nc] = a[i]; nc++; // c[nc++] = a[i];

for (int i = 0; i < na; i++) { }

c[nc] = b[i]; nc++; // c[nc++] = b[i];

for (int i = 0; i < nb; i++) { }

void GopMang(int a[], int na, int b[], int nb, { }

10/30/2015

105

KTLT - Mảng một chiều

TÌM GIÁ TRỊ LỚN NHẤT CỦA MẢNG

 Yêu cầu

• Cho trước mảng a có n phần tử. Tìm giá trị lớn nhất trong a (gọi là max)

 Ý tưởng

• Giả sử giá trị max hiện tại là giá trị phần tử đầu tiên a[0] • Lần lượt kiểm tra các phần tử còn lại để cập nhật max.

7 8 ?

max

n – 1

0

1

2

MAX - 1

7

2

8

8

10/30/2015

106

KTLT - Mảng một chiều

53

HÀM TÌM MAX

10/30/2015

int max = a[0];

for (int i = 1; i < n; i++) if (a[i] > max)

max = a[i];

return max;

int TimMax(int a[], int n) { }

10/30/2015

107

KTLT - Mảng một chiều

SẮP XẾP MẢNG THÀNH TĂNG DẦN

 Yêu cầu

 Ý tưởng

• Cho trước mảng a kích thước n. Hãy sắp xếp mảng a đó sao cho các phần tử có giá trị tăng dần.

• Sử dụng 2 biến i và j để so sánh tất cả cặp phần tử với nhau và hoán vị các cặp nghịch thế (sai thứ tự).

8 5

tạm

n – 1

0

1

MAX - 1

2

1 5

5 1

6 8

8 6

10/30/2015

108

KTLT - Mảng một chiều

j

j

j

i

j

54

10/30/2015

HÀM SẮP XẾP TĂNG

if (a[i] > a[j])

HoanVi(a[i], a[j]);

for (j = i + 1; j < n; j++) { }

int i, j; for (i = 0; i < n – 1; i++) { }

void SapXepTang(int a[], int n) { }

10/30/2015

109

Bài giảng nhập môn lập trình

HÀM SẮP XẾP TĂNG

if (a[i] > a[j])

HoanVi(a[i], a[j]);

for (j = i + 1; j < n; j++) { }

int i, j; for (i = 0; i < n – 1; i++) { }

void SapXepTang(int a[], int n) { }

10/30/2015

110

KTLT - Mảng một chiều

55

10/30/2015

THÊM MỘT PHẦN TỬ VÀO MẢNG

 Yêu cầu

• Thêm phần tử x vào mảng a kích thước n tại vị trí vt.

 Ý tưởng

• “Đẩy” các phần tử bắt đầu tại vị trí vt sang phải 1 vị trí. • Đưa x vào vị trí vt trong mảng. • Tăng n lên 1 đơn vị.

x

chèn?

n – 1

n

0

1

2

MAX - 1

3

a

b

c c

z z

… …

10/30/2015

111

KTLT - Mảng một chiều

vt

HÀM THÊM

for (int i = n; i > vt; i--) a[i] = a[i - 1];

a[vt] = x; n++;

if (vt >= 0 && vt <= n) { }

void Them(int a[], int &n, int vt, int x) { }

10/30/2015

112

KTLT - Mảng một chiều

56

10/30/2015

XÓA MỘT PHẦN TỬ TRONG MẢNG

 Yêu cầu

• Xóa một phần tử trong mảng a kích thước n tại vị trí vt

 Ý tưởng

• “Kéo” các phần tử bên phải vị trí vt sang trái 1 vị trí. • Giảm n xuống 1 đơn vị.

xóa?

n - 1

n – 1

0

2

1

MAX - 1

a

b b

x

z z

… …

10/30/2015

113

KTLT - Mảng một chiều

vt

HÀM XÓA

for (int i = vt; i < n – 1; i++)

a[i] = a[i + 1];

n--;

if (vt >= 0 && vt < n) { }

void Xoa(int a[], int &n, int vt) { }

10/30/2015

114

KTLT - Mảng một chiều

57

10/30/2015

BÀI TẬP THỰC HÀNH

a. Nhập mảng b. Xuất mảng

1. Các thao tác nhập xuất

a. Mảng có phải là mảng toàn chẵn b. Mảng có phải là mảng toàn số nguyên tố c. Mảng có phải là mảng tăng dần

10/30/2015

115

2. Các thao tác kiểm tra

KTLT - Mảng một chiều

BÀI TẬP THỰC HÀNH

a. Có bao nhiêu số chia hết cho 4 nhưng không chia hết cho 5 b.

Tổng các số nguyên tố có trong mảng

3. Các thao tác tính toán

a. Vị trí cuối cùng của phần tử x trong mảng b. Vị trí số nguyên tố đầu tiên trong mảng nếu có Tìm số nhỏ nhất trong mảng c. d. Tìm số dương nhỏ nhất trong mảng

10/30/2015

116

4. Các thao tác tìm kiếm

KTLT - Mảng một chiều

58

10/30/2015

BÀI TẬP THỰC HÀNH

a. b.

c. d.

Tách các số nguyên tố có trong mảng a đưa vào mảng b. Tách mảng a thành 2 mảng b (chứa các số nguyên dương) và c (chứa các số còn lại) Sắp xếp mảng giảm dần Sắp xếp mảng sao cho các số dương đứng đầu mảng giảm dần, kế đến là các số âm tăng dần, cuối cùng là các số 0.

10/30/2015

117

5. Các thao tác xử lý

KTLT - Mảng một chiều

BÀI TẬP THỰC HÀNH

Sửa các số nguyên tố có trong mảng thành số 0

a. b. Chèn số 0 đằng sau các số nguyên tố trong mảng c.

Xóa tất cả số nguyên tố có trong mảng

10/30/2015

118

6. Các thao tác thêm/xóa/sửa

KTLT - Mảng một chiều

59

10/30/2015

CHUỖI

G V : T H S . L Ê T H Ị N G Ọ C H Ạ N H

11 9

10/30/2015

Bài giảng nhập môn lập trình

NỘI DUNG

 Khái niệm Khởi tạo Các thao tác xử lý trên chuỗi

10/30/2015

120

Bài giảng nhập môn lập trình

60

10/30/2015

KHÁI NIỆM

 Kiểu char chỉ chứa được một ký tự. Để lưu trữ một chuỗi (nhiều ký tự) ta sử dụng mảng (một chiều) các ký tự.

 Chuỗi ký tự kết thúc bằng ký tự “\0” (null)  Độ dài chuỗi = kích thước mảng – 1

10/30/2015

121

char szHoten[30]; // Dài 29 ký tự char szNgaySinh[9]; // Dài 8 ký tự

Bài giảng nhập môn lập trình

KHỞI TẠO

10/30/2015

122

 Khởi tạo như mảng thông thường  Độ dài cụ thể

Bài giảng nhập môn lập trình

61

10/30/2015

KHỞI TẠO

10/30/2015

123

Bài giảng nhập môn lập trình

XUẤT CHUỖI

 Sử dụng hàm puts

10/30/2015

124

 Sử dụng hàm printf với đặc tả “%s”

Bài giảng nhập môn lập trình

62

10/30/2015

NHẬP CHUỖI

 Sử dụng hàm scanf với đặc tả “%s”  Chỉ nhận các ký tự từ bàn phím đến khi gặp ký tự khoảng trắng hoặc ký tự xuống dòng.

 Chuỗi nhận được không bao gồm ký tự khoảng trắng và

10/30/2015

125

xuống dòng

Bài giảng nhập môn lập trình

NHẬP CHUỖI

10/30/2015

126

 Sử dụng hàm gets:  Nhận các ký tự từ bàn phím đến khi gặp ký tự xuống dòng.  Chuỗi nhận được là những gì người dùng nhập (trừ ký tự xuống dòng).

Bài giảng nhập môn lập trình

63

10/30/2015

MỘT SỐ HÀM THAO TÁC TRÊN CHUỖI

 Thuộc thư viện

10/30/2015

127

strlen strcpy strdup strlwr/strupr strrev strcmp/stricmp strcat strstr

Bài giảng nhập môn lập trình

64