163636_ngon ngu c

65
8/14/2019 163636_Ngon Ngu C http://slidepdf.com/reader/full/163636ngon-ngu-c 1/65 Bài 1: NGUYÊN TẮC LẬP TRÌNH Các khái niệm cơ bản: MTĐT hoạt động dựa trên nguyên tắc làm việc theo chương trình. -1 Chương trình (Program): Gồm những phát biểu, những lệnh riêng lẻ sắp xếp theo một trình tự nào đó nhằm điểu khiển máy tính làm việc. Các lệnh này phải được diễn tả bằng một ngôn ngữ lập trình thích hợp mới có thể thực hiện được. Những ngôn ngữ thường dùng như : Basic, Pascal, C, Prolog ... . -2 Ngôn ngữ lập trình (Programming language): Là một hệ thống hữu hạn các ký hiệu Ví dụ: Ngôn ngữ Pascal dùng các ký hiệu: if, then, else, while, , var, {, }.... gọi là các từ khóa (key word) và các ký tự: a,..,z,A,..,Z, 0,1,..,9,... không dùng các ký hiệu của bộ chữ cái Hy Lạp. Các ký hiệu đó phải tuân theo các qui ước về ngữ pháp và ngữ nghiã, cũng giống như khi bạn muốn nói một câu có ý nghiã thì phải kết hợp các từ theo các qui tắc ngữ pháp và ý nghiã của từ trong tiếng mình đang sử dụng.  Ngữ pháp (Syntax) : qui ước về quan hệ giữa càc ký hiệu. Ví dụ: Trong ngôn ngữ Pascal, các ký hiệu {, } phải đi thành từng cặp; sau ký hiệu IF  phải là một (biểu thức điều kiện), sau đó phải là ký hiệu THEN;...  Ngữ nghiã (semantics): Qui ước về ý nghiã của các ký hiệu. Ví dụ: Dấu + biểu thị phép cộng; dấu * biểu thị phép nhân; phát biểu IF ... THEN ... có nghiã là “Nếu ... thì ....”;... -3 Sự thực hiện chương trình (Program Execution): Chương trình được thực hiện tuân theo các qui ước ngữ nghiã của ngôn ngữ. Ví dụ: Phát biểu: IF (x > 0) THEN frintf("dương") ELSE frintf("không dương"); Đến lúc thực hiện phát biểu này nếu trị của x lớn hơn 0 thì phát biểu WRITE(‘dương’) được thực hiện (chuỗi chữ ‘dương’ được in ra), còn phát biểu WRITE(‘không dương’) không được thực hiện. Phần lớn các ngôn ngữ hiện nay thực hiện tuần tự, tức là lần lượt thực hiện phát biểu này xong rồi đến phát biểu kế tiếp. Cũng có ngôn ngữ thực hiện song song, tức là thực hiện cùng lúc một số phát biểu. -4 Thuật Toán (Algorithm): Cách thức giải quyết vấn đề. Giáo sư Niklaus Wirth (Trường ĐH kỹ thuật Zurich, Thụy sĩ), người sáng lập ra ngôn ngữ Pascal (1970) đã viết: Algorithms + Data structures = Programs Để viết chương trình giải quyết một vấn đề, trước tiên cần phải có giải thuật. Thuật toán là một dãy các chỉ dẫn rõ ràng các thao tác (công việc, phép toán...) trên những đối tượng, sao cho sau một số hữu hạn bước thực hiện các thao tác, ta đạt được mục tiêu định trước. Có nhiều cách diễn đạt thuật giải: a. Bằng ngôn ngữ tự nhiên: Ví dụ: Thuật toán giải phương trình bậc nhất ax + b = 0 Bước 1: Nhập vào các hệ số a và b Bước 2: Nếu a = 0 chuyển sang bước 3 nếu không thì chuyển sang bước 4. Bước 3: Nếu b = 0 thì thông báo phương trình đã cho có vô số ngiệm

Upload: binhthuongthui095928

Post on 30-May-2018

240 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 1/65

Bài 1: NGUYÊN TẮC LẬP TRÌNHCác khái niệm cơ bản:

MTĐT hoạt động dựa trên nguyên tắc làm việc theo chương trình.-1 Chương trình (Program):

Gồm những phát biểu, những lệnh riêng lẻ sắp xếp theo một trình tự nào đó nhằmđiểu khiển máy tính làm việc.

Các lệnh này phải được diễn tả bằng một ngôn ngữ lập trình thích hợp mới có thểthực hiện được. Những ngôn ngữ thường dùng như : Basic, Pascal, C, Prolog ... .-2 Ngôn ngữ lập trình (Programming language):

Là một hệ thống hữu hạn các ký hiệuVí dụ: Ngôn ngữ Pascal dùng các ký hiệu: if, then, else, while, , var, {, }.... gọi là các

từ khóa (key word)và các ký tự: a,..,z,A,..,Z, 0,1,..,9,... không dùng các ký hiệu của bộ chữ cái HyLạp.

Các ký hiệu đó phải tuân theo các qui ước về ngữ pháp và ngữ nghiã, cũng giống nhưkhi bạn muốn nói một câu có ý nghiã thì phải kết hợp các từ theo các qui tắc ngữ phápvà ý nghiã của từ trong tiếng mình đang sử dụng.

 Ngữ pháp (Syntax): qui ước về quan hệ giữa càc ký hiệu.Ví dụ: Trong ngôn ngữ Pascal, các ký hiệu {, } phải đi thành từng cặp; sau ký hiệu IF

 phải là một (biểu thức điều kiện), sau đó phải là ký hiệu THEN;... Ngữ nghiã (semantics): Qui ước về ý nghiã của các ký hiệu.

Ví dụ: Dấu + biểu thị phép cộng; dấu * biểu thị phép nhân; phát biểu IF ... THEN ...có nghiã là “Nếu ... thì ....”;...

-3 Sự thực hiện chương trình (Program Execution):Chương trình được thực hiện tuân theo các qui ước ngữ nghiã của ngôn ngữ.

Ví dụ: Phát biểu:IF (x > 0) THEN frintf("dương") ELSE frintf("không dương");

Đến lúc thực hiện phát biểu này nếu trị của x lớn hơn 0 thì phát biểuWRITE(‘dương’) được thực hiện (chuỗi chữ ‘dương’ được in ra), còn phát biểuWRITE(‘không dương’) không được thực hiện.

Phần lớn các ngôn ngữ hiện nay thực hiện tuần tự, tức là lần lượt thực hiện phát biểunày xong rồi đến phát biểu kế tiếp. Cũng có ngôn ngữ thực hiện song song, tức là thực hiệncùng lúc một số phát biểu.-4 Thuật Toán (Algorithm): Cách thức giải quyết vấn đề.

Giáo sư Niklaus Wirth (Trường ĐH kỹ thuật Zurich, Thụy sĩ), người sáng lập rangôn ngữ Pascal (1970) đã viết: Algorithms + Data structures = Programs

Để viết chương trình giải quyết một vấn đề, trước tiên cần phải có giải thuật.Thuật toán là một dãy các chỉ dẫn rõ ràng các thao tác (công việc, phép toán...) trên

những đối tượng, sao cho sau một số hữu hạn bước thực hiện các thao tác, ta đạt được mụctiêu định trước.

Có nhiều cách diễn đạt thuật giải:a. Bằng ngôn ngữ tự nhiên:

Ví dụ: Thuật toán giải phương trình bậc nhất ax + b = 0Bước 1: Nhập vào các hệ số a và b

Bước 2: Nếu a = 0 chuyển sang bước 3nếu không thì chuyển sang bước 4.Bước 3: Nếu b = 0 thì thông báo phương trình đã cho có vô số ngiệm

Page 2: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 2/65

 Nếu không thì thông báo là phương trình vô nghiệm.Chuyển sang bước 5.

Bước 4: Thông báo nghiệm của phương trình là -b/a.Bước 5: Dừng thuật toán.

Trong ví dụ này, đối tượng chịu thao tác là các số thực a, b, x với ràng buộc ax + b =0. Và các thao tác là :

-  Nhập hai số a, b- So sánh ( a = 0 ?; b = 0 ?)- Chia ( phép chia -b cho a)- Thông báo kết quả- Dừng thuật toán.- Chuyển sang bước ...

 Nhận xét: Ưu điểm là người viết không phải chuẩn bị trước những kiến thức gì đặt biệt. nhưng thường dài dòng, không làm nổi bật được cấu trúc thuật toán.b. Ngôn ngữ Lưu đồ (Flow Chart: sơ đồ khối):

Lưu đồ thuật giải được xây dựng từ những hình cơ bản sau:a.Nút giới hạn:

b. Nút thao tác:

c. Nút điều kiện:

d. Cung: là những đường có hướng nối từ nút này đến nút khác.Hoạt động của thuật toán dưới dạng lưu đồ được bắt đầu từ nút đầu tiên, theo các

cung đến các nút khác cho đến khi gặp nút kết thúc thì dừng thuật toán.Ví dụ: Lưu đồ thuật toán giải phương trình bậc nhất ax + b = 0

Begin

End

 Nhập a, b

a = 0

Xuất phương trìnhcó nghiệm x = -b/a

Xuất phương trìnhcó vô số nghiệm

Xuất phương trìnhcó vô nghiệm

 b = 0

-

+-

+

2

BE

A

ĐK -

+

Page 3: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 3/65

Page 4: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 4/65

-  Nếu UCLN(x,x')=1 thì ghi nhận xCách giải 2:

 Nhận Xét 1: x = 23 ta có UCLN(23, 32) =1 suy ra 23 là số cần tìm và số 32 cũng làsố cần tìm.

 Nhận xét 2: x = 44 thì x'=44 UCLN(x,x')=44 suy ra x=aa không là số cần tìm. Nhận xét 3: Trong các số x=a0 thì chỉ có x=10 là số cần tìm

Thuật toán 2: Ghi nhận số 10 là số cần tìmCho a = 1 tới 9

cho b = 1 tới a-1x = a*10+b và x' = b*10+a

 Nếu UCLN(x,x') =1 thì ghi nhận x và x'Chú ý:

Khi lập trình thường có hai loại sai lầm như sau:+ Thuật giải sai: Với cách giải sai thì chương trình sẽ cho kết quả sai+ Thuật giải đúng nhưng thể hiện bằng chương trình sai: có nghiã không thể hiện

chính xác giải thuật bằng ngôn ngữ lập trình.Ví dụ: Tính nghiệm phương trình bậc hai: x1:=(-b - sqrt(delta))/2*a là sai

4

Page 5: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 5/65

Bài 2: Tổng Quan Về Ngôn Ngữ C-I Giới thiệu về C:

Khác với Pascal, là ngôn ngữ cấp cao được xây dựng để học tập và giảng dạy lậptrình, ngôn ngữ C và ngôn ngữ phát triển của nó là C++ được xây dựng xuất phát từ nhữngyêu cầu xây dựng những ứng dụng thực tế, vì thế C có được tất cả những ưu điểm của ngônngữ cấp cao đó là:

• Tính cô đọng và rất gọn khi lập trình, có thể thâm nhập vào mọi nguồn dữ liệu vàhệ thống.

• Có nhiều mô hình tổ chức bộ nhớ và nhiều toán tử mạnh.Với những ưu điểm trên, ngày nay các chương trình lớn đều được viết bằng C. Ví dụ

như hệ điều hành Windows, Unix... Ngôn ngữ C trở nên bắt buộc đối với các nhà lập trìnhchuyên nghiệp.

• Bộ phần mềm Turbo C 2.0 có các tập tin chính như sau:- TC.EXE: Trình soạn thảo và biên dịch chính

- *.LIB: Các thư viện hàm- *.H: Các tập tin tiêu đề khai báo các hằng, biến, kiểu dữ liệu, hàm thư viện.• Khởi động trình soạn thảo TC: DDL>TC• Đóng trình soạn thảo TC: Alt + X• Thoát tạm khỏi IDE: Alt F O .Để vào lại IDE: nhập EXIT

I- Các ví dụ về chương trình C:Ví dụ 1: In ra màn hình 2 dòng chữ:

DAY LA CHUONG TRINH CCHAO CAC BAN

/* Chương trình in 2 dòng chữ*/#include “stdio.h”#include “conio.h”void main() /* hàm chính */{

printf (“DAY LA CHUONG TRINH C”);printf (“\nCHAO CAC BAN”);getch();

}

Giải thích:• /* ... */ : dòng ghi chú sẽ không được biên dịch.Mỗi chương trình nên bắt đầu bằng một ghi chú nói rõ mục đích của nó• Chỉ thị #include : dùng nạp header file chứa các hàm thư viện sử dụng trong

chương trình:

- File stdio.h: chứa các hàm nhập xuất trên dòng nhập xuất gián tiếp (printf )- File conio.h: chứa các hàm nhập xuất trực tiếp từ bàn phím, màn hình (getch).

 Khi sử dụng một hàm chuẩn cần biết nó nằm trong tập tin header nào và phải dùng lệnh #include để nạp tập tin đó vào chương trình.#include <[path]filename> : mặc định sẽ tìm trong thư mục chỉ định trong Options

Directories INCLUDE Directories#include “[path]filename” : mặc định tìm ở thư mục hiện hành, nếu không tìm thấy

sẽ tìm trong thư mục INCLUDE.Thông báo lỗi nếu không tìm thấy: Unable to open include file ‘[path]filename’ • Dòng main() : là bắt buộc đối với tất cả các chương trình C. Dấu () sau từ khóa

main cho biết main là 1 khối chương trình gọi là hàm (function).Khối thân hàm được xác định bằng cặp ký hiệu:

{ /* bắt đấu phần thân */

Page 6: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 6/65

} /* kết thúc phần thân */• Một câu lệnh được viết trên 1 hay nhiều dòng nhưng phải kết thức bởi dấu ; 

Ví dụ 2: Chương trình tính chu vi và diện tích hình tròn theo giá trị bán kính r nhập vào từ bàn phím.

#include “stdio.h”#include <conio.h>

#define Pi 3.14main(){ float r, cv, dt; /*Khai báo 3 biến kiểuthực*/

printf (“\nNhap ban kinh r = “);scanf (“%f”, &r);if (r <= 0)

printf (“\a\aBan kinh <= 0 khongtinh“);

else{

cv = 2 * PI * r;dt = PI * r * r;printf (“\nKet Qua:”);printf (“\n\t Chu vi = %10.2f \n\tDien tich = %10.2f”, cv, dt );

}getch();

}

Ví dụ 3: Một chương trình C có thể chứa 1 hay nhiều hàm, trong đó, bắt buộc phải có 1hàm main và phải nằm trên tất cả những hàm khác (nếu có). hàm này được tự độngthực hiện đầu tiên khi chạy chương trình.

#include “stdio.h”#include <conio.h>#define Pi 3.14float r ; /*biến ngoài*/Void NhapBanKinh( );main(){

float cv, dt; /*Khai báo 2 biến cục bộ*/ printf(“\nChương trình tính diện tíchvà chu vi hình tròn\n”);

 NhapBanKinh;if (r <= 0)

printf (“\a\aBan kinh <= 0 khongtinh“);

else{ cv = 2 * PI * r; dt = PI * r * r;

printf (“\nKet Qua:”);printf (“\n\t Chu vi = %10.2f \n\tDien tich = %10.2f”, cv, dt );

}getch();

}Void NhapBanKinh( ){ printf (“\nNhap ban kinh hinh tron r =“);

scanf (“%f”, &r);}

Chú thích: có thể sử dụng hằng M_PI đã định nghiã trong math.h -IICấu trúc của một chương trình C:• Các #include: dùng nạp header file chứa các hàm thư viện sử dụng trong chương trình:

• Các #define: dùng tạo các macro thay thế.• Khai báo các đối tượng dữ liệu ngoài (biến, mảng, cấu trúc, hợp...)• Khai báo trước đặc trưng các hàm tự tạo (nếu có).• Hàm main• Phần định nghiã các hàm tự tạoChú ý: Hàm main có thể đặt sau hoặc xen vào giữa các hàm khác, nhưng được tự động gọithực hiện đầu tiên trong chương trình.

6

Page 7: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 7/65

BÀI 3: Các Thành Phần Trong Ngôn ngữ C-I Khối lệnh:

Một dãy các câu lệnh nằm trong phạm vi 2 dấu móc { và } được gọi là khối lệnh• Một khối lệnh được xem như là 1 lệnh.• Do đó, các khối lệnh có thể lồng nhau.

-IIKiểu dữ liệu:Một kiểu dữ liệu là một tập hợp các giá trị có chung cách thức lưu trữ trong bộ nhớ,

cùng phương pháp xử lý, cùng một số các phép toán.Các kiểu dữ liệu cơ bản bao gồm:

Kiểu M Phạm vi Kích thướcChar -128 ... +127 1 byteunsigned char 0... 255 1 byteInt -32768 .. 32767 2 byteunsigned (int) 0 .. 65535 2 byte

long (int) -2.147.483.648 ..2.147.483.647 4 byte

unsigned long 0 .. 4.294.967.295 4 byteFloat 3.4E-38 .. 3.4E+38 4 byteDouble 1.7E-308.. 1.7E+308 8 bytelong double 3.4E-4932..1.1E+4932 10 byte

Kiểu số thực: Số có giá trị tuyệt đối nhỏ hơn cận dưới được xem = 0.Kiểu char và unsigned char: Một giá trị kiểu char chiếm 1 byte và biểu diễn được một kýtự trên bảng mã ASCII.

Ví dụ: ‘0’..’9’ có mã 48..57; ‘A’..’Z’ <--> 65..90; ‘a’..’z’ <--> 97..122

Ví dụ: sự khác nhau giữa 2 kiểu:char c1=196; unsigned char c2 = 196;

 printf(“Biểu diển c1 : %c %d \n Biểu diễn c2 : %c %d ”, c1, c1, c2, c2);Kết quả: Biểu diễn c1 : - -60

Biểu diễn c2 : - 196Thực chất: c1 = -60 nhưng c1 và c2 đều biểu diễn ký tự có mã ASCII là 196.

-IIIHằng:Hằng là những giá trị cố định thuộc phạm vi của một kiểu dữ liệu, không bị thay đổi

khi thực hiện chương trình.-1 Hằng số nguyên:• Hằng int: -15 1234

Printf(“%d %d”, -15, 1234);• Hằng long: Được viết: - 4567L hay - 4567l

Số nguyên vượt ra ngoài miền xác định của int cũng được xem là hằng long• Hằng số nguyên hệ 8: Luôn nhận giá trị dương, được viết dưới dạng: 0a1a2a3 

Ví dụ: số 97 hệ 10 được viết: 0141 trong hệ 8Printf(“%7d, 0141) -->97

• Hằng nguyên hệ 16: Được viết: 0xa1a2... hay 0Xa1a2...Ví dụ: số 169 được viết 0xa9 hay 0XA9

Printf(“%d”, 0xa9) --> 169.-2 Hằng số thực:• Kiểu float: 123.45F

Page 8: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 8/65

• Kiểu double: 123.45 123.45e-4 (0.012345)• Kiểu long double: 123.45L-3 Hằng kiểu ký tự:

Là 1 ký tự riêng biệt được viết trong 2 dấu nháy đơn. Ví dụ: ‘A’• Hằng ký tự thực sự là một số nguyên. Giá trị của hằng ký tự chính là mã ASCII

của ký tự đóVí dụ: char c1 = ‘A’; printf(“Biểu diễn c1: %c %d %o %x”, c1, c1, c1, c1) --> A 65 101 41

• Hằng ký tự có thể tham gia vào các phép toán như mọi số nguyên khác:Ví dụ: ‘B’ - ‘A’ = 66 - 65 = 1

• Có thể biểu diễn hằng ký tự bằng số:Ví dụ: char c1=’A’,c2=65, c3=’\101’, c4 = ‘\x41’;

hay c1=’A’,c2=65, c3=0101, c4 = 0x41;  printf(“%c %c %c %c”,c1, c2, c3, c4); sẽ in ra A A A A printf(“%c%c%c“,7,7,7); sẽ phát 3 tiếng beep.

• Một vài hằng ký tự đặt biệt ta cần phải sử dụng cách viết sau:‘\’ ’ :

‘‘\” ‘:

“‘\\’ :

\‘\n’ :LF (10)

‘\r’CR(13)

‘\b’: backspace

‘\0’: NULL

‘\t’ :Tab.

-4 Hằng chuỗi:Là chuỗi bất kỳ đặt trong cặp dấu ngoặc kép (“ “)

Ví dụ: “TURBO C”• Các ký tự trong chuỗi có thể gồm các ký tự không có trên bàn phím, khi đó được

 biểu diễn sau ký hiệu (\)• Chuỗi ký tự trong C được lưu trữ dưới dạng mảng các ký tự và được C thêm ký tự

‘\0’ (null) cuối chuỗi.Ví dụ: Phân biệt giữa ký tự ‘a’ và chuỗi “a”

• Chuỗi rỗng được viết bằng 2 dấu nháy đôi liên tục: “”-IVBiến:

Một biến là 1 vùng nhớ trong RAM dùng lưu trữ dữ liệu tạm thời trong quá trìnhthực hiện chương trình. Việc truy xuất đến giá trị lưu trong vùng nhớ được thực hiện thôngqua tên biến.-1 Khai báo biến:

[static] Kiểudữliệu tênbiến1[= giátrị] , tênbiến2[=giátrị];Tên (identifier): là 1 chuỗi tối đa 32 ký tự gồm chữ cái, số, dấu gạch dưới. Trong đó

ký tự đầu tiên không phải là số. C phân biệt chữ hoa và chữ thường. Có thể chỉđịnh chiều dài tối đa của tên bằng chức năng:OptionsCompilerSourceIdentifier length.

-2 Vị trí khai báo:Vị trí khai báo biến sẽ qui định phạm vi hoạt động của biến.

• Khai báo bên trong khối lệnh: (Biến cục bộ)- Phải được khai báo sau dấu {, đầu khối và trước tất cả các câu lệnh khác trong khối.- Phạm vi hoạt động: Các biến này chỉ được sử dụng bên trong khối lệnh đó.- Thời gian tồn tại: Khi thực hiện xong khối lệnh, thì vùng nhớ cấp phát cho các

 biến này sẽ xóa (ngoại trừ trường hợp có sử dụng từ khóa static).

- Giá trị ban đầu: Nếu không gán giá trị khởi đầu thì giá trị của các biến cục bộ chưađược xác định. Trường hợp có sử dụng từ khóa Static: thì các biến này có giá trị khởi

8

Page 9: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 9/65

đầu mặc định là 0 và chỉ được gán giá trị khởi đầu khi thực hiện lần đầu tiên, các lầnsau sẽ sử dụng giá trị hiện đang lưu trử.

- Tên các biến trong cùng 1 khối lệnh không được trùng nhau nhưng có thể trùng tênvới biến nằm ngoài khối lệnh.

Ví dụ: {int a =5, b =2;

{int a=4;

 b = a+b; printf(“\n In trong khối a = %d, b = %d, a, b);

} printf(“\n In ngoài khối a = %d, b = %d, a, b);

}Kết quả: In trong khối a = 4, b = 6

In ngoài khối a = 5, b = 6Ví dụ: Phân biệt giữa biến cục bộ có cùng tên.

main(){ int x = 5;

thu(); printf(“\n gia tri x trong ham main = %d, x);

}void thu(void){ int x =3;

 printf(“\n gia tri x trong ham thu = %d, x);}

• Khai báo bên ngoài các hàm:(gọi là Biến ngoài)- Phạm vi sử dụng của biến ngoài là từ vị trí khai báo của nó cho đến cuối chương

trình. Nó có thể sử dụng cho các chương trình khác nhờ khai báo extern viết trên cácfile này.

- Giá trị ban đầu: Khi chưa được khởi đầu thì giá trị của biến ngoài = 0.- Thời gian tồn tại: cho đến khi kết thúc chương trình.

-3 Lấy địa chỉ của biến:Mỗi biến được cấp phát trong bộ nhớ gồm một hay nhiều byte liên tiếp tùy thuộc vào

kiểu dữ liệu. Địa chỉ của byte đầu tiên là địa chỉ của biến.Phép toán: &tênbiến trả về địa chỉ của biến.

-VLệnh Nhập Xuất Dữ Liệu Cơ Bản:-1 Xuất dữ liệu ra màn hình:

printf(“dòng điều khiển”, danh sách biểu thức)• Dòng điều khiển: gồm 3 loại

- Các ký tự hiển thị- Các ký tự điều khiển: ký tự \ dùng để bắt đầu một ký hiệu điều khiển.

Ký hiệu Điều khiển Ký Hiệu Điều khiển\n NewLine. Dời con trỏ xuống dòng \\ Backslash. In dấu \\t Tab. Dời con trỏ đến vị trí tab kế tiếp \” Dùng in dấu nháy kép “\r Carriage return. Dời con trỏ về đầu dòng \’ Dùng in dấu nháy đơn ‘

\a Alert. Phát tiếng beep ở loa- Các mã đặc tả giá trị của biểu thức khi hiển thị. Thứ tự các đặt tả phải phù hợpvới kiểu của biểu thức cần in.

9

Page 10: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 10/65

Đặc tả Ý nghiã Đặc tả Ý nghiã%d số nguyên hệ thập phân có dấu %e %E số thực dạng mũ 10 (1.23456e+2)%u số nguyên không dấu %g Đọc 1 số dấu chấm động%o số bát phân %c ký tự đơn%x số thập lục phân %s chuỗi ký tự%f số thực (123.456)

Để ấn định độ rộng tối thiểu vùng in 1 số nguyên :%[-][n]dVí dụ: printf(“%6d”,-456) |__-456| //thêm dấu cách bên trái

 printf(“%-6d”,-456) |-456__| //Canh lề trái printf(“%2d”,-456) |-456|

Đối với số thực: %[-][n][.tp]f Ví dụ: printf(“%f”,-45.63) |-45.630000|

 printf(“%f”,45.63) |45.630000| printf(“%8.3d”,-45.63) |_-45.630| /*thêm dấu cách bên trái printf(“%.1d”,-45.67) |-45.7|

-2 Xuất kết quả ra máy in:fprintf(stdprn,“dòng điều khiển”, danh sách biểu thức)

* Tham số stdprn dùng chỉ định thiết bị xuất là máy in.-3 Nhập giá trị cho biến:a. Toán tử gán và biểu thức gán: (Assignment operators & Assignment expression)• Trong C có 2 kiểu gán giá trị như sau:

Phép gán đơn giản: biến = biểu thức ;Phép gán phức hợp: biến pt= biểu thức; <==>biến = biến pt biểuthức

pt : +, -, *, /, %Ví dụ: a = a + 2; <==> a += 2;

a = a*(b-c); <==> a *= b-c;• Biểu thức gán: biến = biểuthức- Giá trị của biểu thức gán là giá trị của biểuthức vế phải- Kiểu của biểu thức gán là kiểu của biến.

Ví dụ: a = b = 5; <==> a = 5; b = 5;x = (a = 2) * (b = 3);<==> a = 2; b = 3; x = a * b ; (x==6)

b- Hàm scanf: int scanf (“chuổi điều khiển”, danh sách địa chỉ các biến);int scanf(const char *đk [,danh sách đối số]);

Dùng đọc dữ liệu trên dòng nhập stdin vào cho các biến. Nếu dòng nhập stdin khôngcó đủ dữ liệu thì hàm sẽ chờ nhập tiếp dữ liệu cho dòng nhập từ bàn phím, khi ấn phím

Enter, hàm tiếp tục đọc dữ liệu cho các biến còn lại.Dòng nhập stdin: là vùng nhớ chứa dãy ký tự nhập từ bàn phím, bao gồm cả các kýtự trắng như dấu cách, tab, ký tự xuống dòng \n.

Chuỗi điều khiển: chứa 3 loại : Các Mã đặc tả kiểu dữ liệu của biến; Ký tự trắng; Kýtự khác ký tự trắngMã đặc tả: dùng xác định cách thức đọc ký tự trên dòng nhập và chuyển thành kiểu dữ

liệu đã đặc tả trước khi gán nó cho biến tương ứng.Mỗi đặt tả có dạng: %[*][w][.sốlẻ]kýtựchuyểndạngKý tự chuyển dạng gồm: d, ld, o, lo, x, lx, f hay e, lf hay le, c, s

[dãykýtự]: Đọc cho đến khi gặp 1 ký tự không thuộc dãy

[^dãykýtự]: Đọc cho đến khi gặp 1 ký tự thuộc dãy.W : chỉ định chiều dài tối đa ký tự cần đọc.Cách đọc trên dòng nhập: có 2 cách

10

Page 11: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 11/65

- Đọc theo ký tự : khi ta sử dụng 1 trong 3 ký tự chuyển dạng: c, [...], [^...]Ví dụ: int a,b;

char s1[10], s2[10];scanf(“%d%[_0123456789]%[^0123456789]%3d”, &a, s1, s2,&b);Với dòng nhập là: 35_13456_XZY_58654thì: a=35; s1=”_13456_”; s2=”XYZ_” ; b=58645.

- Đọc theo từng trường: mỗi trường là một dãy ký tự được kết thúc bằng ký tựtrắng. Cách đọc theo trường phụ thuộc vào [W]Ví dụ: scanf(“%f%5f%3d%d”,&x,&y,&a,&b)

Với dòng nhập là: 54.32e-1 25 1234567Thì các biến sẽ nhận giá trị : x = 54.32e-1; y = 25; a = 123; b = 4567.

Dấu * dùng đọc dữ liệu trên dòng nhập nhưng không lưu vào bộ nhớ. Như vậy,đặt tả chứa dấu * sẽ không có đối số tương ứng.

Ví dụ: scanf(“%d %*c %d”,&x,&y); dữ liệu nhập: “10/20” --> x=10; y=20Ký tự trắng: dùng bỏ qua 1 hay nhiều khoảng trống (như dấu cách, tab, ký hiệu xuống

dòng \n) trên dòng nhập cho đến khi gặp ký tự khác trống.

Ví dụ: scanf(“%d %d “,&a,&b);Dòng nhập phải có 3 trường: 25 12 5 .Khi đó a=25, b=12 còn 5 vẫn còn trên stdin

Ký tự khác ký tự trắng: dùng đọc và bỏ qua ký tự phù hợp trên dòng nhập. Hàm scanf sẽchấm dứt thao tác nếu không tìm thấy ký tự chỉ định

Ví dụ: scanf(“%d / %d”,&x,&y) Nếu dữ liệu nhập là : 10/20 thì x =10; y = 20 Nếu dữ liệu nhập là : 10 20 <Enter> thì a=10 còn y thì không xác định. Do hàm scanf 

dò tìm ký tự / không thấy và số 20 ‘\n’ (10) vẫn còn trên trường vào.Chú ý: int a,b; scanf(“%d”,&a); scanf(“%d”,&b);

nếu nhập: 25 123 <Enter> thì trôi qua lệnh scanf thứ 2 và a = 25, b = 123.

11

Page 12: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 12/65

BÀI 4 : CÁC PHÉP TOÁN & HÀM CƠ BẢN-I Các phép toán-1 Các phép toán số học:(Arithmetic Operators)

C có 7 toán tử số học gồma) 5 toán tử 2 ngôi:

Phép toán Ký hiệu Ví dụ Phép toán Kýhiệu

Ví dụ

Cộng + a + b Nhân * a * bTrừ - a - b Chia / a / b

Lấy phần dư(Modulus)

% n % m

• Phép chia trên 2 số nguyên cho kết quả là 1 số nguyên, cắt bỏ phần thập phânkhông làm tròn số. Ví dụ: 19 / 5 = 3 cắt bỏ 0.8

• Phép chia lấy phần dư chỉ được dùng trên 2 toán hạng kiểu số nguyên (nếu không 

 sẽ sinh lỗi cú pháp) Ví dụ: 19 % 5 = 4• Thứ tự thực hiện các toán tử trong một biểu thức tương tự như trong PascalVí dụ: được viết (b*b - 4*a*c)/(2*d) hay (b*b - 4*a*c)/2/d

b) Hai toán tử 1 ngôi: Dùng tăng giảm các biến nguyên hay thực 1 đơn vịToán tử tăng (++) : ++biến; hay biến++;Ví dụ: ++n; hay n++<==> n = n+1;Toán tử giảm (--): --biến; hay biến--;Ví dụ: --n; hay n--; <==> n = n -1;

Chú ý: Trường hợp sử dụng toán tử này trong một biểu thức thì việc đặt trước hay sau sẽảnh hưởng đến kết quả bài toán:

Đặt trước: nếu muốn thay đổi giá trị cho n trước khi sử dụng nĐặt sau: nếu muốn thay đổi giá trị cho n sau khi sử dụng n xong.Ví dụ: Với n = 4. Lệnh x = ++n sẽ gán 5 cho x. Lệnh x = n++ sẽ gán 4 cho xVí dụ: Với x = 10 và y =11 thì:

 printf(“%d %d %d“, x--*--y, x-- - --y, x++ + ++y);Cho kết quả: 120 0 22

 Nhưng nếu tách thành 3 lệnh printf: printf(“%d “, x--*--y); printf(“%d”, x-- - --y); printf(“%d “, x++ + ++y);

Cho kết quả: 120 -2 20• Độ ưu tiên:Toán tử 1 ngôi có độ ưu tiên cao hơn toán tử 2 ngôi.

-2 Phép chuyển đổi kiểu dữ liệu:Việc chuyển đổi kiểu dữ liệu thường được diễn ra tự động trong 2 trường hợp:• Khi 2 toán hạng trong 1 phép toán khác kiểu thì:

- Kiểu thấp hơn sẽ được nâng thành kiểu cao hơn trước khi thực hiện phéptoán.

- Giá trị thu được có kiểu cao hơnVí dụ: 1.5 * (5/2) ---> 1.5 * 2 = 3.00

1.5 * 5/2 ---> 7.5 / 2 = 3.751.5 * (5/2F) ---> 1.5 * 2.5= 3.75

• Khi gán giá trị kiểu này cho 1 biến kiểu kia: Giá trị của biểu thức vế phải được

chuyển sang kiểu của vế trái và đó là kiểu kết quả.Ví dụ:int n;

n = 10.5; ---> n = 10

12

Page 13: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 13/65

Trong một số trường hợp bạn cần sử dụng phép chuyển kiểu:(type)expression

Phép chuyển kiểu cho ra giá trị thuộc kiểu type chỉ định. Bản thân của expressionthì không thay đổi kiểu.

Ví dụ: Đổi số thực sang số nguyên có làm tròn sốint a; float x;

a = (int)( x + 0.5);x = (float)a / 2; /*nếu a=5 ==> x = 2.5*/

• Độ ưu tiên của toán tử ép kiểu cùng cấp với toán tử một ngôi.-3 Các toán tử quan hệ và logic: (Ralational & logical operators)

Các phép toán quan hệ và logic cho kết quả là 1 (Đúng) | 0 (Sai). Được dùng tạo các biểu thức điều kiện cho việc chọn lựa công việc cần thực hiện.a) Kiểu logic: C không có kiểu logic cụ thể như Pascal, mà xem:

Số <> 0 là True; Số = 0 là False.b) Toán tử quan hệ:

Phép so sánh Ký hiệu Ví dụ Phép so sánh Ký

hiệu

Ví dụ

Bằng == a == b Lớn hơn hoặc bằng >= a >= bKhác != a != b Nhỏ hơn < a < bLớn hơn > a > b Nhỏ hơn hoặc bằng <= a <= b

Độ ưu tiên:• Hai phép toán đầu có cùng độ ưu tiên. Bốn phép toán sau cũng cùng độ ưu tiên

nhưng cao hơn 2 phép toán đầu.• Phép toán so sánh có độ ưu tiên thấp hơn so với các phép toán số học.

Ví dụ: a < b + c <==> a < (b + c)c) Các phép toán Logic:

Các phép toán logic có thể thực hiện trên các toán hạng nguyên hay thực.* Phèp phủ định: ! * Phép Và: && * Phép Hoặc ||Ví dụ: 3 && 7 ---> 1 !1.2 ---> 0 3 || 7 ---> 1

Độ ưu tiên:Các phép toán so sánh có độ ưu tiên nhỏ hơn phép phủ định nhưng lớn hơn phép && và ||.

Ví dụ: (a < b) && (c > d) <==> a < b && c > d-4 Phép toán ? : <điều kiện> ? <biểu thức 1> : <biểu thức 2> ;

Trả về giá trị của <biểu thức 1> nếu <điều kiện> đúng, ngược lại trả về giá trị của<biểu thức 2>Ví dụ: Tìm số lớn nhất trong 2 số bất kỳ nhập từ bàn phím.main(){

float a, b, max;clrscr();

 printf(“\n Nhập số thứ nhất: “);scanf(“%f”,&a); printf(“\n Nhập số thứ hai : “); scanf(“%f”,&b);if (a > b) max = a;else max = b;

 printf(“\n Số lớn nhất là : %f “, max);

getch();}Thì có thể viết: max = (a > b) ? a : b ;

13

Page 14: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 14/65

-5 Phép toán phẩy: (<biểu thức 1> , <biểu thức 2> , ... , <biểu thức n>)Việc thực hiện được thực hiện từ trái sang phải. Kết quả và kiểu dữ liệu của biểu

thức phẩy là của biểu thức ở bên phải <biểu thức n>.Ví dụ: m = ( t = 2, t*t+3 ); t = 2 và m = 7

-6 Phép toán Xử lý Bit:Dùng xử lý đến từng Bit của một số nguyên.

Phép toán Ý nghiã Ví dụa & b Phép AND theo Bita | b Phép OR theo Bita ̂ b Phép hoặc loại trừ (XOR)~ a Lấy phần bù theo Bit

a << n Dịch trái n Bit =a * 2n

A >> n Dịch phải n Bit = a / 2n

Chú ý: Phép chuyển trên giá trị Int bảo toàn bit dấu, thực hiện trên giá trị unsignedint không bảo toàn Bit dấu.

Ví dụ: (-256) << 2 = -1024; (-256) >> 2 = -64.Ví dụ: Để trích Byte thấp và byte cao của một số nguyên:

 b_thap = a & 0xff  b_cao = a >> 8

-7 Thứ tự ưu tiên của các toán tử:ưu tiên Toán tử Thứ tự thực hiện

1 ( ) [ ] . -> Trái sang phải2 ! ++ -- - (type) sizeof Phải sang trái3 * / % Trái sang phải4 + - Trái sang phải

5 << >>6 < <= > >= Trái sang phải7 == != Trái sang phải8 &9 ^

10 |11 && Trái sang phải12 || Trái sang phải13 ? :14 = += -= *= /= %= Phải sang trái

15 , (dấu phẩy) Trái sang phải-IIMột Số Hàm Cơ Bản:-1 Hàm đại số:1) Tính trị tuyệt đối của số nguyên num: int abs(int num); (stdlib.h)2) Tính trị tuyệt đối của số nguyên kiểu long int: long labs(long num); (stdlib.h)

 /* Các hàm sau khai báo trong math.h */ 3) Tính trị tuyệt đối của 1 số thực x: double fabs(double x); (math.h)4) Tìm số nguyên lớn nhất ≤ x: double floor(double x);5) Tìm số nguyên bé nhất ≥ x: double ceil(double x);

6) Tìm phần dư của y/x: double fmod(double y, double x);7) Tính căn bặc 2 của x: double sqrt(double x);8) Tính yx : double pow(double y, double x);

14

Page 15: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 15/65

9) Tính ex : double exp(double x);10)Tính ln(x): double log(double x);11)Tính log10x: double log10(double x);-2 Hàm lượng giác:12)Tính sin(x): double sin(double x);13)Tính cosine của x: double cos(double x);14)Tính tangent của x: double tan(double x);15)Tính arc cosine của (x):double acos(double x);16)Tính arc sine của (x) double asin(double x);17)Tính arc tangent của x: double atan(double x);-3 Hàm xử lý ký tự: <CTYPE.H>1. int tolower(int ch); Trả về chữ thường2. int toupper(int ch); Trả về chữ in hoa3. int islower(int ch); Là chữ thường4. int isupper(int ch); Là chữ in hoa5. int isdigit( int ch); Là số6. int isalpha(int ch); Là mẫu tự7. int isalnum(int ch); Là số hay mẫu tự8. int isspace(int ch); Là dấu cách.

15

Page 16: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 16/65

BÀI 5 : CÁC CẤU TRÚC ĐIỀU KHIỂN-I Cấu trúc chọn:-1 Cấu trúc chọn với if:Cú pháp: if (điều kiện)

<Lệnh>;<Lệnh>: có thể là lệnh đơn hay khối lệnh.

Lưu đồ:

Ví dụ: Xét bài toán tính tiền 1 khách hàng phải trả khi mua hàng với quy tắc giảm giá nhưsau:•  Nếu mua với số lượng > 50 thì được giảm 2%•

 Nếu mua với số lượng > 100 thì được giảm 3%Trong đó đơn giá và số lượng mua được nhập từ bàn phímmain(){

float dongia, soluong, tien; printf(“\n Cho biết đơn giá : “);scanf(“%f”, &dongia);

 printf(“\n Cho biết số lượng: “);scanf(“%f”, &soluong);tien = soluong * dongia;

if (soluong > 50 && soluong <=100)tien = tien * 0.98;

if (soluong >100)tien = tien * 0.97;

 printf(“\nTien phai tra : %10.2f “, tien);getch();

}

Ví dụ: Cần hiện số phần trăm giảm giáif (soluong > 50 && soluong <=100){ tien = tien * 0.98;

 printf(“\n Khách được giảm giá 2% “);}if (soluong >100){ tien = tien * 0.97;

 printf(“\n Khách được giảm giá 3% “);}

1.1Cấu trúc chọn với if/else:

Cú pháp: if (điều kiện)lệnh1;else

lệnh2;Luu đồ:Ví dụ: sử dụng ví dụ tính tiền mua hàng{ ... if (soluong > 50)

tien = tien * 0.98;else

if (soluong >100)

tien = tien * 0.97;......}Ví dụ: Viết chương trình phân loại học sinh theo DTB ( bằng 2 cách)

16

Lệnh ;

Lệnh 1 Lệnh 2

Page 17: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 17/65

Cách 1: Xét bắt đầu từ dtb >= 5main(){

float dtb; printf(“\n Cho biết điểm trung bình : “);scanf(“%f”, &dtb);

if (dtb >= 5 )if (dtb <= 6.5)

 printf(“\n Trung bình”);else

if (dtb <= 8)

 printf(“\n Khá “);else

 printf(“\nGiỏi “);else

if (dtb >= 3.5)

 printf(“\n Yếu “);else

 print(“\n Kém “);getch();

}Cách 2: Xét bắt đầu từ dtb >=8.5Chú ý: Các lệnh if..else lồng nhau thì else sẽ luôn luôn kết hợp với if nào chưa có else gầnnhất.Ví dụ:if (n >0)

if (a > b)z = a;

elsez = b;

if (n >0)if (a > b)

z = a;else

z = b;

if (n >0){if (a > b)

z = a;}else

z = b;-2 Cấu trúc chọn với switch:

switch (biểu thức){

case hằng1: <Công việc 1>;break;

case hằng2: <Công việc 2>;break;

.............case hằngn: <Công việc n>;

break;[default : Công việc n+1;]

}Diễn giải:

Các hằng i  phải là số nguyên. Nếu Biểu thức là số thực sẽ được chuyển sang kiểu nguyênGiá trị của biểu thức sẽ lần lược so sánh với các hằngi . nếu biểuthức == hằngi thì lệnhi

sẽ được thực hiện. Ngược lại thì lệnh tương ứng với từ khóa default sẽ được thực hiện (nếucó).

Sau khi máy thực hiện lệnhi nếu sau lệnhi không có lệnh break thì máy sẽ tiếp tục thựchiện các lệnhi+1,.. cho tới khi gặp lệnh break hay kết thúc lệnh.

Lệnh break cho phép thoát khỏi vòng lặp For, while, do while hoặc lệnh switch.Ví dụ 1: (máy tính bỏ túi) Nhập vào 2 số và 1 phép toán (+,-,*,/). Hãy in ra giá trị của biểu

thức đó.Ví dụ 2: Biết tháng và năm. Hãy tính số ngày trong tháng đó.main(){

int thang, nam; printf(“\nCho biết tháng: “);scanf(“%d”,&thang); printf(“\nCho biết năm: “);scanf(“%d”,&nam);songay = 0;

17

Page 18: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 18/65

switch (thang){

case 1: case 3: case 5: case 7: case 8: case 10:case 12: songay = 31; break;case 4:case 6:case 9:case 11: songay = 30; break;

case 2:if (nam % 4 == 0) songay = 29;else songay = 28;

 break;default: printf(“\nNhap thang sai “);

}if (songay >0) printf(“\nThang %d nam %d co %d ngay”,thang, nam, songay);getch();

}-IICấu trúc Vòng LặpMục đích: Thực hiện công việc lặp đi lặp lại theo một qui luật nào đó. Số lần lặp có thể xác

định trước hoặc không thể xác định được.-1 Cấu trúc lặp với điều kiện trước: (câu lệnh While)

Cú pháp : while (Điều kiện) <công việc>;Ngữ nghĩa: TRONG KHI điều kiện còn đúng thì thực hiện công việc.Diễn giải: Trong khi <Điều kiện> còn đúng thì còn thực hiện <lệnh>. Vòng lặp kết

thúc khi <Điều kiện> sai.Ví dụ 1: Tìm USCLN của hai số nguyên dương m và n. Theo nguyên tắc:

 Nếu m=n : thì UCLN(m,n) = m Nếu m > n : UCLN(m,n) = UCLN(m-n,n) Nếu m<n : UCLN(m,n) = UCLN(m,n-m)

Ví dụ: n= 35 m= 84 thì UCLN là 7.while (m<> n)

if (m>n) m:=m-n; else n:=m-n;Ví dụ 2 : Lãi suất hàng tháng gửi tiết kiệm không kỳ hạn là 1.2%. Một người gởi vào mộtsố tiền ban đầu là a. Sau bao nhiêu tháng người đó đạt số tiền không nhỏ hơn b?Ý tưởng: - Số tiền gởi đầu tháng là a

- Cuối tháng số tiền thu được gồm tiền đầu tháng cộng tiền lãi (a+a*k). Đócũng là tiền gởi tiết kiệm cho đầu tháng sau.

main(){ double a, b, c;

int dem = 0; printf(“\n Nhap tien goi ban dau: “);scanf(“%lf”, &a);while (a <= 0){

 printf(“\nHay nhap lai tien goi:“);scanf(“%lf”, &a);

} printf(“\n Nhap so tien dự kiến : “);scanf(“%lf”,&b);while (b <= a)

{ printf(“\nNhap lai tien dự kiến:“);scanf(“%lf”,&b);

}c = a;while (c < b){

c = c + c*0.012;dem++;

} printf(“\nPhải gởi %d thang”,dem);getch();

}Chú ý:

- Vòng lặp không thực hiện lần nào: khi lần đầu tiên <điều kiện> có giá trị 0.

18

Page 19: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 19/65

- Vòng lặp không dừng: khi <điều kiện> luôn luôn khác 0.Ví dụ: 100 trâu 100 cỏ, trâu đứng ăn 5, trâu nằm ăn 3, lụ khụ trâu già 3 con 1 bó.Hỏi mỗi

loại có mấy con?HD: a:=1 to 100 div 5; b:=1 to 100 div 3;

nếu a*5+b*3+(100-a-b)/3=100 thì a, b, (100-a-b) div 3 là kết quả#include "stdio.h"

main(){ int td, tn, tg;

printf("\nBai toan dem trau");td = 1;while (td < 100/5){ tn = 1;

while (tn < 100/3){ if (td*5 + tn*3 + (float)(100-td-tn)/3 == 100)

{ tg = (100-td-tn);printf("\n trau : %d, %d,%d ",td,tn,tg);

}

tn++;}td++;

}getch();

}

-2 Cấu trúc lặp với điều kiện sau: do .. whileCú pháp: 

do {<công viêc lặp>

} while ( biểu thức);Ngữ nghiã: Dùng lặp đi lặp lại một công việc trong khi biểu thức điều kiện còn đúng(khác 0) và thoát khi biểu thức điều kiện sai ( bằng 0)

Chú ý: Thân vòng lặp được thực hiện ít nhất 1 lầnVí dụ: Viết chương trình tính trung bình cộng của n số nguyên nhập từ bàn phím. Khi nàonhập số 0 thì kết thúc nhập và tính trung bình.main(){ int so, tong=0, n = 0;

float tb;clrscr();

do{ printf(“\nNhap 1 so :”);scanf(“%d”, &so);tong += so;

n +=1;} while (so != 0);n -= 1;tb = (float) tong / n;

printf(“\nBan da nhap vao : %d so”,n);printf(“\nTrung binh cong = %f”,tb);getch();

}

Ví dụ : Nhập số thực Eps ∈(0,1). Tính số Népè e (= 2,71828) bằng công thức khai triểnchuỗi như sau: e = 1 + 1/1! + 1/2! + ..+ 1/N! cho đến khi 1/(N+1)! < Eps .

HD: Dùng thuật toán cộng dồn với một biến chạy i từ 1 trở đimain(){ double e = 1; i =1; x = 1, eps;

do { printf (“\n Nhâp số Epsilon: “); scanf (“%lf”, &eps);

} while ( eps >=1 || eps <=0 );do {e := e + 1/x; /* hay e += 1/x ; */

19

Page 20: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 20/65

i++; x = x * i; /* hay x = x *++i; */ /*hay x *= ++i */} while (1/ x >= eps);

 printf(“\nSo e = %.10lf “, eps);}-3 Cấu trúc lặp với for :

Vấn đề: Lãi suất hàng tháng gưỉ tiền không kỳ hạn là k%. Một người gởi vào một số

tiền ban đầu là a. Tính tiền người đó có được sau t tháng.Diễn giải: Tiền lãi tháng = tiền gởi đầu tháng * k %

Tiền gởi đầu tháng sau= tiền gởi đầu tháng trước + tiền lãi thángCú pháp:

for ( biểu thức 1; biểu thức 2; biểu thức 3)lệnh;

Biểu thức 1: Thường là 1 phép gán để tạo giá trị ban đầu cho biến điều khiểnBiểu thức 2: là  biểu thức điều kiệnBiểu thức 3: là phép gán dùng thay đổi giá trị của biến điều khiển.

Ví dụ: Viết chương trình tính N! trong đó N là số nguyên dương nhập từ bàn phím.main(){ double gt = 1, ;

unsigned int n, i; printf(“\nTinh giai thua cua : “);scanf(“%u”, &n);

for (i = 1; i <= n ; i++)gt = gt * i ; /* gt *= i */

 printf(“\nN! = %.0lf “,gt );getch();

}Chú ý: 

Biểu thức 1 chỉ được thực hiện 1 lần (lần đầu)Biểu thức 2, biểu thức 3 và thân vòng For được thực hiện nhiều lần.Bất kỳ biểu thức nào trong 3 biểu thức trên đều có quyền vắng mặt, Tuy nhiên vẫn

 phải giữ dấu “; “Ví dụ : Vắng biểu thức 1 và 3main(){ double gt = 1 ;

unsigned int n, i =0; printf(“\nTinh giai thua cua : “);

scanf(“%u”, &n);for ( ; ++i <= n ; ) gt *= i ;

 printf(“\nN! = %.0lf “,gt );}

 Nếu không có biểu thức 2 hay biểu thức 2 là 1 hằng số khác 0 thì vòng lặp thực hiện vôtận. Khi đó muốn thoát khỏi vòng lặp phải dùng lệnh break, goto nhan, return(biểuthức),exit(mã thoát).Ví dụ : Vắng biểu thức 1, 2 và 3

main(){double gt = 1 ;unsigned int n, i = 1;

 printf(“\nTinh giai thua cua : “);scanf(“%u”, &n);

for ( ; ; ){ gt = gt * i ; /* gt *= i */if (++i > n) break ;

} printf(“\n Ket qua %u! = %.0lf “, n, gt );

}

Mỗi biểu thức có thể gồm 1 dãy biểu thức con cách nhau bởi dấu phẩy “,” và đượctính toán từ trái qua phải. Nếu biểu thức 2 là 1 dãy các biểu thức thì tính đúng sai của biểu thức 2 được xác

định bởi giá trị của biểu thức cuối cùng trong dãy này.Ví dụ : Vắng biểu thức 1 và 3 và thân vòng lặp là rỗng.main()

20

Page 21: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 21/65

{ double gt = 1 ;unsigned int n, i =1;

 printf(“\nTinh giai thua cua : “); scanf(“%u”, &n);for ( ; gt = gt * i, ++i <= n ; ) ; /* for ( ; i <= n ; gt = gt * i++) ; */

 printf(“\nN! = %.0lf “,gt );}

Ví dụ: Lãi suất hàng tháng gửi tiết kiệm theo chế độ có kì hạn 3 tháng là 2%( tức là cứ 3tháng người ta lấy số tiền hiện có nhân với lãi suất 2% 1 tháng để ra lãi, rồi cộng lãivới vốn để có vốn mới). Một người gởi vào 1 số tiền ban đầu là a. Tính số tiền ngườiđó có được sau t tháng.

 HD : Số lần tính lãi là : t % 3. Tiền vốn có được sau mỗi lần tính lãi : a + a*3*2%Ví dụ 3: Tìm tất cả các số có 3 chữ số abc sao cho tổng lập phương của các chữ số thì bằng

chính số đó. { 153, 370, 371, 407 }abc =100a + 10b + c = a3 + b3 + c3

 Hướng Dẫn: a lấy giá trị 1..9; b và c lấy giá trị từ 0..9-IIICác Câu Lệnh Khác:-1 Lệnh goto:Công dụng: Dùng chuyển điều khiển thực hiện đến 1 câu lệnh nào đó được chỉ định bởi

nhãn.Cú pháp: goto nhan;

Trong đó, nhan là 1 tên hợp lệ được đặt trước lệnh cần nhẩy đến:nhan: lệnh;

Chú ý: Không dùng lệnh goto để nhẩy từ ngoài vào trong 1 khối lệnh, nhưng cho phépnhẩy từ trong khối lệnh ra ngoài.Ví dụ: Để thoát khỏi thân While, bạn có thể dùng 1 trong các câu lệnh sau:

+ Break;+ goto nhãn;

Ví dụ:Thoát vòng lặp vô tận với break c = a;while (1){ if (c >= b) break;

c = c + c*0.012;dem++;

} printf(“\nBan phai goi %d thang”,dem);

Ví dụ: Thoát vòng lặp vô tận với goto nhãn;c = a;while (1){ if (c >= b) goto kq;

c = c + c*0.012;dem++;

}kq: printf(“\nBan phai goi %d thang”,dem);

Ví dụ: Viết chương trình tính N! trong đó N là số nguyên dương nhập từ bàn phím.main(){ double gt = 1 ;

unsigned int n, i = 1; printf(“\nTinh giai thua cua : “);scanf(“%u”, &n);for ( ; ; )

{ gt = gt * i ; /* gt *= i */if (++i > n) goto ketthuc;

}ketthuc: 

 printf(“\n %u! = %.0lf “, n, gt );}

Lệnh goto kết hợp với lệnh if cũng có thể tạo thành 1 cấu trúc lặp như sau:main(){ double gt = 1 ;

unsigned int n, i = 1; printf(“\nTinh giai thua cua : “);scanf(“%u”, &n);laplai: gt = gt * i; /* hay gt *= i */

i = i + 1;if ( i > n ) goto ketthuc;else goto laplai;ketthuc: printf(“\n Ket qua %u! =

%.0lf “, n, gt );}

21

Page 22: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 22/65

Nhận xét: Hạn chế sử dụng lệnh goto vì khó theo dõi việc thực hiện chương trình.-2 Lệnh continue:Công dụng: Được sử dụng trong thân các cấu trúc lặp. Dùng chuyển điều khiển giữa

chừng về đầu vòng lặp, chuẩn bị cho lần lặp mới.Đối với for: Máy sẽ thực hiện biểu thức3, rồi thực hiện biểu thức 2, sau đó thực hiện lần

lặp mới nếu biểu thức 2 là đúng.

Đối với while và do .. while: máy sẽ chuyển tới xác định biểu thức sau while và thựchiện lần lặp mới nếu biểu thức 2 là đúng.Ví dụ: Viết chương trình tính trung bình cộng của n số nguyên dương nhập từ bàn phím.Khi nào nhập số 0 thì kết thúc nhập và tính trung bình.main(){ int so, tong=0, n = 0;

float tb;clrscr();do{ printf(“\nNhap 1 so :”);

scanf(“%d”, &so);if (so <= 0) continue;

tong += so;n +=1;

} while (so != 0);tb = (float) tong/n;

 printf(“\nBan da nhap vao : %d so”,n); printf(“\nTrung binh cong = %f”,tb);

getch();}

22

Page 23: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 23/65

Page 24: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 24/65

-IIĐỊNH NGHIÃ VÀ SỬ DỤNG HÀM TỰ TẠO:-1 ĐỊNH NGHIÃ HÀM:

Hàm được định nghiã dựa trên cấu trúc sau:Cấu trúc Hàm:

kiểukếtquả tênhàm(danh sách đối số){ Khai báo biến cục bộ

các câu lệnh[return [biểu thức];]

}• tênhàm: được đặt theo qui tắc đặt tên biến và phải khác nhau trong cùng 1 chương trình.• Kiểu kết quả của hàm: Nếu hàm cần trả về 1 giá trị thì phải khai báo kiểu của giá trị đó.

 Nếu hàm không trả về một giá trị thì dùng kiểu void. Nếu kiểu kết quả là kiểu int thì có thể bỏ qua phần khai báo kiểu.

• Lệnh return: Dùng để thoát khỏi hàm và trở về nơi gọi hàm. Nếu có (biểuthức) thì giá trịcủa biểu thức sẽ là giá trị của hàm.

• Danh sách đối số: là các biến cục bộ mà giá trị của chúng sẽ được cung cấp trong lời gọi

hàm. Các đối số chỉ được sử dụng bên trong thân hàm. Nếu hàm không có đối số thì thaythế danh sách đối số bằng void.

• Tên Biến cục bộ và tham số hình thức phải khác nhau vì có cùng phạm vi sử dụng là trongthân hàm. Nhưng có thể trùng tên với các biến bên ngoài hàm.

• Thân hàm: được bắt đầu bằng dấu { và kết thúc bằng dấu }.-2 GỌI HÀM:

Hàm có thể được gọi thực hiện trong các biểu thức hoặc có thể thực hiện như một lệnhđộc lập. tên_hàm([danh sách tham số])

Danh sách tham số theo thứ tự phải phù hợp với kiểu của đối số.-3 TRUYỀN THAM SỐ CHO HÀM:

Việc khai báo các đối số cho hàm nhầm mục đích tính toán, thao tác trên nhiều dữ liệukhác nhau

Ví dụ: long giaithua(int n): dùng tính giai thừa cho nhiều giá trị n khác nhauCác đối số sẽ nhận các giá trị từ các tham số khi hàm được gọi thực hiện. Có 2 cơ chế

truyền tham số cho hàm.a) Truyền tham trị:

Đối số được cấp phát vùng nhớ riêng để chứa giá trị của tham số tương ứng. Việc thayđổi giá trị của đối số không làm thay đổi giá trị của tham số.

void Thu(int a, int b){ int c;

a = 5; b = 6; c = 7; d = 8; printf(“Trong ham thu: %d %d %d %d”, a, b, c, d);

}main(){ int a = 1, b = 2, c = 3, d = 4;

 printf(“ Truoc khi goi ham thu: %d %d %d %d”, a, b, c, d);Thu(a,b);

 printf(“Sau khi goi ham thu: %d %d %d %d”, a, b, c, d);

Page 25: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 25/65

}b) Truyền Tham chiếu:

Đối số thực chất là một tên mới của tham số (còn gọi là bí danh). Do đó, việc thay đổigiá trị của đối số sẽ ảnh hưởng trực tiếp giá trị của tham số.

Ví dụ: void Thu(int a, int &b)Ví dụ:

int a, b, c;void Thu(int d, int &e, int c){ int a;

a =c+1; e = a+c; c = c*2; printf(“Trong ham thu: %d %d %d %d %d”, a, b, c, d, e);

}main(){ a =2; b = 4; c = 6;

 printf(“ Truoc khi goi ham Thu: %d %d %d ”, a, b, c);Thu(b, c, a);

 printf(“ Sau khi goi ham Thu: %d %d %d ”, a, b, c);}Ví dụ Viết chương trình giản ước 1 phân số, có sử dụng 1 hàm tính ước số chung lớn nhất của

2 số.void nhap_phan_so(int &, int &);void toigianps(int &, int &);int ucln(int , int );main(){

int a, b; NhapPhanSo( a, b);toigianps(a,b);

 printf(“\nSau khi giản ước: %d/%d”,a,b);}/*-------------------------------*/int ucln(int a, int b){int m,n,r;

m = abs(a); n = abs(b);while (n != 0){ r = m%n; m = n; n = r ; }

return m;}void toigianps(int &tu, int &mau){

long int usc;usc = ucln(tu,mau);tu = tu/usc;mau = mau/usc;

Page 26: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 26/65

}/*=========================*/void nhap_phan_so(int &x, int &y){

do{ printf("\nNhap phan so (x/y) : ");

scanf("%d %*c %d", &x, &y); fflush(stdin);if ( y == 0) printf("\nMau so bang 0");else

if (x < 0 && y < 0){ x = abs(x);

y = abs(y);}

elseif (x*y<0)

{ x = -abs(x);

y = abs(y);}} while (y == 0);

}-IIITÍNH ĐỆ QUI CỦA HÀM:-1 Khái niệm:

Một đối tượng X gọi là được định nghiã đệ qui nếu trong định nghiã của X có sử dụngtrực tiếp hay gián tiếp ngay chính khái niệm X.

Ví dụ: Định nghiã phép toán giai thừa(a) 0! = 1! = 1

(b) nếu n > 1 thì n! = n*(n-1)!Ví dụ: Định nghiã UCLN của 2 số x và y :(a)UCLN(x,y) = x nếu y = 0(b)UCLN(x,y) = UCLN(y, phần dư của x/y) nếu y<>0

* Nhận xét: Một định nghiã đệ qui phải có 2 thành phần:- Thành phần dừng (Không chứa khái niệm đang định nghiã)

Ví dụ: 0! = 1! = 1- Thành phần đệ qui (có chứa khái niệm đang định nghiã)

ví dụ: n! = n*(n-1)! nếu n > 1Hàm đệ qui: Một hàm là một sự định nghiã về một công việc nào đó, nên cũng có thể là

đệ qui: Nếu trong CTC P có lời gọi tường minh đến chính nó thì gọi là đệ qui trực tiếp Nếu trong P có gọi ctc Q, và trong Q lại có lời gọi P thì P được gọi là đệ qui gián

tiếp.Khi hàm gọi đệ qui đến chính nó thì mỗi lần gọi, máy sẽ tạo ra một tập biến cục bộ mới

hoàn toàn độc lập với tập biến cục bộ của hàm trước đó.Cũng như các lệnh lặp, các thủ tục đệ qui cũng có thể thực hiện các tính toán không

dừng, vì thế cần chú ý vấn đề kết thúc.Ví dụ: Xây dựng hàm tính n! theo đệ qui.

Page 27: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 27/65

long gt(int n){

if (n <= 1) return 1;else return (n * gt(n-1));

}Ví dụ: Tính UCLN(x,y) theo thuật toán Euclide

int UCLN(int x, int y){if (y == 0) return x;else return (ucln(y, x % y));

}Ví dụ: Dãy số Fibonacci được xác định như sau: F0=1; F1=1; Fn=Fn-1+Fn-2 với n>=2.Hãy xác định phần tử thứ n của của dãy số.int Fibo(int n){ if (n == 0 || (n == 1) return 1;else return (fibo(n - 1) + fibo(n - 2));

}Ví dụ : Bài toán Tháp Hà Nội (Tower of HaNoi)Có 3 cột A, B, C và 64 điã kích thước khác nhau ở cột A, điã lớn ở dưới, điã nhỏ ở trên.

Hãy chuyển các điã từ A sang C sao cho :- mỗi lần chỉ được chuyển 1 điã- ở các cột tình trạng điã luôn luôn là điã lớn ở dưới, điã nhỏ ở trên.Chúng ta giải bài toán theo kiểu giải quyết từ trên xuống (Top Down) như sau:Để chuyển n điã từ A ---> C: làm cách nào đó ta chuyển n-1 điã từ A -->B, sau đó

chuyển điã lớn nhất còn lại từ A ---> C. Và rồi lại làm cách nào đó chuyển n-1 điã từ B --> CThuật toán: Chuyển n điã từ A sang C, lấy B làm trung gianBắt đầu:

 Nếu n > 0- chuyển n-1 điã từ A sang B, lấy C làm trung gian- chuyển 1 điã từ A sang C- chuyển n-1 điã từ B sang C, lấy A làm trung gian/*Program ThapHaNoi;*/typedef char cot; {có 3 cột ‘A’, ‘B’, ‘C’}char n;void main(){

 printf(“Nhap so đia: “);

scanf(“%d”, &n);Doicot(n,’A’,’B,’C’);getch();

}void Doicot(char n ,cot A, cot B, cot C ){ if ( n > 0 )

{doicot(n-1,A,C,B);

Page 28: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 28/65

 printf(“\n chuyen 1 dia tu %c sang %c”, A,C);doicot(n-1,B,A,C);

}}

 Nhận xét: Số lần chuyển điã : 20 + 21 + ... + 2n-1 = 2n -1 Nếu 1 lần chuyển 1 điã mất 1/100 giây thì cần đến 24 tỷ năm

Ví dụ đệ qui gián tiếp: Một con ếch từ đáy giếng leo lên miệng giếng. cứ leo lên 3m thì tụt lại1 m. Đếm số lần tiến, số lần lùi khi ếch lên được mặt giếng.int z, t, l ;void Lui(int &x);void Tien(int &y){ if ( y > 0)

{y = y - 3;t = t + 1;Lui( y );

}}void Lui(int &x){ if ( x > 0 )

{ x = x + 1;l = l + 1;Tien( x);

}}main(){ t = 0; l = 0; z = 5; Tien( z );

 printf(“\nso lan tien: %d”,t); printf(“\nso lan lui: %d”, l );

}

Page 29: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 29/65

BÀI 7 : QUẢN LÝ THIẾT BỊ-I QUẢN LÝ MÀN HÌNH VÀ CỬA SỔ:

Trong phần này giới thiệu một số hàm dùng thay đổi màu sắc, di chuyển con trỏ, vàtạo cửa sổ nhập xuất văn bản đã được khai báo trong CONIO.H-1 Chọn Kiểu Màn Hình Văn Bản:

Mặc định, màn hình gồm 80 cột (đánh số từ 1 đến 80), 25 dòng (đánh số từ 1 đến25). Để thay đổi số cột và số màu cần hiển thị ta dùng hàm chọn kiểu màn hình như sau:

void textmode(int mode);Biến mode có thể chứa các giá trị sau:

Tên hằng Giá trị Kiểu màn hìnhLASTMODE 1 kiểu màn hình trước đóBW40 0 đen trắng 40 cộtC40 1 16 màu, 40 cộtBW80 2 đen trắng 80 cột

C80 3 16 màu, 80 cộtMONO 7 đơn sắc, 80 cột.Ví dụ: textmode(C80) --> định kiểu màn hình văn bản là 16 màu, 80 cột, 25 dòng.

textmode(C40) --> định kiểu màn hình văn bản là 16 màu, 40 cột, 25 dòng, chữ rộnggấp đôi chế độ 80.

-2 Tạo Cửa Sổ Văn Bản:void window(int xt, int yt, int xd, int yd);

-3 Quản Lý Con Trỏ Màn Hình:- gotoxy(X, Y) : Di chuyển con trỏ màn hình đến vị trí (X,Y). (1..80, 1..25)- int wherex(void) : Trả về vị trí cột hiện hành.

- int wherey(void) : Trả về vị trí cột hiện hành.Ví dụ:void WriteXY(int x,y, char ch){ int x1, y1;x1 = wherex(); y1 = wherey();gotoxy(x,y);cprintf(“%d”,ch);gotoxy(x1, y1);}

-4 Đặt Màu Nền Và Màu Chữ:

a. Các Hằng Định Màu:BLACK (0); BLUE(1); GREEN(2); CYAN(3); RED(4); MAGENTA(5);BROW(6); LIGHTGRAY(7); DARKGRAY(8); LIGHTBLUE(09);LIGHTGREEN(10); LIGHTCYAN(11); LIGHTRED(12); LIGHTMAGENTA(13);YELLOW(14); WHITE(15); BLINK(128): Nhấp nháy.

b. void textcolor(int Newcolor): Đặt màu văn bản màn hình.Ví dụ: textcolor(RED + BLINK)

c. void textbackground(int Newcolor): Đặt màu nền màn hình.d. void textattr(int Newcolor): Thay đổi nhanh màu chữ màu nền. từ bít 0-3 (0-15) màu

chữ, bít 4-6 (16<= ...<128) màu nền, bit 7 nhấp nháy.

TEXTATTR(<MÀU CHỮ>+MÀU NỀN*16 );-5 Các Hàm Xóa Dữ Liệu Trên Màn Hình Hoặc Cửa Sổ:• clrscr(): xóa dữ liệu trên màn hình và cửa sổ theo màu nền hiện hành.

Page 30: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 30/65

• clreol(): Xóa đến cuối dòng• delline(): Xóa dòng hiện hành.• void gettextinfo(struct text_info *r);

Dùng lưu kiểu hiển thị văn bản hiện tại vào biến cấu trúc kiểu text_info.r là con trỏ tới biến cấu trúc kiểu text_info đã được định nghiã trong conio.h như

sau:struct text_info{ unsigned char winleft, wintop, winright, winbottom;

unsigned char attribute, normattr;unsigned char currmode;unsigned char screenheight, screenwidth;unsigned char curx, cury;

}Ví dụ: struct text_info mh;

gettextinfo(&mh); /* Lưu kiểu màn hình hiện hành*/textbackground(mh.attribute % 16); /*Phục hồi màu nền*/textcolor(mh.attribute / 16); /*phục hồi màu chữ*/

-6 Nhập Xuất Dữ Liệu Theo Màu Chỉ Định:a. Nhập Dữ Liệu:• int cscanf (“chuổi điều khiển”, danh sách địa chỉ các biến);• int getch(void);

 Nhận 1 ký tự từ bộ đệm bàn phím, không cho hiện trên màn hình. Nếu bộ đệm rỗngthì chờ ấn 1 phím bất kỳ.

 Nếu phím được ấn là phím chức năng thì trả về ký tự ‘\0’ và ghi vào buffer bàn phím1 ký tự đại diện.

Ví dụ : Home: #71(G); Up: 72(H); Down: 80(P); Left: 75(K); Right: 77(M)...Ví dụ: Trình bày Mã ASCII của phím chức năng và ký tự tượng trưng của phím.Program Kiem_tra_phim;#include <CONIO.H>char ch;main()

{ printf(“\nKiem tra phim, Nhan ESC để kết thúc”);do { printf(“\nBan hay an một phim hay tổ hợp phím: ”);

ch =getch();if (ch == 0) then

{ ch = getch(); printf(“La Phim chuc nang có mã: %d cua ky tu %c”, ch, ch);} else printf(“\nPhim vua an co ma: %d”, ch );

} while (ch != 27);}

• int getche(void); nhận 1 ký tự từ bộ đệm bàn phím , cho hiện trên màn hìnhVí dụ: ch = getche()

• int kbhit(void): cho biết số ký tự hiện có trong bộ đệm bàn phím. Bằng 0 nếu bộ đệmrỗng.Chú ý: Bạn có thể dùng kbhit() và getch() để xóa bộ đệm bàn phím.

/* Nếu bạn có bấm 1 số phím khi máy đang reo thì các ký tự đó sẽ hiện ra khi kếtthúc reo */#include “conio.h”

30

Page 31: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 31/65

void main(){ int n,ch;

clrscr();while (n > 0){ --n; putch(7); }while (kbhit()) { ch = getch(); putch(ch);

}

b. Xuất dữ liệu ra bộ nhớ màn hình:• int cprintf (“chuổi điều khiển”, danh sách biểu thức);• int putch(int ch);

Xuất ký tự ra cửa sổ văn bản màn hình theo màu đã xác định bởi hàm textcolor (cáchàm trên stdout như printf, putchar luôn hiển thị ký tự theo màu trắng). Hàm trả về ký tựđược hiển thị.

#include <stdio.h> #include <conio.h>#define Len 20char cn[3][Len] = { "Menu 1", "Menu 2", "Thoat"};int scn = 3;void SetItem(int x1,int y1,int x2,int y2,char Caption[],int color){ struct text_info m;

gettextinfo(&m);window(x1,y1,x2,y2); textattr(color); clrscr();cprintf("%s",Caption); textattr(m.attribute);

}void ActiMenu(int x, int y, char cn[3][Len],int scn, int &chon){ int i; char phim; struct text_info m;

gettextinfo(&m);for (i=0; i<scn; i++)

SetItem(x,y+i,x+Len,y+i,cn[i],BLUE+16*YELLOW);do{ SetItem(x,y+chon,x+Len,y+chon,cn[chon],WHITE+16*GREEN);

 phim=getch();if (phim == 0) phim= getch();SetItem(x,y+chon,x+Len,y+chon,cn[chon],BLUE+16*YELLOW);switch (phim){ case 72:if (chon==0) chon = scn-1;

else chon--; break;case 80:if (chon==scn-1) chon = 0; else chon++;

}}while (phim != 13 && phim != 27);if (phim==27) chon=scn-1;window(m.winleft,m.wintop,m.winright,m.winbottom);textattr(m.attribute);

clrscr();}void main(){ int chon;

textattr(WHITE+16*BLACK); clrscr();

chon=0;ActiMenu(1,3,cn,scn,chon); printf("chon = %d",chon);

31

Page 32: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 32/65

getch();}

-IITẠO SỐ NGẪU NHIÊN:Được khai báo trong stdlib.h và kết hợp với Time.h

1. void randomize(void); Khởi động bộ tạo số ngẫu nhiên2. int random(int n); Cho 1 giá trị ngẫu nhiên từ 0 đến n-13. void srand(unsigned seed); Khởi động bộ số tạo số ngẩu nhiên cho hàm rand(). Nhưng

cho phép trả về cùng số ngẫu nhiên với cùng khởi điểm seed.4. int rand(void); Cho 1 giá trị ngẫu nhiên từ 0 đến 32767.

#include <stdlib.h> #include <stdio.h> #include <time.h>void main(void){ int i;

time_t t; //srand((unsigned) time(&t));printf("Ten random numbers from 0 to 99\n\n");

for(i=0; i<10; i++){ srand(i%4);

 printf("%d\n", rand() % 100);}

}-IIIGIỜ HỆ THỐNG: <Dos.h>1. Kiểu time: struct time {

unsigned char ti_hour, ti_min, ti_sec, ti_hunt;};

2. Lấy giờ hệ thống: void gettime(struct time *t );3. Đặt giờ hệ thống: void settime(struct time *t );Ví dụ: Chương trình luyện tập bàn phím: Hiển thị ngẫu nhiên 1 ký tự, người chơi phải gỏ

ngay ký tự đó, nếu quá thời gian qui định thì tăng điểm lỗi.long ptramgiay(){struct time t;gettime(&t);return (((t.ti_hour*3600)+ t.ti_mic*3600)+t.ti_sec)*100+t.ti_hunt;void main(){

int i, soloi;

char ch, ktgo;for (i=1; i<= sokytu; i++){ ch = random(26)+65;

gotoxy(20+i, dong); putchar(ch);tgbd = ptramgiay();while (1){ tghh =ptramgiay();if (tghh-tgbd>tgcho){ soloi++; gotoxy(20+i, dong); putchar(' '); break; }if (kbhit())

{ ktgo = toupper(getch());gotoxy(20+i, dong+1); putchar(' ');if (ktgo != ch)

32

Page 33: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 33/65

{ soloi++; gotoxy(20+i, dong+2); putchar(ch); } break;

}}

}gotoxy(20, 15);

 printf("So Loi : %d", soloi);}

-IVÂM THANH: <DOS.H>1. sound(tần số: word): Phát âm thanh theo tần số xấp xỉ.2. nosound() : Tắt bộ phát âm;3. void delay(int n): dừng thực hiện chương trình n mili giây4. void sleep(int n); Tạm dừng trong n giây

Các tần số sau tương ứng với cao độ của các nốt nhạc trong bát độ trung bình, muốn lấy bát độ thấp hơn thì chia 2, cao hơn thì nhân 2:

DO=523;DO#=554;Re=587;Re#=622;Mi=659;Fa=698;Sol=784;Sol#=831;La=880;La#=932;Si=988

Ví dụ: /*Program CON_CO;*/#include "dos.h"#include "stdio.h" #include "conio.h" #include "stdlib.h" #include “string.h”const int do1=262,re1=294,mi1=330,fa1=349,sol1=392,la1=440,si1=494,

do2=523,re2=587,mi2=659,fa2=698,sol2=784,la2=880,si2=988,m3=1,m2=2,m1=4,m1c=6,d=8,dc=12,t=16,tr=32;

int tempo;void vekhungdon(int x1, int y1,int x2,int y2,int color){ int i;

textattr(color); gotoxy(x1,y1); cprintf("%c",218);for (i=x1+1;i<=x2-1;i++){ gotoxy(i,y1); cprintf("%c",196); gotoxy(i,y2); cprintf("%c",196);}gotoxy(x2,y1); cprintf("%c",191);for (i=y1+1;i<=y2-1;i++){ gotoxy(x1,i); cprintf("%c",179); gotoxy(x2,i); cprintf("%c",179);}gotoxy(x1,y2); cprintf("%c",192); gotoxy(x2,y2); cprintf("%c",217);

}void note(int tanso, int tg,char *loi){ if (strlen(loi)!=0) cprintf("%s ",loi);

sound(tanso);delay(tg*tempo); nosound();}void main(void)

{ textbackground(BLACK); clrscr(); vekhungdon(20,5,60,20,WHITE+GREEN*16);randomize(); tempo=2200; window(21,6,59,19);textbackground(BLUE); clrscr();note(do2,m1c,"con"); note(re2,m2,"");

note(sol1,d,"co"); note(sol1,m1,"co");note(do2,m1,"bay");note(sol1,m1,"la");note(do1,m1,""); note(sol1,m2,"la");

33

Page 34: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 34/65

note(do2,m2,""); note(la1,m2,"bay");note(sol1,m2,""); note(la1,dc,"la");note(la1,m2,"bay"); note(sol1,m2,"");note(fa1,d,"tu"); note(fa1,m1,"tu");note(fa1,m2,"cua"); note(sol1,m2,"");note(do2,dc,"phu"); note(la1,m2,"bay");

note(sol1,m2,""); note(la1,d,"ra");note(la1,m1,"ra"); note(la1,m1,"canh");note(fa1,d,"dong"); note(fa1,m1,"tinh");note(la1,m2,"tinh"); note(do2,m2,"");note(la1,d,"tang"); note(la1,m1,"tang");note(la1,m2,"tinh"); note(do2,m2,"");note(fa1,d,"tinh");

}

34

Page 35: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 35/65

BÀI 8: KIỂU MẢNG (ARRAY)-I KHÁI NIỆM:

Mảng là 1 tập hợp nhiều biến nhớ có cùng kiểu, có cùng tên gọi và được cấp phátnhững vị trí liên tục trong bộ nhớ.

Mỗi phần tử trong mảng được xác định dựa trên tên mảng và chỉ số xác định vị trícủa phần tử trong mảng. Số lượng chỉ số dùng để xác định 1 phần tử trong mảng được gọilà số chiều của mảng.

Việc khai báo một mảng cần định rỏ:• Kiểu cơ sở của các phần tử trong mảng• Tên mảng• Số chiều và kích thước mỗi chiều đặt trong ngoặc vuông [ ]. Số phần tử trong

mảng bằng tích kích thước các chiều.Ví dụ: int a[5];

Khai báo mảng 1 chiều tên là a có 5 phần tử, Mỗi phần tử a[i] là một

 biến kiểu int và được xác định dựa trên 1 chỉ số như sau: a[0], a[1], a[2], a[3],a[4].Ví dụ: int b[2][3];

Khai báo mảng 2 chiều tên là b, có 2*3 = 6 phần tử, Mỗi phần tử làmột biến kiểu nguyên và được xác định dựa trên 2 chỉ số dòng và cột nhưsau::

 b[0][0] b[0][1] b[0][2] b[1][0] b[1][1] b[1][2]

Trong đó, thường sử dụng là mảng 1 chiều và mảng 2 chiều.-IIMẢNG MỘT CHIỀU:

Dùng biểu diễn 1 danh sách giá trị cùng kiểu.-1 Khai Báo Biến Mảng 1 Chiều:<kiểucơsở> <tênmảng>[<số phần tử>];Ví dụ: int a[5];

a là 1 biến mảng; còn a[0],a[1],..,a[4] là các biến số nguyên.• Có thể sử dụng hằng biến để xác định kích thước mảng:

Ví dụ: #define MAX 100float a[MAX];const int MAX = 100;float b[MAX];

• Có thể gán giá trị khởi đầu cho các phần tử của mảng trong khi khai báo:<kiểucơsở> <tênmảng>[<số phần tử>] = {gt1, .., gtn} ;Ví dụ: int a[5] = {1, 3, 4 }

•  Nếu số giá trị khởi đầu < số phần tử thì các phần tử còn lại sẽ được gán giá trị khởi đầu= 0.

Ví dụ: gán giá trị khởi đầu cho 5 phần tử của mảng a là: int a[5] = {0};• Có thể không chỉ định số phần tử của mảng : <kiểucơsở> <tênmảng>[] = {gt1, .., gtn} ;

Khi đó số phần tử của mảng sẽ là số gía trị khởi đầu trong khai báo mảng.Ví dụ: int a[] = {1, 3, 4 }; Mảng a có 3 phần tử.

-2 Khai Báo Kiểu Mảng:typedef <kiểucơsở> tênkiểu[<số phần tử>];

35

Page 36: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 36/65

Ví dụ: Khai báo kiểu mảng 1 chiều có 10 phần tử mỗi phần tử là 1 biến kiểu sốnguyên

typedef int Dayint[10];Dayint a;

-3 Một Số Thao Tác Trên Mảng 1 Chiều:.3.1 Truy xuất trực tiếp đến từng phần tử của biến mảng như 1 biến thuộc kiểu cơ sở:

tênmảng[<chỉsố>]Ví dụ: ch[1] = ‘A’; x[6] = (x[4]+x[5])/2;

scanf(“%d”, &a[2]); printf(“a[%d] = %d”, i, a[i]);

Chú ý: Không thể nhập xuất trực tiếp biến mảng..3.2 Nhập giá trị cho các phần tử của mảng:

Ý tưởng: Sử dụng 1 vòng lặp thay đổi chỉ số, để nhập dữ liệu cho từng phần tử theo chỉsố.

Ví dụ: Viết chương trình nhập N số nguyên (N <= 100). Sau đó tính tổng của các số

nguyên lẻ ..3.3 Xuất giá trị các phần tử :

Ý tưởng: Sử dụng 1 vòng lặp chạy theo chỉ số và xuất phần tử theo chỉ số đó.for (i = 0; i < n ; i++) printf(“%8d“, a[i]) ;

.3.4 Tìm kiếm một phần tử theo yêu cầu:Ý tưởng: Lần lượt kiểm tra từng phần tử, bắt đầu từ phần tử đầu mảng.

.3.4.1Tìm kiếm phần tử chứa giá trị cần tìm:Ý tưởng: Khởi đầu từ phần tử đầu mảng. Lần lượt so sánh với phần tử X. Quá trình tìm

kiếm kết thúc khi tìm thấy hoặc khi hết mảng.Ví dụ: Tìm trong mảng có N số nguyên phần tử đầu tiên có giá trị là X.

.3.4.2Tìm kiếm phần tử thỏa yêu cầu cực trị:Ý tưởng: Sử dụng các biến để lưu giữ vị trí phần tử cực trị trong quá trình so sánh.

Ví dụ: Nhập vào nhiệt độ của mỗi ngày trong tuần, từ chủ nhật đến thứ 7. Hãy cho biếtngày nào nóng nhất.

int Thu[7];int i, ndmax, ngaynong;void main(void){ printf(“\nNhap nhiet do 7 ngay trong tuần: \n“);

for (i=0; i < 7; i++) { printf(“Nhap nhiêt do ngay %d : “, i); scanf(“%d”, &Thu[i]);}ndmax = Thu[0]; ngaynong = 0;for (i=1; i < 7; i++)

if (ndmax <Thu[i]) { ndnong = Thu[i]; ngaynong = i; } printf(“\nNgay nong nhat la ngay %d “, ngaynong +1);

}.3.5 Sắp xếp một mảng theo thứ tự tăng ( hay giảm) dần:

Thuật toán chọn trực tiếp (select sort)

Ý tưởng: - Tìm phần tử nhỏ nhất trong mảng (0 .. n-1) ta đổi chổ với pt[1]- Sau đó, lại tìm phần tử nhỏ nhất trong dãy từ (1 .. n-1) ta đổi chổ với

 pt[2]36

Page 37: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 37/65

- Tiếp tục cho tới khi mảng con chỉ còn 1 phần tử.void selectsort(kiểu A[ ]; int n);{ int i, j, vtmin;

for ( i =1; i <= n-1; i++){ vtmin = i;

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

if (a[ j ] < a[vtmin]) min = j ;Hoanvi(a[vtmin],a[i]);

}}

.3.6 Chèn một phần tử vào mảng:Ví dụ: Chèn 1 giá trị vào mảng đã sắp thứ tự.

.3.7 Xóa một phần tử trong mảng:Ý tưởng: Dồn các phần tử sang trái và giảm số phần tử.

-4 Truyền tham số Mảng một chiều:

Việc truyền tham số là mảng cho hàm luôn theo nguyên tắc truyền địa chỉ. Khi gọihàm và thiết kế tham số là mảng 1 chiều cho hàm cần tuân theo nguyên tắc:

Đối số là mảng :Tên biến mảng: <kiểuhàm> tênhàm( kiểucơsở tênđốisốmảng[ ], ...)

Chú ý: Không cần khai báo kích thước đối số mảng, tuy nhiên nếu có khai báo trình biên dịch cũng sẽ bỏ quan

Khai báo đặc trưng của hàm có thể là:<kiểuhàm> tênhàm( kiểu tênmảng[ ], ...);<kiểuhàm> tênhàm( kiểu [ ], ...);

Gọi hàm và truyền Tham số kiểu mảng: phải là tên mảng, vì tên mảng là hằng địa

chỉ của biến mảng: tênhàm( tênmảng, ...)Ví dụ: Viết chương trình tính tổng 2 vecto có tối đa N phần tử (N ( 100).#include <stdio.h>#define MAX 100;void NhapVecto( char; int [ ], int );void InVecto(char, int [ ], int);void TongVecto(int [ ], int [ ], int [ ], int);void main(){

int A[MAX], B[MAX], C[MAX], n;

 printf(“\nNhap so chieu : “); scanf(“%d”, &n); NhapVecto(‘A’, a, n); NhapVecto(‘B’, b, n);TongVecto(a,b,c, n); InVecto(‘C’, c , n);

}void NhapVecto( char tenvecto, int x[ ], int sc){ int i;

 printf(“\n Nhập tọa độ vecto %d chiều : \n“, sc);for (i = 0; i < sc; i++){ printf(“\nTọa độ thứ %d : “, i + 1);

scanf(“%d”, &x[ i ]);}

}}void InVecto( char tenvecto, int x[ ], int sc)

37

Page 38: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 38/65

{ int i; printf(“\n Tọa độ vecto %c : “, tenvecto);for (i = 0; i < sc; i++) printf(“%6d“, &x[ i ]);

}void TongVecto(int x[], int y[], int z[], int sc){ int i;

for (i = 0; i < sc; i++) z[ i ] = x[ i ] + y[ i ];}

-IIIMẢNG HAI CHIỀU:-1 KHÁI NIỆM:

Mảng 2 chiều là mảng 1 chiều mà mỗi phần tử lại là mảng 1 chiều.-2 KHAI BÁO VÀ SỬ DỤNG MẢNG HAI CHIỀU:

<kiểu phần tử> tênbiếnmảng[số dòng tối đa][số cột tối đa];Ví dụ: int a[3][4];• Gán giá trị ban đầu khi khai báo:

Ví dụ: float x[3][4] = {{3,9,4,6}, {4,0,7,2}, {6,4,8,2} };x có 3 phần tử x[0],..,x[2] mà mỗi phần tử x[i] là một mảng 1 chiều có 4 phần

tửx[0] là mảng có các phần tử x[0][1],.., x[0][3] là các số thực.

• Có thể khai báo không chỉ định tổng số dòng: Khi đó tổng số dòng phụ thuộc vàosố dòng được gán.

Kiểu tênmảng[ ] [tổng số cột]= {giá trị gán};-3 THAO TÁC TRÊN MẢNG 2 CHIỀU:.3.1 Nhập xuất giá trị của 1 phần tử trên mảng 2 chiều, dùng công thức:

<tên biến mảng>[<chỉ số dòng>][<chỉ số cột>]

Ví dụ: x[1][3] = 9.5;.3.2 Xuất giá trị của các phần tử của mảng 2 chiều:

for ( i = 0; i < sodong; i++){for (j = 0; j < socot; j++) printf(“%8d”, x[ i ][ j ]);

 puts(“”);}

.3.3 Nhập giá trị cho các phần tử của mảng 2 chiều:

.3.3.1Bằng hàm random(100)

for ( i = 0; i < m; i++)for (j = 0; j < n; j++) x[ i ][ j ] = random(100);

Ví dụ: Cho một ma trận số nguyên gồm M dòng N cột (M,N<=100).a) Hãy cho biết cột nào có tổng các số hạng trên cột là lớn nhất.

 b) Dòng nào có tổng các số hạng trên dòng là nhỏ nhất..3.3.2Nhập giá trị cho các phần tử của mảng 2 chiều Bằng hàm scanf:

for ( i = 0; i < m; i++)for (j = 0; j < n; j++){ printf(“\na[%d][%d] = “, i, j);

scanf(“%d”, &x[ i ][ j ]);}

38

Page 39: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 39/65

Ví dụ: Viết chương trình nhân ma trận A (NxL) và B (LxM) : C (NxM) = A*B#include <stdio.h>#define MAX 10main(){

float a[MAX][MAX], b[MAX][MAX], c[MAX][MAX], x;

int n=2,l=3,m=3;int i, j;

 printf("\nNhap gia tri cho cac phan tu cua mang A: \n");for (i=0; i< n; i++)

for (j=0; j < l; j++){

 printf("\tA[%d][%d] : ",i+1,j+1);scanf("%f", &x);a[i][j] = x ;

}

 printf("\nNhap gia tri cho cac phan tu cua mang A: \n");for (i=0; i< l; i++)

for (j=0; j < m; j++){ printf("\tA[%d][%d] : ",i+1,j+1);

scanf("%f", &x); b[i][j] = x;

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

for (j=0; j<m; j++){ c[i][j] = 0;

for (k=0; k < l; k++) c[i][j] +=a[i][k]* b[k][j];}

for (i=0; i< sd; i++){ for (j=0; j < sc; j++) printf("%5.0f", c[i][j]);

 puts("");}getch();

}-4 TRUYỀN THAM SỐ TRÊN MẢNG 2 CHIỀU:

• Khai báo đối số là mảng 2 chiều:<kiểuhàm> tênhàm( kiểu tênmảng[ ][số cột], ...)

• Gọi hàm và truyền tham số kiểu mảng hai chiều:tênhàm( tênmảng, ...)

-IVMảng nhiều chiều:-1 KHÁI NIỆM:

Mảng N chiều là mảng N -1 chiều mà mỗi phần tử là mảng một chiều.-2 KHAI BÁO MẢNG:

<kiểu phần tử> tênbiếnmảng[kt1][kt2]..[ktN];Ví dụ: float y[2][3][4];

• y là mảng 3 chiều.• y[i] là mảng 2 chiều.• y[i][j] là mảng 1 chiều có 4 phần tử kiểu số thực.

39

Page 40: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 40/65

Page 41: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 41/65

BÀI 9: KỸ THUẬT LẬP TRÌNH VỚI CON TRỎ-I KHÁI NIỆM VỀ BIẾN CON TRỎ:-1 Khái niệm:

Biến con trỏ có kiểu cơ sở T là loại biến dùng lưu trữ địa chỉ vùng nhớ của một biếnkhác thuộc một kiểu T.

-2 Khai báo biến con trỏ:<Kiểucơsở> * <Tênbiếncontrỏ>;Ví dụ: float *pf, p;

int *pi, p;char *pc, p;

• <Kiểu cơ sở> có thể là kiểu vô hướng hoặc kiểu có cấu trúc bất kỳ hoặc kiểu void.Đặc biệt: Kiểu con trỏ void: void *Ptr;

Con trỏ kiểu void được gọi là con trỏ không định kiểu và cho phép chứa địa chỉ củamọi biến thuôc kiểu dữ liệu bất kỳ.• Biến con trỏ có thể nhận giá trị 0, NULL hay một địa chỉ bộ nhớ. Một biến con trỏ

có giá trị 0 hay NULL hàm ý không trỏ đến vùng nhớ nào cả.• Sau khi khai báo, biến con trỏ chứa giá trị ngẫu nhiên. Có thể khởi gán giá trị của

 biến con trỏ khi khai báo hoặc sử dụng câu lệnh gán tường minh.-IICÁC THAO TÁC TRÊN BIẾN CON TRỎ:-1 Gán địa chỉ vùng nhớ cho biến con trỏ:• Gán địa chỉ của một biến kiểu cơ sở cho biến con trỏ:

<biếncontrỏ> = &<tênbiếnkiểuT>;Ví dụ: int y, *yptr, *xptr;

y = 5; yptr = &y;

• Gán nội dung của một con trỏ khác cho biến con trỏ:<biếncontrỏ 1> = <biếncontrỏ 2>

•  Nếu hai con trỏ khác kiểu thì khi gán phải ép kiểu của <biến con trỏ 2> theo kiểucủa <biến con trỏ 1>: <biếncontrỏ 1> = (<kiểucơsở 1> * ) <biếncontrỏ 2>;Ví dụ: char *zPtr;

zPtr = (char*) yPtr;-2 Nhập xuất nội dung vùng nhớ thông qua con trỏ:

Sử dụng toán tử một ngôi * để lấy nội dung vùng nhớ mà con trỏ trỏ đến:* <biếncontrỏ>

Ví dụ: printf(“Giá trị của biến y là %d “, *yPtr ); ----> Giá trị của biến y là 5

*yPtr = 8; //Gán giá trị cho biến y thông quan biến con trỏ yPtr •  Nhập dữ liệu vào vùng nhớ của biến y thông qua biến con trỏ:

scanf(“%d”, yPtr);-3 Phép so sánh con trỏ:

Có thể so sánh địa chỉ vùng nhớ lưu trong các biến con trỏ bằng các phép sosánh

Ví dụ: Để kiểm tra 2 biến con trỏ có chứa cùng địa chỉ vùng nhớ hay không:yPtr == xPtr 

Ví dụ: So sánh biến con trỏ với giá trị NULL: yPtr == NULL-IIICON TRỎ VÀ MẢNG:

Ví dụ: int A[8];int * Aptr;

41

Page 42: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 42/65

3000 3002 3004 3006 3008 3010A[0] A[1] A[2] A[3] A[4] A[5]

Trong C, Tên mảng được xem là một con trỏ hằng, chứa địa chỉ phần tử đầu tiên củamảng nên có thể :-1 Gán địa chỉ đầu mảng cho biến con trỏ bằng cách dùng tên mảng:

Aptr = A; Aptr = &A[0];

-2 Phép toán cộng trừ địa chỉ phần tử mảng:Chỉ sử dụng trên biến con trỏ trỏ đến 1 mảng

• Phép cộng địa chỉ: <biếncontrỏ> + <số nguyên> <biếncontrỏ> + sizeof(kiểucơsở) * <số nguyên>

Ví dụ: Aptr = A + 3; hayAptr += 3; // Aptr = 3000 + 3 * 2

• Phép trừ địa chỉ: <biếncontrỏ 1> - <biếncontrỏ 2> số phần tử mảng từ con trỏ 1 đến contrỏ 2

Ví dụ: &A[3] - &A[1] 3

-3 Truy xuất đến 1 phần tử trong mảng bằng cách:.3.1 Đối với mảng một chiều:

• Dùng tên mảng như địa chỉ đầu và chỉ số là khoảng cách đến phần tử cần truyxuất.

Ví dụ: *(A + i) với i = 0 .. n -1.• Dùng tên con trỏ trỏ địa chỉ đầu và chỉ số là khoảng cách đến phần tử cần truy

xuất.Ví dụ: *(Aptr + i) với i = 0 .. n -1.

• Dùng con trỏ kèm chỉ số: Aptr[ I ]

.3.2 Đối với Mảng 2 chiều:- Địa chỉ của phần tử [ i ][ j ] bằng: pt + i * CMAX + j- Giá trị của phần tử [i][j] bằng : *(pt + i * CMAX + j)Ví dụ: Viết chương trình nhân ma trận A (NxL) và B (LxM) : C (NxM) = A*B

#include <stdio.h>#define MAX 10void NhapMaTran(char ,float *, int, int);void InMaTran(float *,int, int);void TichMaTran(float* , float *, float *,int , int , int );main()

{ float a[MAX][MAX], b[MAX][MAX], c[MAX][MAX];int n=2,l=3,m=3;

 NhapMaTran('A',(float*) a, n,l); NhapMaTran('B', (float*) b,l,m);TichMaTran((float*)a, (float*)b,(float*)c,n,l,m);InMaTran((float*)c,n,m);getch();

}/*===============================*/void NhapMaTran(char ten,float *pt, int sd, int sc){ int i,j;

 printf("\nNhap gia tri cho cac phan tu cua mang %c : \n",ten);for (i=0; i< sd; i++)

42

Page 43: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 43/65

for (j=0; j < sc; j++){ printf("\t%c[%d][%d] : ",ten,i+1,j+1);

scanf("%f",pt + i*MAX + j);}

}/*=======================================*/

void InMaTran(float *pt,int sd, int sc){ int i,j;

for (i=0; i< sd; i++){ for (j=0; j < sc; j++) printf("%5.0f",*(pt+i*MAX+j));

 puts("");}

}/*=================================*/void TichMaTran(float *pa, float *pb, float *pc,int n, int l, int m){ int i, j, k;

for (i=0; i<n; i++)for (j=0; j<m; j++){ *(pc+i*MAX+j) = 0;

for (k=0; k < l; k++)*(pc+i*MAX+j) += (*(pa+i*MAX+k)) * (*(pb+k*MAX+j));

}}-4 Gán 1 biến mảng cho 1 biến mảng khác cùng kiểu mảng:

Sử dụng hàm memmove hay memcpy trong string.h:• memmove(địachỉmảngđích, địachỉmảngnguồn, Kíchthướcmảngnguồn);• memcpy(địachỉmảngđích, địachỉmảngnguồn, Kíchthướcmảngnguồn);

Dùng sao chép các byte liên tiếp bắt đầu <địachỉmảngnguồn> cho các byte chỉ bởi<địachỉmảngđích> với số byte chỉ bởi <Kíchthướcmảngnguồn>.

Ví dụ: #define MAX 5int a[MAX] = {2, 5, 7, 8, 9};int b[MAX], C[MAX];

Gán giá trị các phần tử của mảng a cho mảng b: memmove(b, a, sizeof(a));Gán giá trị 3 phần tử của mảng a bắt đầu từ phần tử thứ 2 cho 3 phần tử của mảng c

 bắt đầu từ phần tử thứ 3.memmove(c + 2, a + 1, sizeof(a[0])*3);

Ví dụ: Viết chương trình tạo mảng A gồm 5 phần tử . Gán giá trị mảng A cho mảngB. Sao chép gía trị 3 phần tử kể từ phần tử thứ 2 cho mảng C bắt đầu từ phần tử thứ 3.

#include <stdio.h>#include <string.h>#define MAX 5int a[MAX] = {2, 5, 7, 8, 9};int b[MAX], C[MAX], I;main(){ menmove(b, a, sizeof(a));

inmang(b, sizeof(b));menmove(c + 2, a + 1, sizeof(a[0])*3);inmang(c, 3);

43

Page 44: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 44/65

}• void *memset( void * s, int Ch, sốbyte); Đặt n Byte của mảng A tới ký tự Ch

Ví dụ: memset( A, 0, sizeof(A));-IVCon trỏ và Hàm:

 Ngoài cách truyền tham số kiểu tham chiếu bằng toán tử tham chiếu & có thể truyềntham chiếu bằng biến con trỏ.

• Khai báo hàm nhận tham số kiểu tham chiếu<Kiểuhàm> <TênHàm>( <Kiểucơsở> *Tênđối số, ..)

• Gọi hàm và truyền tham số kiểu tham chiếu bằng biến con trỏTênHàm( &tênbiến,…);

Ví dụ Viết chương trình giản ước 1 phân số, có sử dụng 1 hàm tính ước số chung lớnnhất của 2 số./*=========================*/void nhap_phan_so(int *x, int *y){ do

{ printf("\nNhap phan so (x/y) : ");scanf("%d %*c %d", x, y);fflush(stdin);if (*y == 0) printf("\nMau so bang 0");else if (*x < 0 && *y < 0)

{ *x = abs(*x);*y = abs(*y);

}else if (*x**y<0)

{ *x = -abs(*x);

*y = abs(*y);}} while (*y == 0);

}

void toigianps(int *tu, int *mau){ long int usc;

usc = ucln(*tu,*mau);

*tu = *tu/usc;*mau = *mau/usc;}/*-------------------------------*/int ucln(int a, int b){

int m,n,r;m = abs(a); n = abs(b);r = m%n;while (r != 0)

{ m = n;n = r; r = m%n;}return n;

}main(){

int a, b; NhapPhanSo( &a, &b);toigianps(&a,&b);

 printf(“\nSau khi giản ước: %d/%d”,a,b);}• Kiểu kết quả của hàm là kiểu con trỏ:

Khi đó, giá trị trả về phải là một địa chỉ hay giá trị NULLint *Tim(kiểu key; kiểu A[]; int n){

vitri:=0;for (i = 0; i < n; i++)

if ( A[ i ] == key ) return &A[i];return NULL;

}

44

Page 45: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 45/65

BÀI 10: CHUỖI KÝ TỰ -I Khái niệm:

Chuỗi ký tự là mảng một chiều có các phần tử là các ký tự, được đánh dấu kết thúcchuỗi bằng ký tự NULL (‘\0’).

Các hằng chuỗi là dãy ký tự bao trong dấu nháy kép.

Trong C, các hàm xử lý chuỗi ký tự rất đa dạng và phong phú và được cung cấp trongtập tin tiêu đề STRING.H (STRING.LIB).-1 Khai báo biến chuỗi:

Khai báo biến chuỗi như mảng các ký tự:char tênbiến[kích thước];

Kích thước là một hằng số nguyên qui định kích thước lưu trử tối đa(<65335), kể cảdấu kết thúc chuỗi. Chương trình sẽ chạy không ổn định nếu nhập giá trị vượt quá kíchthước tối đa.

Ví dụ: char hoten[25];C sẽ cung cấp 25 bytes từ 0..24 để lưu nội dung và ký tự kết thúc chuỗi.

- Có thể khởi đầu giá trị cho biến chuỗi khi khai báo:- danh sách các hằng ký tự: char str[10] = {‘C’,’o’,’m’,’p’, ‘u’,’t’,’e’,’r’};- Một hằng chuỗi ký tự: char str[10] = “Computer”;Các byte còn lại được gán giá trị Null (‘\0’).Too many initializers in ....: Số giá trị khởi tạo vượt quá kích thước mảng.

- Có thể khai báo biến chuỗi không chỉ định kích thước :Ví dụ: char str[ ] = “Computer”;

-2 Khai báo kiều chuỗi:typedef char string[255];

Tổ chức bộ nhớ:

Giống như mảng, biến chuỗi được cấp phát những byte liên tục.Tên biến chuỗi là hằng chứa địa chỉ đầu của vùng nhớ.

Do đó, Không thể thực hiện lệnh gán 1 biến hay 1 hằng chuỗi cho biến mảng chuỗi.Ví dụ: Lệnh gán sau sẽ bị lỗi: str = “Computer”;

1- Địa chỉ chứa ký tự thứ i trong chuỗi có thể truy xuất bằng:Phép toán lấy địa chỉ: &str[i]Phép toán cộng địa chỉ: (str + i)

-IICác thao tác trên kiểu chuỗi:-1 Nhập chuỗi ký tự:

Trong stdio.h có các hàm: scanf(“%s”,str) và gets(str)

Hàm gets: Nhận dãy ký tự từ stdin cho đến khi gặp ‘\n’ . Ký tự ‘\n’ bị loại khỏi stdinnhưng không đặt vào cuối chuỗi, chuỗi được bổ sung thêm ký tự kết thúc ‘\0’.

Dạng hàm: char *gets(char *s);Ví dụ: char ht[25]; gets(ht);

Chú ý: int a; char ch,ht[25];scanf(“%d”,&a); ch = getchar(); gets(ht);

 Nếu tại hàm scanf nhập “12Etran van” thì trôi qua cả 2 lệnh kế tiếp. và a = 12, ch =‘E’, ht = “tran van”. Do đó, nên dùng hàm fflush để làm sạch stdin.

Trong conio.h còn có hàm: cscanf(“%s”,str) và cgets(str)Hàm scanf() và cscanf() chỉ dùng nhập chuỗi không có dấu cáchHàm gets() và cgets() cho phép nhập chuỗi có cả dấu cách, C tự động thêm ký tự

 Null ‘\0’ vào cuối nội dung chuỗi được nhập.

45

Page 46: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 46/65

-2 Xuất chuỗi:Trong stdio.h có hàm: printf(“%s”, const char *str );

int puts(const char *str );a) Hàm puts: int puts(const char *str);

Xuất chuỗi ký tự str (hằng hay biến con trỏ) và đưa thêm ký tự ‘\n’ lên stdout. Khithành công hàm trả về ký tự ‘\n’. Khi có lỗi hàm trả về EOF.

Ví dụ: puts(“\nLac Hong”);Trong conio.h có hàm: cprintf(“%s”, str);

int cputs(const char *str);In chuỗi có địa chỉ str đến cuối chuỗi, xác định bởi ký tự Null.Ví dụ: char s[20] = “An toan la ban”;In toàn bộ chuỗi: printf(“%s”, s );In từ chữ ‘t’ về cuối chuỗi: printf(“%s”, s+3); --> toan la ban

-3 Truy xuất đến từng ký tự trong chuỗi: biếnchuỗi[chỉsố]Ví dụ: Chuyển 1 chuỗi thành chuỗi có ký tự đầu từ là chữ hoa, trong từ là chữ thường.Ý tưởng: Ký tự đầu từ là ký tự khác dấu cách và có ký tự đứng trước là dấu cách. Ký tự

trong từ là ký tự khác dấu cách và có ký tự đứng trước cũng khác dấu cách#include <stdio.h>#include <ctype.h>#define Max 500main(){ char s[Max]="an toan la ban";

char curr, pre; int i; pre = 32; i=0;while (s[i] != 0){

if (s[i]!= 32)if (pre == 32) s[i] = toupper(s[i]);else s[i] = tolower(s[i]);

 pre = s[i];i++;

} printf("\n%s",s); getch();

}Ví dụ: Cắt bỏ dấu cách bên phải 1 chuỗi chữ bằng cách ghi ký tự NULL vào sau ký tự khác

dấu cách đầu tiên ở bên phải.#include <stdio.h>#include <ctype.h>#define Max 500main(){ char s[Max]="an toan la ban ";

int i, len;len = strlen(s);i = len-1;while (s[i] == 32 && i >=0) i--;if (i>=0) s[i+1]=0;

 printf("\n%s!",s);}

46

Page 47: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 47/65

-IIIMảng các chuỗi:Mảng các chuỗi là mảng 2 chiều có kiểu phần tử là kiểu char.Ví dụ: Khai báo 1 mảng chứa 20 chuỗi ký tự, mỗi chuỗi dài tối đa 7 ký tự

char as[20][8]; ==> as[i] là một chuỗi có tối đa 7 ký tự.Ví dụ: Viết chương trình nhập vào 1 năm dương lịch. In ra năm âm lịch tương ứng.#include "string.h"

#include "stdio.h"char Chi[12][7]={"Than","Dau","Tuat","Hoi","Ti","Sua","Dan",

"Meo","Thin","Ty","Ngo","Mui"};char Can[10][7]={"Canh","Tan","Nham","Qui","Giap","At","Binh","Dinh"

,"Mau","Ky"};int nam;main(){

 printf("\nNhap Nam Duong Lich: ");scanf("%d",&nam);

 printf("\nNam am lich %s %s", Can[nam % 10],Chi[nam % 12]);getch();

}-IVCon trỏ và Chuỗi ký tự:-1 Khai báo con trỏ: char *p, s[10];-2 Gán địa chỉ vùng nhớ của biến chuỗi cho biến con trỏ: p = s;-3 Gán hằng chuỗi cho biến con trỏ: p = “Lac Hong”;

C sẽ cung cấp 1 vùng nhớ 9 bytes và chứa địa chỉ vào biến con trỏ.Ví dụ kiểm tra:main(){ char *s1, *s2;

s1 = “Lac Hong”; s2 = “Dai Hoc”; printf(“\n%p %p”, s1, s2); --> 400 409

}-4 Cấp phát động 1 vùng nhớ chứa dữ liệu và ghi địa chỉ vào biến con trỏ:

void *malloc(int sốbytes);void *calloc(int sophầntử, int kíchthước1ptử);

void *realloc(void *ptr, kíchthướcmới); Cấp phát vùng nhớ mới theo kíchthướcmới vàchép dữ liệu của vùng nhớ trỏ bởi Ptr sang vùng nhớ 

mới. Trả về địa chỉ vùng nhớ mới hoặc giá trị NULL .Ví dụ: Tạo vùng nhớ để chứa 1 chuỗi 20 ký tựchar *s;s = (char*) malloc(20);

Sau lệnh gán các thao tác trên biến chuỗi đều có thể áp dụng trên biến con trỏ.-VHàm tự tạo và kiểu chuỗi:

Truyền một chuỗi ký tự cho hàm và luôn theo nguyên tắc truyền địa chỉ giống nhưmảng 1 chiều. Khi đó:

Tham số khai báo thường là kiểu con trỏ char Tham số thực sự tương ứng trong lời gọi hàm phải là địa chỉ hay là hằng chuỗi.

Và Hàm cũng có thể trả về địa chỉ một chuỗichar * tênhàm(char *str,...);Ví dụ: Xây dựng hàm trả về một chuỗi chữ có ký tự đầu từ in, trong từ là thường.

47

Page 48: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 48/65

char *Proper(char *s){ char curr, pre;

int i; pre = 32;i=0;while (s[i] != 0)

{if (s[i]!= 32)

if (pre == 32) s[i] = toupper(s[i]);else s[i] = tolower(s[i]);

 pre = s[i];}return s;

}Ví dụ: Xây dựng hàm xuất 1 chuỗi ký tự tại tọa độ x,y

void putxy(char *str, int x, int y, int color)

{textattr(color);gotoxy(x,y);cprintf(“%s”, str);

}-VICác hàm xử lý chuỗi strong STRING.H:-1 Xác định chiều dài thật sự của chuỗi:

int strlen(const char *s);-2 Đổi chữ thường thành chữ hoa và ngược lại:

char *strupr(char *s); chuyển chuỗi s thành chuỗi chữ Hoachar *strlwr(char *s); chuyển chuỗi s thành chuỗi chữ thường

* Trong ctype.h có: int tolower(int ch); int toupper(int ch);-3 Nối 2 chuỗi:

 Nối chuỗi nguồn vào sau chuỗi đích: trong đó chuỗi đích phải có đủ kích thước đểchứa

char *strcat(char *dest, const char *src );Ví dụ: char ho[20]=”Van Nhu“; ten[7]=”Bich”; hoten[30]=””;

strcat(hoten,ho); strcat(hoten,” “); strcat(hoten, ten); puts(hoten);

Ví dụ: Viết chương trình dịch 1 số nguyên dương có tối đa 3 chữ số thành chữ.#include "stdio.h"#include "string.h"char cs[10][6]={"khong","mot","hai","ba","bon","nam",

"sau","bay","tam","chin"};int so ;

char *Dich3so(int so){

int dv,tram,chuc;char chu[40];dv = so % 10;chuc = (so / 10) % 10;tram = so / 100;

48

Page 49: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 49/65

chu[0] = 0;if (tram > 0)

strcat(strcat(chu,cs[tram]), " tram ");if (chuc>1){

strcat(chu,cs[chuc]);

strcat(chu, " muoi ");}else

if (chuc == 1) strcat(chu,"muoi");else

if (tram > 0 && dv > 0) strcat(chu,"linh ");if (dv > 0)

if (dv == 5 && chuc>0) strcat(chu,"lam");else (strcat(chu,cs[dv]));

return chu;

}void main(void){

clrscr(); printf("Nhap 1 so co toi da 3 chu so: ");scanf("%d",&so);

 printf("\n%s",Dich3so(so));getch();

}Ví dụ: Xây dựng hàm Concat dùng nối 2 chuỗi và trả về chuỗi kết quả không thay đổi nội

dung 2 chuỗi nguồn.char *Concat(const char *s1, const char *s2){ char *s;

s = (char*)malloc(strlen(s1)+strlen(s2));s[0] = 0;strcat(s, s1); strcat(s, s2);return s;

}-4 Nối n ký tự của chuỗi nguồn vào sau chuỗi đích:

char *strncat(char *dest, const char *src, int n);sau đó thêm vào ký tự NULL cuối chuỗi destVí dụ: Viết hàm cắt bỏ các dấu cách không cần thiết trong chuỗi.char *Trim(char *s){ int i,len;

char *str;char pre=32;len = strlen(s);str = (char*) malloc(len+1);str[0] = 0;for (i=0; i < len; i++){ if ((s[i] != 32) || (s[i] == 32 && pre != 32))

strncat(str,&s[i],1);

49

Page 50: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 50/65

 pre = s[i];}if (s[len-1] == 32) str[strlen(str)-1] = 0;return str;

}-5 Sao chép chuỗi:

Sao chép chuỗi nguồn sang chuỗi đích từ ký tự đầu cho đến ký tự kết thúc chuỗinguồn :

char *strcpy(char *dest, const char *src);Ví dụ: Viết hàm trích 1 chuỗi con dài n ký tự bên phải chuỗi S.char *Right(char *s, int n){ int len,vt = 0;

char *s1;len = strlen(s);if (n <= 0) n = 0;else

if (n > len) n = len;vt = len - n;s1 = (char*)malloc(n+1);strcpy(s1,s+vt);return s1;

}Có thể dùng strcpy để cắt bỏ ký tự trong chuỗi.Ví dụ: Xóa n ký tự từ vị trí thứ thứ i trong chuỗi Str.void Delete(char *str; int i, int n) /*Xóa ký tự tại vị trí thứ i */{ int len ;

len = strlen(str);if (i >=0 && i < len && n >0){

if (n > len-i) n = len-i;strcpy(&str[ i ], &str[i+n]);

}}

-6 Sao chép n ký tự từ chuỗi nguồn sang chuỗi đích:char *strncpy(char *dest, const char *src, int sốtừ);

 Nếu sốtừ > strlen(src): thì sẽ thêm những ký tự Null vào cho đủ sốtừ Nếu sốtừ < strlen(src): thì chuỗi kết quả dest không được kết thúc rỗng.Ví dụ: Trích ra chuỗi con dài n ký tự bắt đầu từ ký tự thứ i trong chuỗi.char *Substr(char * s, int i, int n){

char *s1;if (i >=0 && i < len && n >0){

s1 = (char*) malloc(n+1);strncpy(s1,s+i-1,n);

s1[n]=0;return s1;}

50

Page 51: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 51/65

return “”;}Ví dụ: Viết hàm trích ra n ký tự từ bên trái chuỗi Schar *Left(char *s,int n){

char *s1;

s1 = (char*) malloc(n+1);strncpy(s1,s,n); /* strncat(s1, s, n); */s1[n]=0;return s1;

}-7 So sánh 2 chuỗi theo thứ tự từ điển:.7.1 So sánh 2 chuỗi :(phân biệt chữ hoa chữ thường)

int strcmp(const char *s1, const char *s2);Kết quả: < 0 : s1 < s2; = 0 : s1 == s2; > 0 : s1 > s2;

Ví dụ: Sắp xếp danh sách kiểu chuỗi#include <stdio.h>#include <string.h>#include <stdlib.h>int sosanhtang(const void *p, const void *q);int sosanhgiam(char *p, char *q);main(){

char a[4][10]={"Dai","Hoc", "Lac", "Hong"};int i;

clrscr();qsort(a,4,sizeof(a[0]),sosanhtang);for (i=0; i<4;i++)

 printf("\n%s",a[i]);qsort(a,4,sizeof(a[0]),sosanhgiam);for (i=0; i<4;i++)

 printf("\n%s",a[i]);getch();

}int sosanhtang(const void *p, const void *q)

{ return (strcmp((char*)p, (char*)q));}int sosanhgiam(char *p, char *q){

return (-strcmp((char*) p, (char*) q));}

.7.2 So sánh 2 chuỗi phân biệt chữ hoa chữ thường:int stricmp(const char *s1, const char *s2 );Kết quả: < 0 : s1 < s2; = 0 : s1 == s2; > 0 : s1 > s2;

51

Page 52: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 52/65

-8 Tìm kiếm:.8.1 Tìm chuỗi con substr trong 1 chuỗi str :

char *strstr(const char *str, const char *substr);Trả về con trỏ đến ký tự đầu tiên của chuỗi con str2 trong chuỗi str1.

Ví dụ: char *s;

s = strstr(“Dai Hoc Lac Hong”, “Ho”);puts( s ); --> “Hoc Lac Hong”.8.2 Tìm ký tự ch trong chuỗi str: char *strchr(char * s, int ch)

Ví dụ: char *s;s = strchr(“Dai Hoc Lac Hong”, ‘H’) ;

 puts( s ); --> “Hoc Lac Hong”.8.3 Hàm: int strspn(const char *str1, const char * str2);

Trả về chỉ số ký tự đầu tiên trong str1 không có trong str2.Ví dụ: Viết hàm cắt bỏ dấu cách bên trái chuỗi s.void Ltrim(char *s){

int i;i = strspn( s, " "); /*tìm ký tự đầu tiên khác ký tự trắng */strcpy(s, s+i);

  printf("\n%s! %d",s,i);}

.8.4 Hàm: char *strpbrk(const char *str1, const char *str2);Trả về con trỏ đến ký tự đầu tiên trong chuỗi str1 xuất hiện trong chuỗi str2.

Ví dụ: printf(“%s”, strpbrk(“Dai hoc”,”h”)) --> hoc

-9 Các hàm chuyển đổi kiểu: (stdlib.h).9.1 Chuyển số thành chuỗi:

char *itoa(int số, char *str, int cơsố): chuyển số nguyên thành chuỗi số theo 1 cơ sốnào đó

Ví dụ: char s[10];itoa(128, s, 10) -->”128”

char *ltoa(int số, char *str, int cơsố): chuyển số Long int thành chuỗi số theo 1 cơ sốnào đó

Ví dụ: ltoa(128, s, 10) -->”128”char *gcvt(double x, int ndig, char *s); chuyển số thực x thành chuỗi s dài ndig ký tựkhông kể dấu trừ..

Ví dụ: gcvt(3.14159, 5, s); ---> s = “3.1416”gcvt(-3.14159, 5, s); ---> s = “-3.1416”

Chuyển chuỗi thành số:int atoi(const char *str): Trả về số nguyên int chuyển từ chuỗi số str 

Vi dụ: int n;n = atoi(“123.56”) ; printf(“%d”,n); --> 123

long atol(const char *str): Trả về số nguyên long int chuyển từ chuỗi số str Vi dụ: long n;

n = atol(“123.56”) ; printf(“%ld”,n);--> 123double atof(const char *str): Trả về số thực double chuyển từ chuỗi số str 

Vi dụ: double x;

52

Page 53: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 53/65

x = atof(“123.56Hello”) printf(“%lf”, x) --> 123.56

53

Page 54: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 54/65

BÀI 11: Kiểu Structure-I Khái niệm:

Kiểu mẫu tin là kiểu dữ liệu tự tạo mà một biến thuộc kiểu gồm nhiều mục dữ liệu,mỗi mục dữ liệu có tên khác nhau và có thể có kiểu khác nhau.

Kiểu mẫu tin cho phép chúng ta mô tả các đối tượng thực tế có cấu trúc phức tạp.Ví dụ: Mô tả thông tin về một con người gồm các thông tin: Họ tên, năm sinh, nơi

sinh, giới tính, địa chỉ, tình trạng gia đình.v.v...-IIĐịnh nghiã kiểu cấu trúc mới:

Mẫu 1:struct tên_kiểu{kiểu tênmục1;kiểu tênmục2;............};

Mẫu 2:typedef struct {

kiểu tênmục1;kiểu tênmục2;............

} tênkiểu;Ví dụ: Định nghiã kiểu cấu trúc tên là datestruct date { char day, month; int year; };Ví dụ: Định nghiã kiểu cấu trúc mô tả lý lịch nhân viên

struct lylich{ char ho[20]; char ten[7];

struct date ngsinh, ngayvaocoquan;float hesoluong;

};-IIIKhai báo biến kiểu cấu trúc:

Mẫu 1:struct tênkiểucấutrúc tênbiến ={giá trị mục 1, giá trị mục 2,...};

Ví dụ: struct date ngay={12,5,1999};struct lylich nv ={“Le Anh”,”Tuan”,{12,3,1960},{16,4,1990},2.05};

Chú ý: * Nếu định nghĩa kiểu theo mẫu 2 thì không cần dùng từ khóa struct.

* Chư c khi aău bieân caâu truc va mạng caâu truc khai bao beđn ngoai cac ham haykhai bao static. Vieôc khi aău c thc hieôn 1 laăn khi dch chng trnh.Mẫu 2: Khai báo biến khi định nghiã kiểu cấu trúc.

struct [tên_kiểu]{

kiểu tênmục1;kiểu tênmục2;............

} danhsáchbiến;-IVCác thao tác trên biến mẫu tin:

-1 Gán 2 biến cấu trúc có cùng kiểu cấu trúc.nv1 = nv2;

54

Page 55: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 55/65

Page 56: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 56/65

c = Tong(a,b); toigianps(&c); printf(“\nSau khi giản ước: %d/%d”,c.tu, c.mau);

}/*=========================*/

void NhapPhanSo(PhanSo *a){ PhanSo x;

do{ printf("\nNhap phan so (x/y) : ");scanf("%d %*c %d", &x.tu, &x.mau); fflush(stdin);if ( x.mau == 0) printf("\nMau so bang 0");} while (x.mau != 0);*a = x;if (a->tu * a->mau >= 0) a->tu = abs(a->tu);else a->tu = -abs(a->tu);a->mau = abs(a->mau);

}/*-------------------------------*/

void toigianps(PhanSo *a){

long int usc;usc = ucln(a->tu,a->mau);a->tu = a->tu/usc;a->mau = a->mau/usc;

}/*-------------------------------*/

int ucln(int a, int b){

int m,n,r;m = abs(a); n = abs(b);while (n != 0){ r = m%n; m = n; n = r; }return m;

}/*----------------------*/

Phanso Tong(Phanso a, Phanso b){

Phanso c;c.tu = a.tu*b.mau + b.tu*a.mau;c.mau = a.mau*b.mau;return c;

}-VIIMảng cấu trúc:

Dùng quản lý danh sách đối tượng thuộc kiểu cấu trúcTênkiểucấutrúc mảng[MAX];Ví dụ: lylich nv[100];nv[i] là 1 biến cấu trúc thuộc kiểu lylich.

Ví dụ: Nhập và in danh sách thí sinh theo thứ tự tên và họ#include <stdio.h>

56

Page 57: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 57/65

#include <conio.h>#include <string.h>#include <stdlib.h>typedef struct{ unsigned char ngay, thang;

int nam; } date;typedef struct{ int sbd;

char ho[25],ten[7];date ngsinh;float toan,ly,hoa;float DTB;

}hoso;hoso thisinh[100];int n;void NhapHoso(hoso ts[],int *n){

int i=0;

hoso hs; printf("\nNhap Ho so thi sinh \"Ho bang rong de ket thuc\"");do{

hs.sbd = i+1; printf("\nNhap ho so cho thi sinh: %3d",hs.sbd); printf("\nHo : "); gets(hs.ho);if (hs.ho[0]=='\0') break;

 printf("Ten: "); gets(hs.ten); printf("Ngay sinh: ");scanf("%d/%d/%d%*c", &hs.ngsinh.ngay, &hs.ngsinh.thang,&hs.ngsinh.nam);

 printf("Diem Toan: "); scanf("%f%*c",&hs.toan); printf("Diem Ly: "); scanf("%f%*c",&hs.ly); printf("Diem Hoa: "); scanf("%f%*c",&hs.hoa);hs.DTB = (hs.toan+hs.ly+hs.hoa)/3;ts[i] = hs;i++;

}while (i<100);*n = i;

}int sosanh(const void *p, const void *q){

int kq;kq = strcmp(((hoso*)p)->ten,((hoso*)q)->ten);if (kq == 0) return strcmp(((hoso*)p)->ho,((hoso*)q)->ho);return kq;

}void InKQ(hoso ts[], int n){

int i;qsort(ts,n,sizeof(ts[0]),sosanh);

57

Page 58: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 58/65

 printf("\n%-4s %-25s %-10s %-4s %-4s %-4s %-5s","SBD", "Ho Ten","Ngay sinh","Toan","Ly","Hoa","Phong");

for (i=0;i<n;i++) printf("\n%4d %-18s %-7s %2d/%2d/%2d %4.1f %4.1f %4.1f %3d",ts[i].sbd,ts[i].ho,ts[i].ten,ts[i].ngaysinh.ngay,

ts[i].ngaysinh.thang,ts[i].ngaysinh.nam,ts[i].toan,

ts[i].ly, ts[i].hoa, ts[i].phongthi);getch();

}void Hoanvi(hoso *ts1, hoso *ts2){

hoso tam;tam = *ts1; *ts1 = *ts2;*ts2 = tam;

}void bublesort(hoso ts[], int n)

{int i,j;int ssten;for (i=1; i<=n-1; i++)

for (j=n-1; j>=i;j--){

ssten = strcmp(ts[j].ten,ts[j-1].ten);if ((ssten < 0 ) ||

(ssten == 0 && strcmp(ts[j].ho,ts[j-1].ho) < 0))Hoanvi(&ts[j],&ts[j-1]);

}}hoso Timhs(int sbd, hoso ts[], int n){

int i; hoso hs;hs.sbd = hs.ngaysinh.ngay= hs.ngaysinh.thang= hs.ngaysinh.nam=0;hs.ho[0]= hs.ten[0] = 0;for (i=0; i<n; i++)

if ( sbd == ts[i].sbd) return ts[i];return hs;

}hoso *pTimhs(int sbd, hoso ts[], int n){

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

if (sbd==ts[i].sbd) return(&ts[i]);return (NULL);

}void main(void){

clrscr(); NhapHoso(thisinh,&n);

58

Page 59: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 59/65

InKQ(thisinh,n);return 0;

}

59

Page 60: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 60/65

Thành Phần Kiểu Bit: (Bit Field)Ý nghiã và cách khai báo:Đối với các thành phần trong một cấu trúc dùng lưu trữ những số nguyên nhỏ, ta có thể khai

 báo theo kiểu nhóm Bits như sau:Kiểudữliệu [tênTP] : sốbít;

Kiểu dữ liệu: là unsigned int hay signed int

Sốbít ( 16;Khi muốn bỏ qua một số Bits ta bỏ trống tên thành phần.Ví dụ:Ta có thể khai báo kiểu ngày như sau:typedef struct{ unsigned d:5; m:4, y : 5, : 2;int t :2; //Thứ tự ngày tháng nămint : 6;char gach;} date;* Các thành phần không phải là kiểu nhóm Bits sẽ được lưu ở byte khác bỏ qua phần bit

không sử dụng..

Các quy tắc nhập xuất các thành phần kiểu Nhóm Bits:Gán/xuất giá trị : Dùng phép toán dấu (.) hay (->) nếu sử dụng con trỏ.Ví dụ: date day;

day.d = 20; printf(" %d ", day.d);Không thể lấy địa chỉ thành phần kiểu nhóm Bits: do đó để nhập dữ liệu cho thành phần

kiểu Nhóm Bits phải dùng 1 biến số nguyên trung gian.Ví dụ: unsigned temp;

scanf(%d",&temp); day.d = temp;Do đó, không thể truyền thành phần kiểu Bit cho hàm theo kiểu địa chỉ.Kieơu Union:Khai nieôm: Gioâng nh kieơu maêu tin, kieơu union cung goăm nhieău thanh phaăn nhng

cac thanh phaăn cụa union c caâp phat vung nh chung, kch thc cụa moôt bieân union baỉng kch thccụa thanh phaăn ln nhaât.

Kieơu union thng c dung mođ tạ thanh phaăn d lieôu thay oơi tuy theoKhai bao:Vieôc nh ngha kieơu, khai bao bieân va truy xuaât eân tng thanh phaăn cụa bieân kieơu

union gioâng nh oâi vi kieơu maêu tin.V dú: Quạn ly danh sach hóc sinh goăm: hó teđn, ngay sinh, ieơm trung bnh, xeâp loái,

neâu hóc sinh gioi hay kha th c hóc boơng, hóc sinh yeâu th lái lp hoaịc khođng tuy theo DTB di3.5 hay tređn 3.5

union ketqua{ float hocbong;char PheBinh[30];};struct hocsinh{ char hoten[30]; float dtb;char xeploai[3]; union ketqua kq;};_typedef union{ float hocbong;char PheBinh[30];} ketqua;typedef struct {

char hoten[30]; float dtb;char xeploai[3];ketqua kq;

} hocsinh;__ 

60

Page 61: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 61/65

KIỂU TẬP TINMột tập tin đơn giản chỉ là một dãy các byte lưu trữ trong bộ nhớ ngoài với một tên file.

Tên file được đặt theo qui ước của hệ điều hành. Dữ liệu ghi ở dạng số nhị phân như trong bộ nhớ.Mỗi file đều được đánh dấu kết thúc bởi ký tự có mã 26 (trong stdio.h đã định nghiã EOF = –1).

Dựa vào cách nhập dữ liệu và xuất dữ liệu, có 2 loại tập tin :• File văn bản: Tổ chức dữ liệu theo từng dòng, cuối mỗi dòng được kết thúc bở 2 ký tự

CR(13) LF(10).• File nhị phân:Việc nhập xuất File văn bản chỉ khác file nhị phân khi xử lý ký tự chuyển dòng (mã 10, ký

hiệu ‘\n’):• Khi ghi, 1 ký tự LF (line feed) được chuyển thành 2 ký tự CR (Carriage Return_13) và

LF (Line Feed_10).• Khi đọc 2 ký tự liên tiếp CR và LF trên file chỉ cho ta 1 ký tự LF.

Việc truy xuất đến 1 file trên đĩa được thực hiện thông qua biến con trỏ file.Qui cách làm việc với tập tin:- Khai báo biến tập tin

- Mở tập tin- Truy xuất tập tin- Đóng tập tinTruy xuất File bằng các Hàm của STDIO.H:

a. Khai báo biến file: FILE *tênbiếnfile;b. Mở file: tênbiếnfile = fopen(char *têntậptin, char *kiểu);

• têntậptin: Bao gồm cả đường dẫn. Nếu có lỗi sẽ cho gt NULL.• Kiểu: Kết hợp bởi các mã sau nhầm khai báo kiểu tập tin và cách thức truy xuất tập tin.

Kiểu Ý nghiã“b” Mở tập tin kiểu nhị phân

“t” Mở tập tin kiểu văn bản“r” Mở để đọc. Nếu không có File sẽ báo lỗi“r 

+”Mở để đọc hoặc ghi

“w”

Mở file mới để ghi. Nếu file đã có sẽ bị xóa

“w+”

Mở file mới để đọc hoặc ghi.

“a”

Mở file để ghi thêm vào cuối file

a+”

Mở file để đọc ghi. Nếu file cũ thì nối thêm,nếu không thì tạo

mớiVí dụ: FILE *fp;

f = fopen(“C:\\THOCA”, “wt”);c. Đọc ghi file :

• Kiểu văn bản:- int fprintf(FILE *fp, const char *dk,các biểu thức);

Ghi dữ liệu theo khuôn dạng. Nếu thành công hàm trả về số byte ghi lên điã, ngược lại trảvề giá trị EOF (-1). Ký tự ‘\n’ được ghi thành 2 ký tự CR và LF.

Ví dụ: fprintf(fp,”so dinh %d \n”, n);- fscanf(FILE *fp, const char *dk,địa chỉ các biến);

Đọc dữ liệu theo khuôn dạng. Nếu thành công hàm trả về số byte đọc được, ngược lại trả về giátrị EOF (-1).

61

Page 62: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 62/65

Ví dụ: Đọc file DAGIAC.DAT chứa toạ độ các đỉnh của đa giác. dòng đầu ghi số đỉnh. Các dòngsau, mỗi dòng ghi tạo độ của 1 đỉnh của đa giác.

typedef struct pointtype Polygol[10];Polygol P;void main(void){

FILE *fp;char c; int n,i;fp = fopen("c:\\dagiac.dat","rt");fscanf(fp,"%d",&n);

 printf("%d\n",n);*/for (i=0; i<n; i++)

fscanf(fp,"%d %d",&P[i].x,&P[i].y);fclose(fp);

}• Trường hợp không biết trước số đỉnh của đa giác:

i = 0;while (fscanf(fp,"%d %d",&P[i].x, &P[i].y) != EOF)

 printf("%d %d\n",P[i].x,P[i].y);- int fputs(const char *Str, FILE *fp);

Ghi chuỗi Str vào file. Khi thành công hàm trả về ký tự cuối cùng được ghi, ngược lại hàm choEOF.

- char *fgets(char * Str, int n, FILE *fp);Đọc 1 chuỗi tối đa n-1 ký tự. Hàm trả về địa chỉ vùng chứa chuỗi. Nếu có lỗi hoặc gặp cuối file

hàm cho giá trị NULL.Việc đọc kết thúc khi:+ Đọc hết n-1 ký tự;

+ Gặp dấu xuống dòng (cặp mã 13 10): khi đó mã 10 (‘\n’) được ghi vào xâu kết quả+ Gặp dấu kết thúc file• Kiểu nhị phân:

- int putw(int n, FILE *fp);Ghi số nguyên n vào file. Trả về EOF nếu có lỗi, ngược lại trả về số byte được ghi.

- int getw(FILE *fp);Đọc số nguyên 2 byte. nếu có lỗi hay cuối file hàm trả về EOF

- int fwrite(void *ptr, int size, int n, FILE *fp);Ghi n phần tử của mảng ptr, mỗi phần tử có kích thước size bytes. Hàm trả về số

 phần tử thật sự được ghi.- int fread(void *ptr, int size, int n FILE *fp);

Đọc n phần tử của mảng ptr , mỗi phần tử có kích thước size bytes. Hàm trả về số phần số phần tử thật sự đọc được.

d. Đóng file:- int fclose(FILE *fp); Nếu có lỗi hàm cho EOF ngược lại cho giá trị 0.- int fcloseall( ); Nếu có lỗi cho EOF nếu không cho số file được đóng.

e. Kiểm tra cuối file: int feof(FILE *fp); Hàm cho giá trị khác 0 nếu gặp cuối file sau khi đọcVí dụ: while (1)

{ fscanf(fp,”%d %d”, &P[i].x, &P[i].y);if ( feof( f )) break;

}f. Di chuyển con trỏ phần tử 

- void rewind(FILE *fp); Chuyển con trỏ phần tử về đầu file.

62

Page 63: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 63/65

- int fseek(FILE *fp, long sốbyte, int vịtríxuấtphát); chuyển đầu đọc từ vị trí xuất  phát qua 1 số byte về cuối file (sốbyte>0) hay đầu file (sốbyte<0). Nếu thành cônghàm trả về giá trị 0.

Vị trí xuất phát có thể nhận các giá trị:+ SEEK_SET hay 0: xuất phát từ đầu file+ SEEK_CUR hay 1: xuất phát từ vị trí hiện hành

+ SEEK_END hay 2: xuất phát từ cuối file.g. Vị trí con trỏ byte: long ftell(FILE *fp); Cho biết con trỏ ở byte thứ mấy của file (tính từ 0).Khi có lỗi hàm trả về –1L.

 Nhận xét:Bản chất là truy xuất tuần tự, nên truy xuất chậm. Lưu trữ dữ liệu dài hạn, không giới hạn

63

Page 64: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 64/65

Phụ lục:Các thao tác soạn thảo và thực hiện chương trình:

1. Mở tập tin chương trình:• Tạo tập tin mới: File New•  Nạp tập tin chương trình từ điã: File Load (F3)

2. Nhập nội dung chương trình:Một số thao tác phím trong khi nhập:Di chuyển con trỏ:

Ctrl + → (Ctrl + ←): Qua trái (phải) 1 từTab: Di chuyển 1 khoảngHome / End: Ra đầu / cuối dòngCtrl+PgUp / Ctrl+PgDn: Về đầu/cuối chương trình

Chèn/ Xóa:Ins : Bật tắt chế độ chèn đèCtrl+N: chèn 1 dòng

Enter: Xuống dòng/ thêm dòng mớiCtrl+Y: Xóa dòngCtrl+Q+Y : Xóa từ con trỏ đến cuối dòng

Khối văn bản:- Ctrl+K+B : Đánh dấu đầu khối- Ctrl+K+K : Đánh dấu cuối khối- Ctrl+K+C : Chép khối- Ctrl+K+V: Di chuyển khối- Ctrl+K+I : Di chuyển khối sang phải 1 cột- Ctrl+K+U : Di chuyển khối sang trái 1 cột

- Ctrl+K+Y: Xóa khối- Ctrl+K+H: Hiện ẩn đánh dấu khối- Ctrl+K+P: In khối ra máy in.- Ctrl+K+W: ghi khối ra điã- Ctrl+K+R: đọc 1 file trên đĩa3. Lưu nội dung vào điã:

Ấn F2 hay File Save và đặt tên file (nếu chưa) Nếu muốn lưu vào file khác: Chọn File Write to và đặt tên file

4. Chạy và sửa lỗi chương trình:• Kiểm tra và chỉ định thư mục hệ thống: Options Directories (nếu cần)

Include directories: C:\TC\INCLUDE (chỉ định nơi chứa các tập tin *.H)Library directories: C:\TC\LIB (Nơi chứa các tập tin thư viện hàm *.LIB)Output Directory: (Nơi chứa các file *.OBJ và *.EXE)Turbo C directory: C:\TC (thư mục chứa tập tin cấu hình .TC và TCHELP.TCH..Pick file name: Tên file lưu trữ tên các file vừa mở Current pick file: Tên file chọn lọc hiện hành

 Nếu có sửađổi và cần lưu cấu hình mới cho các lần sau: Options Save OptionsOverwrite: \TC\TCConfig.TC (Y/N) ?

• Chạy chương trình:

Biên dịch, nối kết và chạy chương trình: Ctrl+F9 (Run Run)- Nếu có lỗi hoặc có các vấn đề cần chú ý thì sẽ xuất hiện những dòng thông báo lỗi(Error) hoặc những dòng cảnh báo (Warning) trong khung Watch.

64

Page 65: 163636_Ngon Ngu C

8/14/2019 163636_Ngon Ngu C

http://slidepdf.com/reader/full/163636ngon-ngu-c 65/65

- Khi chương trình bị treo: Ctrl+Break và Ctrl+F2 (Run Program reset)- Khi đã có tập tin .EXE, ta có thể thực hiện tại dấu đợi lệnh của DOS.

• Chạy từng dòng lệnh chương trình bằng:F7 (Run Trace into) hay F8 (Run Step over)

Ctrl+F7 : Nhập tên biến để kiểm tra giá trị các biến.