8/15/2017

 Số tín chỉ: 3 (30,15)  Mã HP: INFO0621  Đánh giá:

 ĐCC: 0.1; ĐTH: 0.3; ĐT: 06

Số tín chỉ: 3 Bộ môn: Tin học

 Mục tiêu: Cung cấp các kiến thức cơ bản về thiết kế thuật toán và lập trình trên máy tính điện tử, làm quen với một số nguyên tắc và công cụ lập trình cơ bản

 Bắt buộc

Chương

Số tiết LT TH

Chương 1. Tổng quan về cơ sở lập trình

6

6

0

Chương 2. Các thành phần cơ sở

13

9

4

[1].TS Nguyễn Thị Thu Thủy. Giáo trình cơ sở lập trình. NXB Thống kế, 2014. [2]. Phạm Văn Ất. Kỹ thuật lập trình C. NXB GTVT, 2008. [3]. Phạm Hồng Thái. Cơ sở lập trình. NXB ĐHQG, 2007.

 Khuyến khích

Chương 3. Mảng, xâu và con trỏ

9

5

4

Chương 4. Hàm

9

4

5

Chương 5. Kiểu dữ liệu có cấu trúc

8

6

2

Tổng

45

30

15

[1]. Robert Sedgewick. Cẩm nang thuật toán. NXB KHKT, 1994. [2]. Quách Tuấn Ngọc. Ngôn ngữ lập trình C. NXB Thống kế, 2003. [3]. www.cprogramming.com/tutorial.html

1

8/15/2017

1.1. Thuật toán

1.1.1 Khái niệm

1.2. Sơ đồ khối

1.1.2 Tính chất của thuật toán

1.3. Chương trình và ngôn ngữ lập trình

1.4. Các phương pháp lập trình

1.1.3 Ví dụ

1.5. Kỹ thuật thiết kế chương trình

 Tính vào (input)  Tính ra (output)  Tính đơn định (xác định / đơn nghĩa)  Tính đúng đắn  Tính dừng (tính kết thúc / tính đóng)  Tính phổ dụng  Tính khả thi/hiệu quả

7-2010 Cơ sở lập trình 5 7-2010 Cơ sở lập trình 6

Khái niệm 1: Thuật toán là một dãy hữu hạn các bước được sắp xếp theo một trật tự xác định, mỗi bước mô tả chính xác các phép toán hoặc hành động cần thực hiện, để giải quyết một vấn đề. Khái niệm 2: Thuật toán là một dãy hữu hạn các thao tác, sắp xếp theo một trật tự xác định, sau khi thực hiện, từ Input ta nhận được Output cần tìm.

7-2010 Cơ sở lập trình 7 7-2010 Cơ sở lập trình 8

2

8/15/2017

 Thuật toán:

 Yêu cầu: Xây dựng thuật toán để giải phương trình:

ax + b=0

Trong đó a,b là các số thực được nhập vào từ bàn

phím

Nếu đúng chuyển sang bước 3. Nếu sai chuyển sang bước 5.

+ Bước 1: Nhập a, b. + Bước 2: Kiểm tra a≠0? + Bước 3: Tính nghiệm x = -b/a. + Bước 4: In x rồi chuyển bước 8. + Bước 5: Kiểm tra b≠0? Nếu đúng chuyển sang bước 6. Nếu sai chuyển sang bước 7. + Bước 6: In “PTVN”, rồi chuyển bước sang 8. + Bước 7: In “PTCVSN”. + Bước 8: Kết thúc.

 Phân tích: Input: a, b Output: kết luận về x Có 3 khả năng xảy ra: - Có một nghiệm duy nhất: x = -b/a khi a≠0. - Phương trình vô nghiệm khi a=0 và b≠0. - Phương trình có vô số nghiệm khi a=0 và b=0. 9 7-2010

Cơ sở lập trình

1.2.1 Khái niệm

1.2.2 Các cấu trúc điều khiển

1.2.3 Ví dụ

Khái niệm 1: Sơ đồ khối là tập hợp các ký hiệu và quy tắc dùng để biểu diễn thuật toán Khái niệm 2: Sơ đồ khối là cách thể hiện thuật toán bằng các hình khối hình học nối với nhau bằng đường đi có hướng Các thành phần: Hình thoi: thể hiện thao tác so sánh Hình chữ nhật: thể hiện các phép tính toán Hình bình hành: thể hiện thao tác nhập xuất dữ liệu Hình oval: thể hiện sự bắt đầu/kết thúc của thuật toán. Các mũi tên: thể hiện trình tự thực hiện các thao tác

7-2010 Cơ sở lập trình 11 Cơ sở lập trình 7-2010 12

3

8/15/2017

 Các khối

X=-b/a

 Sơ đồ khối dạng tuần tự: Là sơ đồ khối thể hiện thuật toán gồm n khối mà khi thực hiện thuật toán với một bộ dữ liệu cụ thể sẽ lần lượt thực hiện từ khối đầu tiên đến khối cuối cùng theo thứ tự viết của nó.

a=0

Khối tính toán

Khối bắt đầu

Khối kiểm tra điều kiện

 Sơ đồ khối dạng rẽ nhánh: Là sơ đồ khối thể hiện thuật toán gồm n nhánh mà khi thực hiện thuật toán với một bộ dữ liệu cụ thể sẽ thực hiện một trong n nhánh mà thôi.

KT

Vào/ra a

Hướng thực hiện.

Khối Vào/Ra

 Sơ đồ khối dạng chu trình: Là sơ đồ khối thể hiện thuật toán gồm n khối mà khi thực hiện thuật toán với một bộ dữ liệu cụ thể sẽ có một số khối lặp đi lặp lại nhiều lần phụ thuộc vào một điều kiện nào đó vẫn thỏa mãn.

Khối kết thúc

7-2010 Cơ sở lập trình 13 7-2010 Cơ sở lập trình 14

a) Cấu trúc tuần tự:

Có 4 dạng cơ bản.

Dạng thứ nhất:

Dạng thứ hai:

S

S

Đ

Đ

4

8/15/2017

Dạng thứ tư:

Có 2 dạng cơ bản.

Dạng thứ ba:

Dạng thứ nhất:

Dạng thứ hai:

S

S

Đ

BĐK=n1

Đ

BĐK=n1

S

S

Đ

S

Đ

ĐK lặp

CV lặp

S

Đ

Đ

S

CV lặp

BĐK=BĐK +n2

Đ

Đ

BĐK=BĐK +n2

ĐK lặp

S

Nhập a, b

ax + b=0

Xây dựng sơ đồ khối mô tả thuật toán giải phương trình: Trong đó a,b là các số thực được nhập vào từ bàn phím

8/15/ 2017 19 Cơ sở lập trình KT

5

8/15/2017

1.3.1 Chương trình

Làm việc với dãy số nguyên:

1.3.2 Ngôn ngữ lập trình

Tìm giá trị lớn nhất của dãy

1.3.3 Trình tự giải bài toán trên MTĐT

Tính tổng các phầns tử của dãy mà chia hết cho 3

1.3.4 Đánh giá chương trình MTĐT

7-2010 Cơ sở lập trình 21 7-2010 Cơ sở lập trình 22

Khái niệm: Ngôn ngữ lập trình là ngôn ngữ để

viết chương trình.

Phân loại: (phụ thuộc vào kiến trúc và hoạt

Khái niệm: Chương trình là một tập hợp các lệnh để thể hiện một thuật toán giải quyết một bài toán hay một nhiệm vụ nào đó. Trong đó: Lệnh: là một chỉ thị để máy tính có thể thực hiện một cách tự động.

động của máy tính)  Ngôn ngữ máy (ngôn ngữ bậc thấp)  Ngôn ngữ hợp ngữ  Ngôn ngữ bậc cao

7-2010 Cơ sở lập trình 23 7-2010 Cơ sở lập trình 24

6

8/15/2017

 Mục tiêu: xây dựng chương trình tốt, có chất lượng

 Tiêu chuẩn đánh giá:

 Tính đúng đắn:

 Tính bền vững:

 Tính sử dụng lại

 Tính thích nghi (mở rộng)

 Tính tương thích

Bước 1: Xác định bài toán Bước 2: Tìm cấu trúc biểu diễn bài toán Bước 3: Chọn phương pháp giải Bước 4: Lập trình giải bài toán Bước 5: Thử nghiệm chương trình Bước 6: Tối ưu chương trình (bảo trì)

 Tính hiệu quả

 Tính dễ chuyển đổi

 Tính an toàn

 Thân thiện với người sử dụng

 1.4.1 Lập trình hướng thủ tục  1.4.2 Lập trình hướng đối tượng

 Tư tưởng: Chia nhỏ bài toán cho đến khi không còn chia nhỏ được nữa. Từ đó xây dựng cấu trúc dữ liệu và các hàm, thủ tục để giải các bài toán con.

Trong đó: hàm/thủ tục là một đơn vị chương trình độc lập dùng để thực hiện một phần việc nào đó như: nhập số liệu, in kết quả hoặc thực hiện một số tính toán. Hàm có thể có biến và tham số của nó.

 Ví dụ về ngôn ngữ: C, pascal, Foxpro

7-2010 Cơ sở lập trình 25 7-2010 Cơ sở lập trình 26

7-2010 Cơ sở lập trình 27 7-2010 Cơ sở lập trình 28

7

8/15/2017

Chương trình chính

Hàm_2

Hàm_1

Hàm_3

Hàm_4

Hàm_5

Hàm_6

 Ví dụ: Bài toán quản lý dãy số  Các bài toán con:  Nhập, xuất dãy  Tìm kiếm phần tử thỏa mãn điều kiện  Tính tổng các phần tử  Sắp xếp dãy số

Hàm_8

Hàm_7

Hàm_9

 Đặc điểm:

 Nhược điểm

 Tập trung vào công việc cần thực hiện (thuật toán)

 Chương trình lớn được chia thành các hàm nhỏ hơn.

 Phần lớn các hàm sử dụng dữ liệu chung

 Có hàm có thể truy cập và thay đổi dữ liệu chung  khó kiểm soát (nhất là đối với chương trình lớn, phức tạp)

 Các hàm truyền thông tin cho nhau thông qua cơ chế truyền

tham số.

 Dữ liệu trong hệ thống được chuyển động từ hàm này sang

 Nếu thay đổi cấu trúc dữ liệu dùng chung cho một số hàm thì phải thay đổi các hàm liên quan dữ liệu đó.

hàm khác.

 Mô hình được xây dựng không mô tả được đầy đủ

 Đóng gói chức năng

và trung thực các hệ thống trong thực tế.

 Chương trình được thiết kế theo cách tiếp cận từ trên

7-2010 Cơ sở lập trình 29 7-2010 Cơ sở lập trình 30

xuống (top-down)

7-2010 Cơ sở lập trình 31 7-2010 Cơ sở lập trình 32

8

8/15/2017

Vấn đề: xây dựng cấu trúc dữ liệu để thể hiện cây quan hệ: thành thạo con trỏ, cập nhập thông tin trên cây quan hệ

Mr. Định

Mrs. Hương

Mrs. Hải

Mr. Sơn

Mrs. Hà

Mr. Chiến

Yêu cầu bài toán: “Hưng và Hiếu có quan hệ như thế nào?”xây dựng giải thuật xác địnsh mối quan hệ, tên gọi các mối quan hệ ở Việt nam rất phong phú vét cạn các mối quan hệ

Miss. Linh

Mr. Hưng

Mr. Hiếu

Câu hỏi: Muốn quản lý nhiều gia đình và các gia đình có quan hệ thông gia với nhau??  cấu trúc thay đổi  thuật toán thay đổi

7-2010 Cơ sở lập trình 33 7-2010 Cơ sở lập trình 34

Con người

 Giải quyết: xem xét dưới góc độ quản lý tập các

Tên ?

đối tượng con người

Cha ?

 Thuộc tính: tên, cha, mẹ, anh em, con cái, vợ

Mẹ ?

chồng,…

Anh em ?

 Phương thức: sinh con, cưới, là anh, là ông nội,…

Con cái ?

 Tư tưởng: Phân tích bài toán thành các thực thể được gọi là các đối tượng  từ đó xây dựng các dữ liệu và các hàm (thao tác) xung quanh đối tượng đó. Trong đó: đối tượng là sự kết hợp giữa dữ liệu và hàm (phương thức) thao tác trên dữ liệu đó.

 Tạo cây quan hệ bằng các sự kiện:

Vợ chồng?

 Chiến.Cưới(Hải)

Sinh con

 Ví dụ về ngôn ngữ:  C++, Java, Smalltalk

 Hải.Sinh con(gái,Linh)

Cưới

 Hải.Sinh con(trai, Hưng)

Là anh

Là ông nội

 Không cần quan tâm tạo cấu trúc cây quan hệ mà vẫn trả lời được các câu hỏi

….

36 7-2010 Cơ sở lập trình 35 7-2010 Cơ sở lập trình

9

8/15/2017

 Đặc điểm  Đặt trọng tâm vào đối tượng, tập trung vào dữ liệu thay vì

các phương thức.

 Chương trình được chia thành các đối tượng.

 Ưu điểm  Dữ liệu và các hàm mới có thể dễ dàng bổ sung vào đối tượng khi cần thiết  dễ nâng cấp thành hệ thống lớn hơn.  Cơ chế đóng gói dữ liệu Dữ liệu được bao bọc và không cho phép các hàm ngoại lai truy cập tự do  chương trình an toàn

 Các đối tượng tác động và trao đổi thông tin cho nhau thông

qua các hàm với cơ chế thông báo.

 Mô hình được xây dựng gần với hệ thống thực tế .  Thông qua nguyên lý kế thừa  loại bỏ đoạn chương trình lặp lại khi khai báo lớp và mở rộng khả năng sử dụng các lớp  ngắn gọn, tiết kiệm thời gian

 Đóng gói chức năng và dữ liệu (không thể truy cập trực tiếp vào các thành phần dữ liệu của đối tượng mà phải thông qua các phương thức)

 Cách thiết kế đặt trọng tâm vào dữ liệuxây dựng mô hình

 Chương trình được thiết kế theo cách tiếp cận từ dưới lên

chi tiết và cài đặt dễ hơn

(bottom - up)

7-2010 Cơ sở lập trình 37 7-2010 Cơ sở lập trình 38

2.1. Các yếu tố cơ bản trong C 2.2. Cấu trúc chương trình C 2.3. Các lệnh cơ bản của C

1.5.1 Kỹ thuật thiết kế trên xuống Tư tưởng: giải quyết bài toán theo chiến lược chia để trị và tinh chỉnh từng bước 1.5.2 Kỹ thuật chương trình con Tư tưởng: một chương trình con được xây dựng một lần nhưng được sử dụng nhiều lần. 1.5.3 Kỹ thuật đệ quy Tư tưởng: chia bài toán thành các bài toán đơn giản hơn và cùng loại.

40

7-2010 Cơ sở lập trình 39 7/2010 Cơ sở lập trình

10

8/15/2017

 C sử dụng bộ kí tự ASCII, bao gồm:

 Chữ cái: A  Z, a z  Dấu gạch nối: _  Số: 0 -> 9  Các dấu phép toán số học: + - * / <> % ^  Các cặp dấu ngoặc ( ) { } [ ]  Các dấu ngăn cách: dấu cách, dấu nhảy tab, dấu xuống dòng  Các dấu khác: # $ . , : ; “ ! „ ? @

 Đặc điểm

2.1.1. Bảng chữ cái 2.1.2. Từ khóa 2.1.3. Tên gọi 2.1.4. Chú thích 2.1.5. Các kiểu dữ liệu cơ sở 2.1.6. Các đại lượng 2.1.7. Biểu thức

- Mỗi kí tự tương ứng một mã (số nguyên 0255) - 128 kí tự đầu là kí tự cố định, còn lại là kí tự mở rộng

 Lưu ý: không sử dụng các ký tự la mã và tiếng việt trong viết câu lệnh

nhưng được phép ghi chú thích

41

42

 Khái niệm: Là một dãy các ký tự đặt cạnh nhau, được dùng để định danh các đối tượng khác nhau trong chương trình như tên biến, tên hàm,…

 Quy tắc

 Khái niệm: Là một tập các từ dùng riêng cho từng ngôn ngữ lập trình. Mỗi từ khóa có một ý nghĩa và tác dụng cụ thể. Ví dụ như tên kiểu dữ liệu, tên toán tử v.v..

 Tên chỉ được chứa các chữ cái, chữ số và dấu gạch nối _

 Tên phải bắt đầu bằng chữ cái hoặc dấu gạch nối

 Không được trùng với từ khóa

 Một số từ khóa  Lưu ý

 Phân biệt giữa chữ hoa và chữ thường

 Không được đặt tên các đối tượng khác trùng tên

 Độ dài tối đa của tên mặc định là 32

với từ khóa như biến, hằng, mảng…  Từ khóa phải viết bằng chữ thường.

43

44

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

11

8/15/2017

 Khái niệm 1 kiểu dữ liệu: là một tập hợp các giá trị mà một biến thuộc kiểu đó có thể nhận được, và trên đó xác định một số phép toán.

 Mục đích: dùng để giải thích, làm rõ nghĩa cho một câu lệnh nào đó, được trình biên dịch bỏ qua khi dịch chương trình

 Phân loại

 Vị trí: Các chú thích được đặt trong cặp dấu

 Kiểu dữ liệu vô hướng: kiểu cơ sở và kiểu do

/* */ hoặc đặt sau cặp dấu //

người dùng định nghĩa

 Kiểu dữ liệu có cấu trúc: kiểu mảng(array), kiểu cấu trúc –bản ghi (struct – record), kiểu tệp (file)

 Kiểu con trỏ (pointer)

45

46

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

Tên kiểu

Kích thước

Miền giá trị

Kiểu dữ liệu

Kí tự có dấu

(signed) char

1B

-128 127

Kí tự không dấu

Unsigned char

1B

0  255

Số nguyên có dấu

int

2B

-215  215 – 1

Số nguyên không dấu

unsigned int

2B

0  216 – 1

 Đặc trưng  Tên kiểu  Miền giá trị  Vùng nhớ được cấp phát  Các phép toán

Số nguyên ngắn có dấu

short

2B

-215  215 – 1

 Các kiểu dữ liệu cơ sở

Số nguyên ngắn không dấu

unsigned short

2B

0  216 – 1

Số nguyên dài có dấu

long

4B

-231  231 – 1

Số nguyên dài không dấu

unsigned long

4B

0  232 – 1

 Kiểu kí tự  Kiểu số nguyên  Kiểu số thực

47

48

7/2010

Cơ sở lập trình 7/2010 Cơ sở lập trình

12

8/15/2017

 Các phép toán:

Kiểu dữ liệu

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

 Kiểu số nguyên:

 Phép toán số học: +, -, *, /, %

Số thực với độ chính xác đơn

float

4B

3.4e-38 -> 3.4e38

 Phép toán quan hệ: >, <,>=, <=, ….

 Phép toán logic: &&, ||, !

Số thực với độ chính xác kép

double

8B

1.7e-308 -> 1.7e308

 Phép toán với bit: &, |, ^, ~,>>, <<

Số thực dài với độ chính xác kép long double 10B

3.4e-4932->3.4e4932

 Kiểu số thực:

 Phép toán số học: +, -, *, /, %

 Phép toán quan hệ: >, <,>=, <=, ….

Lưu ý: bảng trên biểu diễn miền giá trị có giá trị dương lớn nhất và giá trị âm nhỏ nhất bằng giá trị dương lấy đối

 Lưu ý: cách viết khoa học của số thực (dấu phẩy động)

3.14 314e-2 0.314e+1

49

50

 Kiểu ký tự: sử dụng các hàm thuộc thư viện

 Hằng (constant): là đại lượng giá trị không thay đổi

trong quá trình tính toán.

 Phân loại: Hằng không có kiểu và hằng có kiểu  Khai báo hằng có tên:

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

ctype.h  toASCII(c)  tolower(c)  toupper(c)

Const = ;

 Lưu ý:

 Lưu ý: hằng kí tự được đặt trong cặp dấu „ ‟, xâu ký tự đặt trong cặp dấu “ ”

 Khi làm việc với hằng xâu kí tự ta phải dùng hằng

con trỏ

51

52

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

13

8/15/2017

 Có thể khai báo hằng bằng cách sử dụng định nghĩa

 Biến (variable): là một đại lượng có giá trị thuộc một kiểu dữ liệu nào đó và giá trị này có thể thay đổi trong thời gian tồn tại của biến

macro với từ khóa define #define

 Ví dụ:

[=];

const float pi =3.14;

 Khai báo biến  Lưu ý:

#define max 3.14

 Khai báo nhiều biến cùng kiểu trên cùng dòng lệnh.  Tên biến nên mang tính chất gợi nhớ, ngắn gọn.

 Sự khác nhau

 Ví dụ:

 Cú pháp

 Cấp phát bộ nhớ

 float z=3.14;  int x, y=8;

53

54

 Biên dịch 7/2010

 Phát biểu quy nạp

 Khái niệm: Biểu thức là sự kết hợp giữa các toán hạng và toán tử theo một các phù hợp để diễn đạt một công thức toán học nào đó.

Cơ sở lập trình 7/2010 Cơ sở lập trình

Trong đó:

 Các toán hạng có thể là hằng, biến hay lời gọi hàm hoặc

 Hằng, biến, lời gọi hàm gọi là biểu thức.  Nếu A là biểu thức, B là biểu thức, Δ là một phép toán hợp lệ giữa A và B trên ngôn ngữ C thì A Δ B là một biểu thức

là một biểu thức con nào đó.

 Chỉ những thành phần nào được kết hợp từ hai yếu tố

 Các toán tử phụ thuộc vào tập các toán tử mà ngôn ngữ

trên mới gọi là biểu thức.

hỗ trợ .

55

56 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

14

8/15/2017

 Vị trí của biểu thức: xuất hiện trong bất kì

một câu lệnh nào của C

 Giá trị biểu thức: được ước lượng và có kiểu dữ liệu phụ thuộc vào các thành phần trong biểu thức.

 Ví dụ

 Biểu thức logic trong C

 Vế phải của một câu lệnh gán : ví dụ: x = 5*a +

sqrt(y);

 Trong C không có kiểu dữ liệu logic  Sử dụng các giá trị số (1/0) hoặc giá trị con trỏ

(NULL/!=NULL) để diễn đạt các giá trị logic.

 Làm tham số thực sự của hàm: ví dụ: sqrt(y)  Làm chỉ số: ví dụ: x[++i]  Trong câu lệnh điều kiện if, for

57

58

 Khái niệm: Bao hàm tệp là các chỉ dẫn tiền xử lý để chương

trình dịch chèn file thư viện vào trong chương trình.

 Cách chỉ dẫn

#include <[path]\ file_name.*> hoặc #include “[path]\file_name.*”

 Hoạt động: Trước khi dịch, chương trình dịch sẽ tìm tệp theo tên và đường dẫn ghi trong chỉ dẫn. Nếu tìm thấy thì nội dung của tệp này được gọi ra và chèn vào tệp nguồn đang xét đúng tại vị trí chỉ dẫn include. Nếu không tìm thấy thì thông báo lỗi.

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

1. [Các bao hàm tệp] 2. [Các định nghĩa kiểu, biến, hằng] 3. [Các định nghĩa macro] //chương 4 4. [Các khai báo nguyên mẫu hàm] //chương 4 5. main ([tham số]) { // thân hàm main } 6. [Các định nghĩa hàm] Lưu ý: dấu [ ] để chỉ yếu tố có thể có hoặc không, dấu <> để chỉ yếu tố bắt buộc (đv các trình biên dịch)

 Sự khác nhau: khi không có đường dẫn <> tìm trong thư mục ngầm định trước

“ ” tìm trong thư mục hiện tại chứa tệp chương trình

59

60

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

15

8/15/2017

 Soạn thảo chương trìnhtạo tệp có phần mở

rộng của các tệp *.C, *.CPP

 Khái niệm hàm: là đoạn chương trình được viết ra một lần nhưng có thể sử dụng nhiều lần, chỉ cần gọi tên hàm và cung cấp các tham số tương ứng.

 Dịch chương trình

 Hàm main: là yếu tố bắt buộc của mỗi chương trình C, là

nơi bắt đầu thực thi (chạy) của chương trình

 Lưu ý

Tạo các tệp *.obj, *.com, *.exe Phát hiện lỗi

 Hàm phải trả lại một giá trị cho tên hàm nhưng với hàm

 Chạy chương trình và thử với các bộ dữ liệu

main(), không nhất thiết phải trả kết quả void main()

 Hàm main kiểu void không được trình biên dịch chấp nhận trong một số công cụ hỗ trợ lập trình C như Dev-cpp, MS VisualC

đặc biệt  Phát hiện lỗi

61

62

 Khái niệm  Phân loại:

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

2.3.1. Lệnh gán 2.3.2. Lệnh vào, ra dữ liệu 2.3.3. Các lệnh điều khiển rẽ nhánh 2.3.4. Các lệnh điều khiển chu trình

 Câu lệnh đơn giản: là lệnh không chứa các lệnh khác.Ví dụ: phép gán, lời gọi hàm loại void, lệnh nhảy không điều kiện goto

 Câu lệnh có cấu trúc: khối lệnh, lệnh rẽ nhánh, lệnh

lặp  Lưu ý

 Lệnh kết thúc bằng dấu ;  Khối lệnh luôn nằm trong cặp dấu { }

63

64

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

16

8/15/2017

(tên kiểu mới)(biểu thức)

 Lưu ý: Tình huống ép kiểu tường minh  Ví dụ

 Cú pháp: = ;  Ý nghĩa  Ví dụ

int x=5, y;

y=(x*x-2)/(x-1);

 Lưu ý

int x; float y; long d; x+y*d ?? Kiểu dữ liệu Int x,y; float z; z=x/y z=(float)x/y;

 Giá trị gán phải phù hợp với kiểu dữ liệu của biến.  Tình huống ép kiểu tự động từ thấp lên cao theo

quy tắc: char-> int->long->float->double

65

7/2010

 Lệnh gán mở rộng: Áp dụng đối với các

66 Cơ sở lập trình 7/2010 Cơ sở lập trình

phép toán số học và dịch bit x=x+y ↔ x+=y x=x-y ↔ x-=y

 Phép tăng giảm giá trị đi 1

 Hàm vào ra chuẩn: printf/scanf  Hàm nhập một kí tự: getch, getche,getchar  Hàm nhập một xâu: gets  Hàm in một kí tự: putch  Hàm in một xâu kí tự: puts  Thư viện: stdio.h, conio.h

i=i-1 ↔ i--; --i i=i+1 ↔ i++; ++i  Sự khác nhau a=5; b=a++; a=5; b=++a;

67

68

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

17

8/15/2017

 Chức năng: xuất dữ liệu ra thiết bị chuẩn theo định dạng

 Cú pháp: int printf(format, [values]);

 Định dạng để in theo quy cách: %[-][n][.m]

Trong đó:

Trong đó:  n, m là các số nguyên dương qui định: n là độ dài phần

thông tin in ra, m là số chữ số cho phần thập phân

 format: là một hằng xâu kí tự hoặc có cả các định dạng để in ra các kiểu dữ liệu khác nhau của các giá trị trong values.

 [-]: căn trái hay phải . Khi giá trị được in ra màn hình, nếu độ rộng thực sự nhỏ hơn độ rộng xác định bởi n, thì ngầm định là căn phải. Có dấu – là căn trái

 values là danh sách các giá trị cần in, nó có thể là giá trị của hằng, giá trị của biến, hoặc là giá trị trả về của hàm thông qua một lời gọi hàm v.v.

 ki_tu_dinh_kieu là các kí tự qui định kiểu dữ liệu sẽ được

in ra.

 Lưu ý: Các giá trị được in cách nhau bởi toán tử dấu phẩy , và có thể có nhiều hơn các đặc tả kí tự định kiểu  các giá trị cuối cùng thừa ra sẽ bị bỏ qua.

69

70

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

Kí tự định kiểu

Kiểu dữ liệu

kiểu kí tự char, có thể dùng cho kiểu short và int

c

Kiểu nguyên int, có thể dùng cho kiểu char

d

Chú ý: Kí tự điều khiển là kí tự đặc biệt, bắt đầu bằng kí tự \ tiếp theo là một kí tự dùng để điều khiển và sẽ không hiện ra màn hình.

Kiểu số nguyên không dấu (unsigned char, unsigned short)

u

ld

Long

Kí hiệu

Ý nghĩa

lu

unsigned long

X, x

Kiểu số nguyên viết dưới dạng số hexa (cơ số 16)

Ký tự xuống dòng

\n

o

Kiểu số nguyên viết dưới dạng số octal ( cơ số 8)

Ký tự nhảy tab

\t

lo

unsigned int ( cơ số 8)

i

long, int (cơ số 10, 8,16)

Ký tự xóa trái

\b

f

Kiểu số thực với phần thập phân có 6 chữ số, float, double

Tiếng kêu bíp

\a

E, e

Kiểu số thực dưới dạng kí pháp khoa học

G, g

Kiểu số thực không chứa các số 0 vô nghĩa

71

72

s

Xâu ký tự

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

18

8/15/2017

 Chức năng: Nhập (Đọc) dữ liệu từ bàn phím theo khuôn

 Ví dụ:

dạng cho biến

 Cú pháp: int scanf(format, poiter_list);

Trong đó:  format: là xâu định dạng quy cách nhập dữ liệu cho biến đối

với từng kiểu.

 poiter_list: danh sách các địa chỉ của biến hoặc là các con

trỏ cần nhập dữ liệu.

 Lưu ý:

Const float pi=3.14; int x=6; int y; y=x*pi*pi; printf(“gia tri cua x la:”); printf(“%d”,x); printf(“gia tri cua x là:%d\n”,x); printf(“gia tri cua x=%5d, cua y=%8.3f ”,x,y); printf(“Day la vi du ham printf co xoa ki tu traii:\b\b

73

74

”); 7/2010

 Sự tương ứng về kiểu dữ liệu giữa định dạng và đối số  Quy cách đọc dữ liệu kiểu số  Quy cách đọc dữ liệu kiểu xâu ký tự (đúng số ký tự) 7/2010

 Chức năng: là một vùng của bộ nhớ để lưu trữ dữ liệu do

người dùng gõ vào từ bàn phím để chờ xử lý

 Ví dụ 1: Int a,b; scanf(“%d%d”,&a,&b); //nhập 5 8 scanf(“%3d%3d”,&a,&b); // nhập 21 4159

 Ví dụ 2:

Int n; char c; scanf(“%c%d”,&c,&n); //nhập a 12 scanf(“%d%c”,&n,&c); //nhập 12 a

 Hoạt động: Sử dụng một con trỏ để xác định kí tự chuẩn bị được xử lý. Máy tính sẽ đọc lần lượt các ký tự từ bộ nhớ đệm. Mỗi lần đọc xong một ký tự con trỏ tự động nhảy sang vị trí kí tự tiếp theo để chờ xử lý tiếp.  Hiện tượng đọc nhầm dữ liệu:  Ví dụ: int x,y; int n; char c; scanf(“%d%d”,&x,&y); //nhập 7 13 scanf(“%d%c”,&n,&c); //nhập 12 a

 Xử lý: Làm sạch vùng đệm khi nhập dữ liệu cho các biến với

75

76

câu lệnh: fflush(stdin); 7/2010

Cơ sở lập trình Cơ sở lập trình

Cơ sở lập trình 7/2010 Cơ sở lập trình

19

8/15/2017

 Chức năng: nhập dữ liệu từ bàn phím cho biến xâu

 Cú pháp

ký tự.

 int puts(char *s)  int putch(int ch)

 Hoạt động: Hàm đọc 1 xâu kí tự cho đến khi gõ Enter, sau đó bổ sung mã kết thúc xâu kí tự \0 vào cuối xâu.

 Chức năng

 Ví dụ

 Hàm putch có chức năng in ra màn hình một ký

tự tại vị trí con trỏ đang đứng.

 Hàm puts in xâu ký tự ra màn hình tại vị trí hiện tại của con trỏ sau đó tự động chuyển con trỏ sang dòng mới.

char str[20]; printf(“nhập xâu:”); gets(str); scanf(“%s”,str); // nhập “chao cac ban!”  Hiện tượng trôi dữ liệu

77

78 7/2010 Cơ sở lập trình Cơ sở lập trình

7/2010

 Cú pháp

 If … else  Switch … case

 Int getch()  Int getche()

 Chức năng

 Đợi người dùng nhập vào một ký tự từ bàn phím. Hàm getche sẽ hiển thị ký tự đó lên hàm hình còn hàm getch thì không

80

79 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

20

8/15/2017

 Ví dụ: Viết chương trình nhập giá trị của biến

 Chức năng: cho phép tùy chọn công việc thực

x và tính giá trị của hàm f(x) biết

hiện tùy theo điều kiện

x*x-1 nếu x≠1

 Cú pháp

F(x) =

x+1 ngược lại

if <điều kiện> { // khối lệnh1 } else { // khối lệnh 2 }

 Hoạt động: Nếu điều kiện là đúng thì thực hiện khối lệnh 1. Nếu điều kiện là sai thì thực hiện khối lệnh 2.

81

82

 Cú pháp

 Lưu ý

E1 ? E2 : E3 Trong đó: E1, E2, E3 là các biểu thức.

 Hoạt động: Biểu thức E1 sẽ được tính toán,

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

nếu E1 ≠ 0 thì nó sẽ nhận giá trị của biểu thức E2 và ngược lại sẽ nhận giá trị của biểu thức E3.

 Cấu trúc khuyết của if … else  Cú pháp if (biểu thức điều kiện) { // khối lệnh }  Sử dụng cặp dấu { } với câu lệnh đơn và khối lệnh  Ngôn ngữ C cho phép có nhiều câu lệnh if…else

 Ý nghĩa: là một dạng biểu diễn của câu if đặc biệt. Biểu thức điều kiện hoạt động như một biểu thức bất kỳ.

lồng nhau  nguyên tắc hoạt động của else  Ví dụ: Viết chương trình giải pt bậc 1/bậc 2.

83

84

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

21

8/15/2017

 Chức năng: cho phép lựa chọn một nhánh trong nhiều khả

năng tuỳ thuộc vào giá trị của một biểu thức.

 Ví dụ 1: Tìm giá trị max, min của hai số a và b.

 Cú pháp

(a>b) ? a:b Max = (a>b) ? a:b; Min = (a>b) ? b:a; printf(“gia tri min là: %6.3f”, (a>b) ? b:a);

switch(bieu_thuc) { case n1: khối lệnh 1; break; ….. case nk: khối lệnh k; break; [ default: khối lệnh mặc định ] }

85

 Sự hoạt động

7/2010 Cơ sở lập trình

Trong đó:  bieu_thuc là một biểu thức nhận giá trị kiểu

nguyên

 n1, n2… nk: là số nguyên, hằng ký tự hoặc biểu thức hằng khác nhau từng đôi.

 Xác định giá trị của biểu thức.  So sánh giá trị đó với các ni  Nếu giá trị của biểu thức bằng giá trị của ni nào thì khối lệnh sau nó được thực hiện và kết thúc câu lệnh

 Nếu giá trị của biểu thức khác với tất cả ni thì:

▪ Nếu có default thì khối lệnh đứng sau nó được thực hiện ▪ Nếu không có từ khóa default thì chương trình dịch thoát

 default, switch, case: từ khóa  break: cho phép ra khỏi câu lệnh switch và các lệnh lặp mà không cần điều kiện kết thúc chu trình

khỏi câu lệnh switch.

88

87 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

22

8/15/2017

 Lưu ý

 Ví dụ 1: Viết chương trình tìm học lực khi

biết điểm tổng kết biết

 Nếu không có từ khóa break sau mỗi khối lệnh chương trình sẽ thực hiện khối lệnh rồi đi tiếp xuống nhánh case tiếp theo.

 Cấu trúc đặc biệt: Có thể có nhiều giá trị case cho

cùng một trường hợp.

 Câu lệnh switch có thể lồng nhau hoặc lồng với

DTK = 9.0 xuat sac DTK = 8.0 gioi HL= kha nếu DTK = 7.0 trung bình yeu

DTK =6.0, 5.0 còn lại

các câu lệnh khác.

89

90

 while  do … while  for

 Ví dụ 2: viết chương trình nhập vào một tháng trong năm và in ra mùa của tháng đó.  Ví dụ 3: viết chương trình nhập một biểu thức đơn giản a ∆ b với a, b là các số nguyên dương còn ∆ là một trong các toán tử số học +,-,*,/, %. In ra kết quả của biểu thức tương ứng với từng toán tử. Khác với các toán tử này in ra thông báo toán tử không hợp lệ.

91

92

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

23

8/15/2017

 Chức năng: for là cấu trúc lặp trong đó một khối lệnh sẽ được

 Sự hoạt động:

thực hiện lặp đi lặp lại với số lần lặp được xác định.

 Cú pháp:

for ([khởi_tạo];[điều_kiện];[thay_đổi]) { // khối lệnh } Trong đó:

 khởi_tạo: có thể là biểu thức hoặc khai báo, dùng để khởi

tạo giá trị cho các biến điều khiển của vòng lặp

 điều_kiện: là một biểu thức logic, dùng để quyết định tiếp

 Bước 1: Xác định giá trị biểu thức khởi_tạo  Bước 2: Xác định giá trị của biểu thức điều_kiện.  Bước 3: Nếu biểu thức điều_kiện có giá trị là sai thì trình biên dịch sẽ thoát khỏi cấu trúc lặp for. Nếu biểu thức điều_kiện có giá trị đúng (khác 0) thì khối lệnh sẽ được thực hiện và trình biên dịch sẽ chuyển sang bước 4.

tục hay dừng việc thực hiện khối lệnh.

 Bước 4: Xác định giá trị của biểu thức thay_đổi và

 thay_đổi: thường là một biểu thức gán dùng để thay đổi

quay trở lại bước 2.

( tăng hoặc giảm ) giá trị của các biến điều khiển.

93

94

 Lưu ý:

 Nhận xét

 Cả ba biểu thức trong cấu trúc for có thể vắng mặt nhưng

bắt buộc vẫn phải để dấu ;.

 Nếu biểu thức điều_kiện bị khuyết thì nó luôn được xem là

đúng.

 Biểu thức khởi_tạo chỉ được thực hiện một lần, còn các biểu thức điều_kiện, thay_đổi và khối lệnh có thể được thực hiện lặp lại nhiểu lần.

 Có thể khối lệnh không bao giờ được thực

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

hiện.

 Mỗi phần khởi_tạo,điều_kiện,thay_đổi có thể là một dãy các biểu thức cách nhau bởi dấu phẩy. Khi đó các biểu thức trong mỗi phần sẽ được xác định từ trái sang phải. Tính đúng sai của điều_kiện được xác định bởi tính đúng sai của biểu thức cuối cùng trong dãy này.

 Cấu trúc for có thể sử dụng lồng nhau. Và khi gặp câu lệnh break trong khối lệnh của for, máy sẽ thoát khỏi vòng lặp for sâu nhất chứa câu lệnh này.

95

96

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

24

8/15/2017

 Ví dụ 1: Viết chương trình nhập vào số

 Chức năng: Thực hiện lặp đi lặp lại một khối

nguyên dương và tính n!

lệnh khi điều kiện lặp vẫn còn thỏa mãn.

 Ví dụ 2: viết chương trình nhập vào một số nguyên n. Kiểm tra xem số đó có phải là số nguyên tố hay không.

 Cú pháp while (điều_kiện) { // khối lệnh }

Trong đó:

 điều_kiện là là một biểu thức nhận giá trị nguyên

hoặc thực

 while là từ khóa

97

98

 Chú ý

 Sự hoạt động

 Bước 1: Tính giá trị của biểu thức điều_kiện  Bước 2: Nếu biểu thức điều_kiện có giá trị sai thì trình biên dịch sẽ thoát khỏi cấu trúc while. Nếu biểu thức điều kiện có giá trị đúng thì khối lệnh sẽ được thực hiện và quay trở lại bước 1.

 Biểu thức điều_kiện có thể là một dãy các biểu thức đặt cách nhau bởi dấu phẩy. Giá trị của điều_kiện là giá trị của biểu thức cuối cùng trong dãy.  Tránh lỗi đặt dấu ; sau biểu thức dieu_kien  Sử dụng câu lệnh break để tránh tình huống vòng

lặp không dừng.

 Nhận xét

 Khối lệnh của while có thể không được thực hiện

lần nào.

 Các câu lệnh while có thể lồng nhau hoặc lồng các các câu lệnh lặp khác. Khi gặp lệnh break, máy sẽ ra khỏi câu lệnh while sâu nhất chứa lệnh này

99

100

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

25

8/15/2017

 Ví dụ 1: Tính tổng các số nhập vào từ bàn

phím khi tổng còn <100.

 Chức năng: do … while là cấu trúc lặp trong đó một khối lệnh sẽ được thực hiện đi thực hiện lại khi điều kiện lặp vẫn còn thỏa mãn.

 Cú pháp do

 Ví dụ 2: Xây dựng chương trình thể hiện thuật toán Euclid để tìm UCLN của 2 số nguyên a và b.

{ // khối lệnh }

 Ví dụ 3: Viết chương trình nhập vào số

nguyên dương và tính n!

while(dieu_kien); Trong đó:

 do và while là hai từ khóa

 dieu_kien là biểu thức điều kiện nhận giá trị nguyên hoặc thực

101

102

 Sự hoạt động

 Ví dụ 1: Viết chương trình đọc một số cho đến khi

 Bước 1: Thực hiện khối lệnh

số đó là số dương.

 Bước 2: Xác định giá trị của biểu thức

 Bước 3: Nếu biểu thức có giá trị đúng thì trình biên dịch sẽ quay lại bước 2. Nếu biểu thức có giá trị sai thì trình biên dịch sẽ thoát khỏi cấu trúc lặp do while.

 Ví dụ2: Viết chương trình cho phép người dùng nhập một kí tự từ bàn phím in ra mã của kí tự cho đến khi người dùng nhập phím Enter để thoát.

 So sánh với cấu trúc while

 Ví dụ 3: Viết chương trình nhập vào số nguyên

 Khối lệnh sẽ được thực hiện trước khi xác định giá trị của biểu thức, vì vậy khối lệnh luôn được thực hiện ít nhất là một lần.

dương và tính n!

 Chú ý: tương tự cấu trúc while

103

104

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

26

8/15/2017

3.1. Mảng và xâu 3.2. Con trỏ

 Đều là câu lệnh lặp nhưng cấu trúc for có số lần lặp xác định và bước nhảy rõ ràng, while và do … while không xác định số lần lặp

 Cấu trúc for và while: điều kiện được kiểm tra trước khối lệnh có thể không được thực hiện lần nào. Cấu trúc do … while: điều kiện được kiểm tra sau  khối lệnh luôn được thực hiện ít nhất một lần

105

 Đặt vấn đề: Bài toán quản lý dãy số với n biến

 3.1.1. Mảng  3.1.2. Xâu

106 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

đơn

 Khái niệm: mảng là một dãy các phần tử có cùng kiểu dữ liệu được đặt liên tiếp trong bộ nhớ và có thể truy xuất đến từng phần tử thông qua chỉ số mảng.  Các yếu tố của mảng

▪ Kiểu mảng ▪ Tên mảng ▪ Số phần tử/kích thước của mảng

107 108 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

27

8/15/2017

 Ví dụ

 Khai báo mảng

[size1][[size2][…[sizeN]]];

 int a[10];  float arr[2][3];

Trong đó:

 Chú ý

 Mảng chỉ thực sự làm việc tốt với mảng tối đa 3

chiều

 type là các kiểu dữ liệu cơ sở/ cấu trúc  name: là tên được đặt cho mảng  Size1, size2,.., sizeN là các số nguyên qui định kích cỡ của mảng hoặc số phần tử của mảng.  Số lượng thành phần [ ] được đặt sau tên mảng

 Trường size1,...sizeN phải là một giá trị hằng khi khai báo (vì mảng là một khối nhớ tĩnh có kích cỡ xác định)

sẽ qui định chiều của mảng đó.

 Ví dụ

Cơ sở lập trình

 int n,m;  int a[n][m]; 7/2010

 Với mảng 2chiều

 Khởi tạo mảng

[size1][size2] ={

{a11,a12,a13,...},

 Đối tượng áp dụng: Biến toàn cục  Cách thức: tự động hoặc có thể gán giá trị khởi tạo

{a21,a22,a23,... },

cho các phần tử của mảng

 Với mảng 1chiều

[size]={v1,v2,v3,..,vk}; //( k<=N) Hoặc [ ]={v1,v2,v3,..,vk};

 Ví dụ

109 110 7/2010 Cơ sở lập trình

char a[5] = { 0, 1, 4, 3, 2 };

};  Ví dụ: int a[][4]={ {0},{1,3,5}, {2,4,6,8} }  Cách khởi tạo khác [size1][size2] ={v1,v2,..,vK}; (k<=size1*size2)  Ví dụ: int a[3][2]={1,2,3,4,5,6};

111 112 7/2010 Cơ sở lập trình Cơ sở lập trình 7/2010

28

8/15/2017

name[chỉ_số]

 Cách truy xuất phần tử trong mảng

 Làm việc với các phần tử của mảng: dùng câu lệnh for để duyệt các phần tử của mảng với biến điều khiển chạy theo chỉ số của mảng.

 Vai trò: mỗi phần tử làm việc như một biến đơn lẻ  Ví dụ

 Ví dụ: Làm việc với dãy số

int a[5]; a[2]=8;

 Lưu ý

▪ Trong ngôn ngữ C các phần tử của mảng được đánh số

bắt đầu từ 0

▪ Truy xuất phần tử ngoài phạm vi: không bị báo lỗi nhưng

giá trị của phần tử đó sẽ không kiểm soát được.

▪ Tên của mảng tương ứng với địa chỉ phần tử đầu tiên của

 Nhập dãy số  In dãy số  Đếm số phần tử chia hết cho 5.  Tính tổng các phần tử chẵn.  Sắp xếp dãy

nó.

▪ Truy xuất đối với mảng hai chiều

 Khái niệm: Con trỏ là một kiểu dữ liệu trong đó miền

giá trị là địa chỉ các vùng nhớ .

 Khai báo:

113 7/2010 Cơ sở lập trình

3.2.1 Khái quát về con trỏ 3.2.2 Các phép toán trên con trỏ 3.2.3 Con trỏ và mảng

*;

Trong đó:  Trong đó Type là kiểu dữ liệu của vùng nhớ được trỏ

tới

 Mỗi kiểu địa chỉ có một kiểu con trỏ tương ứng.  Sau khi khai báo nhưng chưa được chỉ định trỏ vào

đâu thì con trỏ mang giá trị NULL

115 116 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

29

8/15/2017

 Ví dụ

 Sử dụng: phân biệt giá trị và địa chỉ của con

int *number; char *character; float *greatnumber;

 Lưu ý

trỏ  Ví dụ Int *p; p chứa địa chỉ các vùng nhớ *p chứa giá trị trong các vùng nhớ mà nó trỏ đến

 Nhập giá trị cho các biến trỏ

 Chiếm một lượng bộ nhớ như nhau (kích thước của một biến con trỏ tùy thuộc vào hệ điều hành)  Nhưng dữ liệu mà chúng trỏ tới không cùng kích

thước bộ nhớ.

 C1: sử dụng phép gán hoặc khởi tạo ban đầu  C2: sử dụng các hàm cấp phát động

 Khởi tạo con trỏ: để chỉ định rõ ràng con trỏ

117 118 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

sẽ trỏ tới biến nào khi khai báo

 Ví dụ

int cat;

 Cấp phát bộ nhớ cho con trỏ  Thư viện: alloc.h  Hàm cấp phát: malloc/ calloc/realloc  Cú pháp

= <(type*)>malloc(size);// dùng cho các kiểu dl cơ

int *tommy = &cat; Tương đương với:

sở

int cat;

= <(type*)>calloc(n,sizeof (type));//dùng cho

kiểu dl người dùng định nghĩa

int *tommy; tommy = &cat;

= <(type*)>realloc(buf_ptr,newsize);//cấp phát

lại 7/2010

119 120 7/2010 Cơ sở lập trình Cơ sở lập trình

30

8/15/2017

 Phép so sánh  Phép cộng con trỏ với số nguyên  Phép trừ hai con trỏ

 Ví dụ: so sánh int *ptr; ptr = (int *) malloc(sizeof(int)); int x = 5; *ptr = x;

int *ptr; int x = 5; ptr = &x;

 Lưu ý: khi gán con trỏ chúng ta phải luôn luôn gán địa chỉ mà nó trỏ tới chứ không phải là giá trị mà nó trỏ tới. 7/2010

 Giống nhau: Tên của một mảng/con trỏ tương đương

 Phép so sánh: là phép so sánh địa chỉ mà con

với địa chỉ phần tử đầu tiên

121 122 Cơ sở lập trình 7/2010 Cơ sở lập trình

trỏ lưu giữ

 Phép cộng con trỏ với số nguyên

 Khác nhau: địa chỉ của mảng cố định (con trỏ hằng) còn vùng nhớ con trỏ trỏ tới có thể thay đổi (con trỏ thường).

 Ví dụ

 Ptr là con trỏ kiểu T, k là số nguyên thì (Ptr+k) là con trỏ kiểu T. Ptr trỏ tới phần tử t thì (Ptr+k) trỏ tới phần tử cách t một khoảng là k ( k<0 về miền địa chỉ lớn hơn và k<0 về miền địa chỉ nhỏ hơn)

 Phép trừ

int numbers [20], *p; p = numbers; //hợp lệ numbers = p; //không hợp lệ

 p, q là hai con trỏ kiểu T thì p-q là số nguyên chỉ số phần tử kiểu T nằm giữa hai phần tử do p và q trỏ tới.

123 124 Cơ sở lập trình 7/2010 7/2010 Cơ sở lập trình

31

8/15/2017

 Mối liên hệ

3.3.1 Khái niệm 3.3.2 Một số hàm xử lý xâu

 Các phần tử của mảng có thể được truy xuất

thông qua chỉ số hoặc con trỏ. (a+i) &a[i], *(a+i)  a[i]

 Ví dụ: a[5] = 0; hoặc *(a+5) = 0;  Với mảng 2chiều a là con trỏ trỏ tới a[0] và a[0] trỏ tới a[0][0] a[0]  &a[0][0] và * a[0]  a[0][0] hay **a 

a[0][0]

(a+i )  &a[i] và a[i] &a[i][0] *a[i] a[i][0] hay *(*a+i)  a[i][0] a[i]+j  &a[i][j] *( a[i]+j)  a[i][j] hay *(*a +i+j)  a[i][j]

 Khai báo xâu

 Khái niệm

 Dùng mảng kí tự: char a[size];  Dùng con trỏ kí tự: char *str;

 Khởi tạo xâu

 Dùng mảng hoặc con trỏ

 Ví dụ

 Xâu là một mảng các kí tự kể cả khoảng trắng.  Một hằng xâu có nội dung được đặt trong cặp dấu “ ” và kết thúc xâu là kí tự „\0‟ hay còn gọi là kí tự NULL  Lưu ý

 char a[15] = “hello world”;

 Kí tự „a‟ khác với xâu “a”.

 hoặc

 char *str = (char*) malloc (15*sizeof (char));  char *str=”hello world”;

125 126 Cơ sở lập trình 7/2010 Cơ sở lập trình 7/2010

127 128 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

32

8/15/2017

 Nhập dữ liệu cho xâu

Cách 1: khởi tạo giá trị mặc định: char *str=”hello world”; Cách 2: Dùng hàm scanf: char *s = (char*) malloc (9*sizeof (char));

char *s = (char*) malloc (9*sizeof (char)); for( i =0; i< 9; i++) { fflush(stdin) ; scanf(“%c”, s+i); }  Nhận xét

 Dài dòng và phức tạp  hạn chế sử dụng hàm

scanf để nhập dữ liệu cho xâu

for( i =0; i< 9; i++) scanf(“%c”, s+i);  Lưu ý: cơ chế làm việc của vùng nhớ đệm có thể nhận được kết quả không theo mong muốn cần làm sạch vùng đệm

 Xuất xâu ra màn hình

 Dùng hàm printf hoặc puts int puts(const char *);

 Sự khác nhau: puts in xong thì con trỏ tự động

nhảy xuống dòng

129 130 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

Cách 3: dùng hàm gets  Cú pháp char * gets(char *str);  Hoạt động

 Ví dụ

char hello[] = "Hello World"; printf("\nChuoi in ra = %s", hello);

puts(hello);

 cho phép nhập vào một dãy kí tự cho đến khi gặp kí hiệu „\n‟(Enter). Kí tự „\n‟ sẽ không được đặt vào chuỗi str, trình biên dịch sẽ thêm vào cuối str là kí tự „\0‟

131 132 Cơ sở lập trình 7/2010 7/2010 Cơ sở lập trình

 Lưu ý: sau khi nhập xâu sẽ để lại kí tự „\n‟ trên dòng nhập  làm sạch vùng đệm trước khi gọi hàm: fflush(stdin);

33

8/15/2017

 Ví dụ: Viết chương trình tìm độ dài của xâu.

 Một số hàm xử lý xâu

 strlen  strchr  strstr  toupper  tolower

 Yêu cầu: viết chương trình để thể hiện các

hàm trên

133 134 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

4.1 Hàm 4.2 Truyền tham số cho hàm

4.1.1 Giới thiệu 4.1.2 Cấu trúc tổng quát của hàm 4.1.3 Nguyên tắc hoạt động của hàm 4.1.4 Sử dụng giá trị trả về của hàm

135 136 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

34

8/15/2017

 Mục đích:Phân rã bài toán thành các bài toán con  Chương trình được tổ chức thành các chương trình con.

 Khái niệm: Hàm là một đơn vị chương trình độc lập dùng để thực hiện một phần việc nào đó

 Ưu điểm

 Ví dụ: hàm để nhập số liệu, in kết quả hay

 Có thể sử dụng lại hàm, tiết kiệm dòng lệnh

thực hiện một số tính toán.

 Chương trình logic, gọn gàng

 Linh động sử dụng hàm qua lời gọi hàm

 Phân chia công việc và ghép kết quả lại  tăng tốc giải bài

toán.

 Đặc điểm của hàm trong C

 Khai báo nguyên mẫu hàm(prototype)  Ý nghĩa: Khai báo sự tồn tại của hàm  Cú pháp:

([ [p1], [p2],…]);

 Trong đó:

 Cho phép một chương trình có thể có nhiều hàm.  Không cho phép trong một hàm định nghĩa một hàm khác nhưng cho phép trong một hàm có thể có nhiều lời gọi hàm đến các hàm khác đã được định nghĩa.

 Các yếu tố của hàm

 type: kiểu giá trị trả về của hàm  name: tên của hàm  type1, type2, …: là các kiểu của các đối số/tham số.  p1,p2, … là tên các đối số

 Khai báo nguyên mẫu hàm (prototype)  Định nghĩa hàm (declaration)  Lời gọi hàm (call).

137 138 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

139 140 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

35

8/15/2017

 Ví dụ

 Vị trí nguyên mẫu hàm: được đặt ở đầu

chương trình, sau chỉ dẫn tiền xử lý

Ví dụ1: Xây dựng hàm tính n! long gthua(int n); Ví dụ 2: Xây dựng hàm tính tổ hợp chập k của n

 Lưu ý: khi khai báo nguyên mẫu hàm, trình biên dịch chỉ quan tâm đến kiểu hàm, tên hàm, kiểu và thứ tự kiểu của đối số  không cần đặt tên của các đối số.

dựa vào công thức tính int tohop(int n, int k);

 Vị trí định nghĩa hàm: sau thân chương trình chính  Lưu ý:

 Định nghĩa hàm  Ý nghĩa: Khai báo các thao tác theo trình tự

141 7/2010 Cơ sở lập trình 142 7/2010 Cơ sở lập trình

cần thực hiện của hàm

 Cú pháp:

 Phải viết đúng kiểu, đúng tên, đúng thứ tự và tên các kiểu các đối số ở trong cặp ( ) tương ứng với trong khai báo nguyên mẫu.

 Bắt buộc phải có tên đối số trong danh sách các đối

số của hàm.

([ [p1], [p2],…]) { // thân hàm return (giá trị); }

 Ngôn ngữ C cho phép một cách viết khác gộp chung khai báo nguyên mẫu hàm và định nghĩa hàm

143 144 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

36

8/15/2017

 Ví dụ 1: Xây dựng hàm tính n!

 Ví dụ2: Xây dựng hàm tính tổ hợp chập k của n.

int tohop(int n, int k) { int th; th=gthua(n)/(gthua(k)*gthua(n-k)); return th; }

long gthua(int n) { long gt=1; for (int i=2;i<=n;i++) gt=gt*i; return gt; } 7/2010

 Ý nghĩa: trả về giá trị cho hàm  Cú pháp:

return (giá trị);

 Loại hàm: các hàm có kiểu khác void  Vị trí: Thông thường được đặt ở dòng lệnh

145 146 Cơ sở lập trình 7/2010 Cơ sở lập trình

cuối cùng của thân hàm

Ví dụ 1: tính n! long gthua(int n) { long gt=1; for (int i=2;i<=n;i++) gt=gt*i; return gt; }

 Lưu ý: Một hàm có thể xuất hiện nhiều câu lệnh return

147 148 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

37

8/15/2017

 Ví dụ2: Kiểm tra 1 số nguyên dương có phải

 Quá trình thực hiện khi gặp lời gọi hàm

 Cấp phát bộ nhớ cho các đối và các biến

cục bộ

 Gán giá trị của tham số thực cho các đối

là số nguyên tố không int ktnto(int n) {

if (n==1 || n==2) return 1;

tương ứng

for (int i=2;i

if (n%i==0) return 0;

return 1;

 Thực hiện các câu lệnh trong thân hàm  Khi gặp câu lệnh return hoặc dấu } cuối cùng của thân hàm thì máy sẽ xóa các đối, các biến cục bộ và rời khỏi hàm

else { }

} 7/2010

 Lưu ý:

 Vị trí xuất hiện: lời gọi hàm  Ý nghĩa: Giá trị trả về của hàm là một giá trị cụ thể có

kiểu như đã được khai báo

 Vai trò: Có thể sử dụng như một giá trị hằng trong

 Đối và biến cục bộ của hàm cần có tên khác nhau  Không thể mang giá trị của đối ra khỏi hàm  Không thể dùng đối để thay đổi giá trị của các đại

lượng bên ngoài hàm.

phép gán, các phép toán số học, các câu lệnh nhập xuất.  Ví dụ

 Các đối số có thể bị biến đổi trong thân hàm nhưng các tham số thực không bị thay đổi (các đối chỉ là bản sao của tham số thực)

printf(“giá trị giai thừa là: %ld”,gthua(n)); th=gthua(n)/(gthua(k)*gthua(n-k));

149 150 Cơ sở lập trình 7/2010 Cơ sở lập trình

151 152 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

38

8/15/2017

 Lưu ý: Nếu hàm không có giá trị trả về lời

gọi hàm sẽ đứng đơn lẻ như một lệnh;

4.2.1 Biến toàn cục và biến địa phương 4.2.2 Tham số hình thức của hàm 4.2.3 Truyền tham số

 Ví dụ:

void nhap(int a[],int n) {

for (int i=0;i

} int x[10], d; nhap(x,d);

 Ý nghĩa: loại biến sẽ quyết định vòng đời và

153 154 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

phạm vi hoạt động của nó.

 Biến cục bộ (địa phương): là biến có phạm vi hoạt động trong một hàm hoặc một khối lệnh  Vị trí : tham số của hàm hoặc biến được khai

 Biến toàn cục: là biến có phạm vi hoạt động

báo trong thân hàm.

toàn chương trình

 Vòng đời: từ vị trí nó được khai báo đến hết

 Vị trí: được khai báo ngoài mọi hàm, dưới khai

phạm vi. (khối lệnh/ hàm)

báo tiền xử lý.

 Lưu ý:

 Nên sử dụng biến cục bộ để giảm không gian lưu

 Vòng đời: từ vị trí của nó được khai báo cho

trữ và dễ kiểm soát

tới hết chương trình.

 Tất cả các biến được khai báo trong thân của các

hàm đều là biến cục bộ (bao gồm hàm main)

155 156 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

39

8/15/2017

 Tham số hình thức của hàm: là các tham số

được viết trong định nghĩa hàm

 Yêu cầu:

int y = 5; //biến cục bộ printf("%d", test()) ;

int x=1; // biến toàn cục int test (); int main(int argc, char *argv[]) { printf("%d",y);

 Các tham số phải có cả kiểu và tên  Kiểu, thứ tự và số lượng tham số truyền vào phải chính xác như khai báo nguyên mẫu, tên của tham số có thể khác.

getch();

return 0;

 Tham số có thể có giá trị mặc đinh, những tham số

này phải viết dồn về bên phải nhất.

157 158

Ví dụ: #include #include } int test () { 7/2010

return x *2; } Cơ sở lập trình

 Ví dụ

 Phân loại:

void nhap(int a[],int n=10) {

 Tham số vào: chứa giá trị đã biết  Tham số ra: chứa các kết quả mới nhận được.

 Lưu ý:

for (int i=0;i

 Có tham số đóng vai trò cả tham số vào và cả

}

tham số ra.

 Ví dụ:

7/2010 Cơ sở lập trình

159 160 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

40

8/15/2017

 Tham số thực sự: là tham số được viết trong lời gọi

hàm

 Vị trí lời gọi hàm: Lời gọi hàm được thực hiện bên trong một thân hàm bất kì nào đó miễn là nó đã được khai báo nguyên mẫu.

 Yêu cầu

 Số lượng tham số  Kiểu giá trị của các tham số.

 Ý nghĩa: sử dụng hàm với tham số cụ thể  Cú pháp lời gọi hàm: [v =]([]); Trong đó:

 Giá trị của tham số:

 Biến, hằng, một lời gọi hàm khác

 v: là tên một biến nào đó được gán giá trị của hàm  name: tên hàm  real-pars: danh sách tham số thực sự

 Ví dụ:

Gthua(5); Nhap(x,d); Nhap(x);//tham số có giá trị mặc định

 Vấn đề: giá trị của tham số thực không thay đổi sau

khi thực hiện hàm???

 Ví dụ: kết quả ?? #include #include void swap_func ( int x, int y) // Ham hoan vi ban 1 { int temp; temp = x; x = y ; y = temp; } void main () { int x,y; printf(“\n Nhap vao hai so x,y: ”); scanf (“%d %d”,&x,&y); swap_function(x,y) ; printf(“\n Hai so sau khi hoan vi: %d %d”,x,y ); }

161 162 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

163 164 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

41

8/15/2017

 Vấn đề

 Khi nào sử dụng con trỏ làm tham số hình

int temp ; temp = *x;

thức?

*x = *y ; *y = temp;

 Nếu tham số hình thức là con trỏ thì tham số thực sự tương ứng có giá trị và kiểu như thế nào?

printf(“\n Nhap vao hai so x,y: ”); scanf (“%d %d”,&x,&y);

Giải pháp: sử dụng con trỏ làm tham số hình thức void swap_func ( int *x, int *y) // Ham hoan vi ban 2 { } void main () int x,y; { swap_function(&x,&y) ; printf(“\n Hai so sau khi hoan vi: %d %d”,x,y ); }

165 166 7/2010 Cơ sở lập trình 7/2010 Cơ sở lập trình

5.1 Khái niệm kiểu dữ liệu có cấu trúc 5.2 Khai báo và truy nhập vào phần tử struct 5.3 Mảng cấu trúc 5.4 Dữ liệu kiểu enum và kiểu typedef (tự học) 5.5 Kiểu dữ liệu file

 Khái niệm: Kiểu dữ liệu có cấu trúc là kiểu dữ liệu mà các phần tử dữ liệu của nó thuộc kiểu dữ liệu đơn giản và được tổ chức theo một quy tắc nhất định. Hay kiểu dữ liệu có cấu trúc là kiểu dữ liệu mà các giá trị của nó là sự kết hợp của các giá trị thuộc kiểu dữ liệu đơn giản.

 Các kiểu dữ liệu có cấu trúc: kiểu mảng, kiểu bản ghi, kiểu tập hợp và kiểu tệp tin

167

168

Cơ sở lập trình Cơ sở lập trình

42

8/15/2017

 Cú pháp: 2 cách

5.2.1 Khai báo kiểu struct 5.2.2 Truy nhập vào phần tử struct

struct TypeName { // Khai báo các thành phần };

typedef struct { //khai báo các thành phần } TypeName;

Trong đó:  struct là từ khóa  TypeName: do người dùng đặt theo quy tắc đặt tên  Các thành phần: có thể là biến, mảng, hợp hoặc một cấu trúc

khác mà kiểu của nó đã định nghĩa từ trước

170

169

 Ví dụ

struct dia_chi { int so_nha; char phuong[20]; char quan[15]; char thanh_pho[15]; };

typedef struct { int so_nha; char phuong[20]; char quan[15]; char thanh_pho[15]; }dia_chi;

struct date { unsigned char ngay; unsigned char thang; unsigned char nam; };

typedef struct { unsigned char ngay; unsigned char thang; unsigned char nam; } date;

171

172

Cơ sở lập trình Cơ sở lập trình

Cơ sở lập trình Cơ sở lập trình

43

8/15/2017

 Khai báo biến kiểu struct  Cách 1

struct TypeName VarName;

Trong đó:

 TypeName: là tên kiểu struct  VarName: là tên biến struct

 Nhận xét: với cách khai báo này thì các biến

struct sinh_vien { char ho_ten[30]; date ngay_sinh; char maSV[10]; };

typedef struct { char ho_ten[30]; date ngay_sinh; char maSV[10]; } sinh_vien;

sẽ được cấp phát đầy đủ cho tất cả các thành phần của nó.

173

174

 Ví dụ

 Khai báo biến kiểu struct  Cách 2: định nghĩa kiểu kết hợp với khai báo biến

struct TypeName {

// Khai báo các thành phần

struct date ngay_sinh,ngay_nhap_hoc; struct dia_chi A, B; struct sinh_vien X, Y;

}danh_sach_ten_bien;

 Nhận xét: với cách khai báo này ta có thể không cần tên kiểu cấu trúc nhưng nếu khai báo thêm biến thì sẽ thành kiểu dữ liệu khác. struct {

// Khai báo các thành phần

}danh_sach_ten_bien;

175

176

Cơ sở lập trình Cơ sở lập trình

Cơ sở lập trình Cơ sở lập trình

44

8/15/2017

 Ví dụ

 Lưu ý: Nếu sử dụng typedef để định nghĩa

int so_nha;

kiểu struct thì khi khai báo biến chỉ cần dùng tên kiểu (bỏ từ khóa struct)

 Ví dụ

int so_nha;

date ngay_sinh,ngay_nhap_hoc; dia_chi A, B; sinh_vien X, Y;

struct dia_chi { char phuong[20]; char quan[15]; char thanh_pho[15]; } A,B; Hoặc struct { char phuong[20]; char quan[15]; char thanh_pho[15]; } A,B;

177

178

struct sinh_vien { char ho_ten[30]; date ngay_sinh; char maSV[10]; }; Hoặc struct { char ho_ten[30]; date ngay_sinh; char maSV[10]; } sv1,sv2;

 Cú pháp

 Chú ý

Ten_cau_truc.ten_thanh_phan Ten_cau_truc.ten_cau_truc.ten_thanh_phan …

 Có thể sử dụng phép toán lấy địa chỉ đối với thành phần cấu trúc để nhập số liệu trực tiếp cho thành phần cấu trúc

 Cách 1: dùng khi biến hoặc mảng là thành phần trực

tiếp của một cấu trúc

 Ví dụ: A.phuong, A.quan, A.thanh_pho  Các cách khác: dùng khi biến hoặc mảng là thành

 Có thể gán hai biến cấu trúc cho nhau  Có thể khởi tạo cho biến cấu trúc bằng cách viết vào sau khai báo của chúng một danh sách các giá trị cho các thành phần.

phần trực tiếp của một cấu trúc mà bản thân cấu trúc này lại là thành phần của 1cấu trúc lớn hơn.

 Ví dụ: X.ngay_sinh.ngay

179

180

Cơ sở lập trình Cơ sở lập trình

Cơ sở lập trình Cơ sở lập trình

45

8/15/2017

 Cách khai báo: Tương tự như với các kiểu

5.3.1 Khai báo biến mảng cấu trúc 5.3.2 Truy nhập phần tử mảng cấu trúc

dữ liệu cơ sở, chỉ thêm từ khóa struct

 Ví dụ

struct sinh_vien ds1[50],ds2[100]; struct dia_chi xom5[100];

181

182

 Tương tự như mảng thông thường: thông qua tên và

 Khởi tạo cho biến cấu trúc: tương tự mảng  Ví dụ

chỉ số của phần tử

 Ví dụ

struct month {

int number; char *name;

} year[] ={

{1,”january”},{2,”february”},…,{12,”december”}

}

 Để xác định số phần tử của year ta có thể dùng toán tử sizeof:

int n= sizeof(year)/sizeof(struct month);

scanf(“%d”,&ds[i].ngay_sinh.ngay); scanf(“%d”,&ds[i].ngay_sinh.ngay); scanf(“%d”,&ds[i].ngay_sinh.ngay); fflush(stdin); gets(ds[i].MaSV);

183

184

Cơ sở lập trình Cơ sở lập trình

Cơ sở lập trình Cơ sở lập trình

struct sinh_viên ds[50]; for (int i=0;i<50;i++) { fflush(stdin);gets(ds[i].ho_ten); }

46

8/15/2017

 Ý nghĩa: định nghĩa kiểu dữ liệu bằng cách liệt kê ra tất cả các giá trị mà ta muốn có.

5.4.1 Kiểu enum (kiểu liệt kê) 5.4.2 Kiểu typedef

 Cú pháp

enum name {// liệt kê các giá trị};

Trong đó enum là từ khóa, name là tên của kiểu

 Ví dụ

enum ten_mua {xuan, ha, thu, dong}; enum ten_mua mua;

185

186

 Đặc điểm

 Khái niệm: kiểu typedef là kiểu dữ liệu do người

dùng định nghĩa với từ khóa typedef.

 Các giá trị được liệt kê thực chất tương ứng là

 Ý nghĩa

một dãy số tự nhiên bắt đầu từ 0.

 Cho phép đặt lại tên cho các kiểu dữ liệu đã tồn tại

 Ví dụ: xuan, ha, thu, dong tương ứng với 0, 1, 2, 3

Cơ sở lập trình Cơ sở lập trình

Ví dụ: typedef int so_nguyen;

printf(“%d”,thu);  in ra giá trị là 2.

 Làm cho chương trình dễ đọc, ngắn gọn và có thể dễ dàng

chuyển mã code sang máy khác

Ví dụ:

 Lưu ý: Không thể đọc trực tiếp và ghi ra giá trị của kiểu liệt kê, vì mỗi giá trị tương ứng với một số tự nhiên

int ds1[20],ds2[20],ds3[20],ds4[20]; typedef int ds[20]; // thay bằng ds ds1,ds2,ds3,ds4; kiểu struct  khai báo biến không cần từ khóa struct

187

188

Cơ sở lập trình Cơ sở lập trình

47

8/15/2017

 Khái niệm: Tệp là một tập hợp các dữ liệu có liên quan với nhau và có cùng kiểu được nhóm lại với nhau tạo thành một dãy. Chúng thường được lưu trong một thiết bị nhớ ngoài với một tên cụ thể.

5.5.1 Khái niệm và phân loại tệp 5.5.2 Các bước xử lý tệp 5.5.3 Một số hàm dùng chung cho các kiểu tệp

 Đặc điểm

(tự học)

 So sánh với struct và mảng (kiểu dữ liệu từng phần

tử, số phần tử, lưu trữ, truy nhập)

 Biến đệm (cửa sổ tệp), bộ nhớ đệm, EOF, feof

5.5.4 Tệp nhị phân 5.5.5 Tệp văn bản

(hàm)  Phân loại

 Theo cách truy cập: tệp truy cập tuần tự và tệp truy

cập trực tiếp (C chỉ định nghĩa tệp tuần tự)

 Theo bản chất dữ liệu: tệp văn bản và tệp nhị phân

189

190

 Khai báo biến tệp

 Cú pháp: FILE *name;

 Khai báo biến tệp  Mở tệp (để đọc hoặc ghi dữ liệu)  Xử lý dữ liệu (đọc hoặc ghi dữ liệu)  Đóng tệp

Trong đó: ▪ FILE: là từ khóa ▪ name: là tên con trỏ tệp (biến tệp)

 Ví dụ FILE *f;

191

192

Cơ sở lập trình Cơ sở lập trình

Cơ sở lập trình Cơ sở lập trình

48

8/15/2017

Mode

Ý nghĩa

„”r” Mở tệp văn bản đã tồn tại để đọc

 Mở tệp  Cú pháp: name = fopen(filename, mode); Trong đó:

“w” Mở tệp văn bản mới để ghi. Nếu tệp đã tồn tại thì nó sẽ bị xóa đi và

 filename: là một hằng xâu ký tự thể hiện tên của tệp

thay vào đó là một tệp mới

cùng với đường dẫn của nó trên bộ nhớ ngoài.

“a”

Mở tệp văn bản đã có và ghi thêm dữ liệu tiếp nối vào cuối tệp. Nếu tệp chưa tồn tại thì một tệp mới được tạo ra

 mode: là một hằng xâu ký tự thể hiện chế độ xử lý

“r+” Mở tệp văn bản đã có và cho phép cả đọc và ghi

tệp, quy định cách xử lý tệp đã mở.

 Ví dụ

“w+” Mở tệp văn bản mới cho phép cả đọc và ghi. Nếu tệp đã tồn tại thì nó

sẽ bị xóa đi và thay bằng tệp mới

“a+” Mở tệp văn bản đã có hoặc tạo tệp mới để đọc và ghi thêm dữ liệu

f=fopen(“D:\\TC\\bt1.txt”,”w”); f=fopen(“D:\\TC\\bt2.txt”,”r”);

tiếp nối vào tệp.

193

194

Cơ sở lập trình Cơ sở lập trình

Mode

Ý nghĩa

“rb” Mở tệp nhị phân đã tồn tại để đọc

“wb” Mở tệp nhị phân mới để ghi. Nếu tệp đã tồn tại thì nó sẽ bị xóa đi

và thay vào đó là một tệp mới

 Hàm đọc/ghi số nguyên  Hàm đọc/ghi ký tự  Hàm đọc/ghi khối dữ liệu (số thực/struct)

“ab” Mở tệp nhị phân đã có và ghi thêm dữ liệu tiếp nối vào cuối tệp.

Nếu tệp chưa tồn tại thì một tệp mới được tạo ra

“r+b” Mở tệp nhị phân đã có và cho phép cả đọc và ghi

“w+b” Mở tệp nhị phân mới cho phép cả đọc và ghi. Nếu tệp đã tồn tại thì

nó sẽ bị xóa đi và thay bằng tệp mới

“a+b” Mở tệp nhị phân đã có hoặc tạo tệp mới để đọc và ghi thêm dữ liệu

tiếp nối vào tệp.

195

196

Cơ sở lập trình Cơ sở lập trình

49

8/15/2017

 Hàm putw

 Hàm getw

 Dạng hàm: int putw(int n, FILE *f) Trong đó:

 Dạng hàm: int getw( FILE *f) Trong đó:

▪ f là con trỏ tệp

▪ n là một giá trị nguyên ▪ f là con trỏ tệp

 Công dụng: đọc một số nguyên 2 bytes từ tệp f. Nếu thành công thì hàm trả lại giá trị là số nguyên đọc được từ tệp. Nếu gặp lỗi hoặc gặp kết thúc tệp hàm trả lại giá trị là EOF.

 Công dụng: ghi một giá trị nguyên n vào tệp f dưới dạng 2 bytes. Nếu thành công thì hàm trả lại giá trị là số nguyên được ghi vào tệp, ngược lại hàm trả lại giá trị là EOF.

197

198

f=fopen(“BT.txt”,”rb”);

/* Đọc các số nguyên từ tệp*/ while ((i = getw(f))!=EOF)

 Ví dụ: viết chương trình thực hiện việc ghi một dãy số nguyên vào tệp sau đó đọc các số nguyên này từ tệp và in ra màn hình.

printf(“%d”,i);

FILE *f; int i;

{

fclose(f); getch(); } //quy tắc đọc tệp trong C: Phải đọc phần tử của tệp trước rồi mới thử xem phần tử đó có phải là EOF hay không.

#include #include void main() /*ghi các số nguyên vào tệp*/ f= fopen(“BT.txt”,”wb”); for (i=1;i<100;i++) putw(i,f); fclose(f);

199

200

Cơ sở lập trình Cơ sở lập trình

Cơ sở lập trình Cơ sở lập trình

50

8/15/2017

 Hàm fputc

int fputc(int ch, FILE *f)

 Dạng hàm Trong đó:

 Hàm fgetc  Dạng hàm int fgetc(FILE *f) Trong đó:

▪ f :là con trỏ tệp

 ch: là một giá trị nguyên  f: là con trỏ tệp

 Công dụng: đọc một ký tự từ tệp f. Nếu thành công hàm trả lại giá trị là mã của ký tự đọc được. Nếu có lỗi hoặc gặp kết thúc tệp thì hàm sẽ trả lại giá trị là EOF

 Công dụng: hàm này có chức năng ghi vào tệp f một ký tự có mã là m = ch % 256. Nếu thành công thì hàm trả lại giá trị là mã của ký tự được ghi. Ngược lại hàm sẽ trả lại giá trị là EOF.

 Lưu ý: Ghi cách khác bằng sử dụng macro

int putc(int ch, FILE *f)

 Lưu ý: Cách đọc khác bằng sử dụng macro int getc(FILE *f)

201

202

 Ví dụ: Chương trình sau thực hiện công việc

Cơ sở lập trình Cơ sở lập trình

sao chép dữ liệu từ tệp f1 sang tệp f2

if (f1== NULL) { printf(“\n Tep khong ton tai”); getch(); exit(1);

while ((c=fgetc(f1))!=EOF) fputc(c,f2);

#include #include void main() { char t1[14], t2[14]; FILE *f1,*f2; int c; printf(“\n Nhap ten tep nguon”); gets(t1); printf(“\n Nhap ten tep dich”); gets(t2);

f1= fopen(t1,”rb”);

204

203

} f2=fopen(t2,”wb”); fclose(f1); fclose(f2); }

Cơ sở lập trình Cơ sở lập trình

51

8/15/2017

 Dạng hàm: int fwrite(void *p, int size, int n, FILE *f) Trong đó:

 Dạng hàm: int fread(void *p, int size, int n, FILE *f) Trong đó:

 p: là con trỏ trỏ tới vùng nhớ chứa dữ liệu cần ghi  size: là kích thước của khối dữ liệu  n: là số khối dữ liệu cần ghi  f: là con trỏ tệp.

 p: là con trỏ trỏ tới vùng nhớ chứa dữ liệu đọc được  size: là kích thước của khối dữ liệu theo byte  n: là số khối dữ liệu cần đọc  f: là con trỏ tệp.

 Công dụng: ghi n khối dữ liệu kích thước size byte từ vùng nhớ p vào tệp f. Hàm trả lại giá trị bằng số khối dữ liệu thực sự ghi được vào tệp

 Công dụng: đọc n khối dữ liệu kích thước size byte từ tệp f đưa vào vùng nhớ p. Hàm trả về giá trị là số khối dữ liệu thực sự đọc được.

 Lưu ý:

 Lưu ý

 Giá trị trả về của hàm có thể nhỏ hơn số khối dữ liệu được

 Hàm cho phép ghi nhiều khối dữ liệu với yêu cầu các khối dữ liệu này phải cùng kích thước. size là tổng kích thước của n khối dữ liệu và được tính bằng hàm sizeof().

yêu cầu (cuối tệp hoặc khi có một lỗi nào đó)

205

206

 Hàm đọc/ghi theo khuôn dạng  Hàm đọc/ghi ký tự  Hàm đọc/ghi xâu ký tự

 Ví dụ: 1. Viết chương trình sử dụng hàm fread và fwrite để đọc/ghi dãy số nguyên lớn(long - 4B)/số thực. 2. Viết chương trình minh họa cách dùng các hàm fwrite và fread để đọc/ ghi một tệp chứa danh sách gồm n sinh viên bao gồm các thông tin hten, que, dtoan, dly,dhoa. (chương trình)

207

208

Cơ sở lập trình Cơ sở lập trình

Cơ sở lập trình Cơ sở lập trình

52

8/15/2017

 Hàm fprintf  Dạng hàm:

int fprintf(FILE *f, char*format, [para_values])

 Hàm fscanf  Dạng hàm: int fscanf(FILE *f, char*format, [para_values]) Trong đó:

Trong đó:

 f: là con trỏ tệp

 format: chứa địa chỉ chuỗi điều khiển

 f: là con trỏ tệp  format: chứa địa chỉ chuỗi điều khiển  para_values:là danh sách các đối chứa kết quả đọc được từ

 para_values: là danh sách các đối mà giá trị của chúng cần ghi lên tệp

tệp

 Công dụng: ghi vào tệp giá trị của các đối theo khuôn dạng được xác định trong chuỗi điều khiển. Nếu thành công hàm trả về giá trị bằng số byte ghi vào tệp. Nếu có lỗi hàm sẽ trả về giá trị là EOF.

 Công dụng: đọc dữ liệu từ tệp biến đổi theo khuôn dạng trong format và lưu kết quả vào các đối. Hàm trả về giá trị bằng số trường đọc được.

 Lưu ý

 Lưu ý

 Chuỗi điều khiển và danh sách các đối có ý nghĩa như trong hàm printf

và cách thức hoạt động của hàm này cũng giống như hàm printf.

 Ý nghĩa của chuỗi điều khiển, danh sách các đối và cách thức hoạt động của hàm này cũng giống như hàm scanf.

209

210

 Tương tự như trong tệp nhị phân  Lưu ý

 Ví dụ: viết chương trình thực hiện nhập một số nguyên n rồi thực hiện ghi n và dãy số nguyên từ 0 đến n-1 vào tệp, sau đó thực hiện đọc tệp và đưa vào một mảng

 (chương trình)

 Đối với các hàm putc và fputc trong tệp văn bản nếu mã của ký tự cần ghi m=10 (mã chuyển dòng) thì hàm sẽ ghi vào tệp hai mã là 13 và 10.  Đối với hàm getc và fgetc trong tệp văn bản khi đọc được hai mã 13 và 10 liền nhau thì hàm sẽ trả lại một giá trị là 10, và khi gặp mã 26 (mã kết thúc tệp) thì hàm sẽ trả lại giá trị là EOF chứ không trả lại giá trị 26.

211

212

Cơ sở lập trình Cơ sở lập trình

Cơ sở lập trình Cơ sở lập trình

53

8/15/2017

 Hàm fgets

 Dạng hàm: char *fgets(char *s, int n, FILE *f) Trong đó:

int fputs(const char *s, FILE *f)

 Hàm fputs  Dạng hàm: Trong đó:

▪ s: là con trỏ tới vùng nhớ chứa chuỗi ký tự đọc

được từ tệp

▪ s: là con trỏ trỏ tới địa chỉ đầu của một chuỗi ký tự kết

thúc bằng dấu „\0‟

▪ n: là số nguyên xác định độ dài tối đa của chuỗi

▪ f: là con trỏ tệp

cần đọc

▪ f: là con trỏ tệp

 Công dụng: ghi chuỗi ký tự s vào tệp f (dấu „\0‟ không được ghi vào tệp). Nếu thành công hàm trả lại giá trị là ký tự cuối cùng được ghi vào tệp. nếu có lỗi hàm trả lại giá trị là EOF

213

214

 Công dụng: đọc một xâu ký tự từ tệp f đưa vào

 Ví dụ: viết chương trình thực hiện nhập các dòng ký tự từ bàn phím và ghi vào tệp. Sau đó sẽ mở lại tệp để đọc tệp và in ra màn hình

vùng nhớ s. ▪ Kết thúc việc đọc khi hoặc đã đọc n-1 ký tự, hoặc gặp dấu xuống dòng (13 và 10, mã 10 được đưa vào xâu kết quả), hoặc kết thúc tệp

 (chương trình)

▪ Xâu kết quả sẽ được bổ sung thêm dấu hiệu kết thúc chuỗi „\0‟. Nếu thành công hàm trả lại giá trị là địa chỉ vùng nhớ nhận kết quả. Ngược lại nếu có lỗi hoặc gặp cuối tệp hàm trả lại giá trị là NULL

216

Cơ sở lập trình Cơ sở lập trình

215 8/15/2017 Cơ sở lập trình Cơ sở lập trình

54