Lập Trình Căn Bản Tổng Quan
Mục Đích Yêu Cầu
Khái niệm về ngôn ngữ lập trình Khái niệm về kiểu dữ liệu Kiểu dữ liệu có cấu trúc (cấu trúc dữ liệu) Khái niệm về giải thuật Ngôn ngữ biểu diễn giải thuật Ngôn ngữ sơ đồ (lưu đồ), sử dụng lưu đồ để biểu diễn các giải thuật Tổng quan về Ngôn ngữ lập trình C Các kiểu dữ liệu trong C Các lệnh có cấu trúc Cách thiết kế và sử dụng các hàm trong C Một số cấu trúc dữ liệu trong C
Nội Dung Cốt Lõi
Chương 1: Giới thiệu về ngôn ngữ C & môi trường lập trình Turbo C Chương 2: Các thành phần của ngôn ngữ C Chương 3: Các kiểu dữ liệu sơ cấp chuẩn và các lệnh đơn Chương 4: Các lệnh có cấu trúc Chương 5: Chương trình con Chương 6: Kiểu mảng Chương 7: Kiểu con trỏ Chương 8: Kiểu chuỗi ký tự Chương 9: Kiểu cấu trúc Chương 10: Kiểu tập tin
LẬP TRÌNH CĂN BẢN Phần 1 GIỚI THIỆU VỀ CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT P.D.Nghiệp
Nội dung chương
Từ bài toán đến chương trình Giải thuật
Khái niệm giải thuật Các đặc trưng của giải thuật Ngôn ngữ biểu diễn giải thuật Một số giải thuật cơ bản Các cấu trúc suy luận cơ bản của giải thuật Từ giải thuật đến chương trình
Kiểu dữ liệu Khái niệm về ngôn ngữ lập trình Chương trình dịch
Từ Bài Toán Đến Chương Trình Các
bước giải bài toán bằng máy tính
Mô tả các bước giải bài toán Vẽ sơ đồ xử lý Viết chương trình xử lý bằng ngôn ngữ giả Chọn ngôn ngữ lập trình và chuyển chương trình từ ngôn ngữ giả sang ngôn ngữ lập trình Thực hiện chương trình: nhập vào các tham số, nhận kết quả
Giải Thuật Khái
niệm giải thuật Các đặc trưng của giải thuật Ngôn ngữ biểu diễn giải thuật Một số giải thuật cơ bản Các cấu trúc suy luận cơ bản của giải thuật Từ giải thuật đến chương trình
Khái Niệm Giải Thuật
Ví dụ: Hoán đổi chất lỏng trong 2 bình A (nước mắm) và B (rượu):
Yêu cầu phải có thêm một bình thứ ba gọi là bình C. Bước 1: Đổ rượu từ bình A sang bình C. Bước 2: Đổ nước mắm từ bình B sang bình A. Bước 3: Đổ rượu từ bình C sang bình B.
“Giải thuật là một dãy các thao tác trên những dữ liệu vào sao cho sau một hữu hạn bước ta thu được kết quả của bài toán ”.
Các Đặc Trưng Của Giải Thuật Tính
Số bước là hữu hạn
Tính
kết thúc xác định
Máy phải thực hiện được Cho cùng kết quả trên các máy khác nhau
Tính
phổ dụng Tính hiệu quả
Thời gian Tài nguyên máy
Ngôn Ngữ Biểu Diễn Giải Thuật Ngôn
ngữ tự nhiên Ngôn ngữ sơ đồ Ngôn ngữ giả
Ngôn Ngữ Tự Nhiên
Là ngôn ngữ của chúng ta Ví dụ: Giải thuật giải phương trình bậc nhất ax+b=0. Bước 1: Nhận giá trị của các tham số a, b. Bước 2: Xét giá trị của a xem có bằng 0 hay không? Nếu a=0 thì làm bước 3, nếu a khác không thì làm bước 4. Bước 3: (a bằng 0) Nếu b bằng 0 => pt vô số nghiệm. Nếu b khác 0 => pt vô nghiệm. Bước 4: ( a khác 0) Ta kết luận phương trình có nghiệm x=-b/a.
Ngôn Ngữ Sơ Đồ (1)
Mô tả giải thuật bằng các sơ đồ hình khối đã được (quy ước trước)
Ngôn Ngữ Sơ Đồ (2)
Ví dụ: Dùng lưu đồ để biểu diễn giải thuật tìm UCLN như sau:
Ngôn Ngữ Giả
Là một sự kết hợp giữa ngôn ngữ tự nhiên với các cấu trúc câu lệnh của một ngôn ngữ lập trình.
Ví dụ: Giải thuật giải phương trình bậc nhất ax+b=0. Nhập
vào a, b
If a==0 then If b==0 then Kết luận phương trình vô số nghiệm else Kết luận phương trình vô nghiệm else Kết luận phương trình có nghiệm x=-b/a
Một Số Giải Thuật Cơ Bản (1)
Ví dụ 1: Yêu cầu:
Nhập vào 1 dãy n số hạng a1, a2, .., an
Tính tổng S: S= a1 + a2 + a3 + ... + an
In S ra màn hình
Một Số Giải Thuật Cơ Bản (2)
Ví dụ 2: Yêu cầu:
Nhập vào 2 số a và b là 2 hệ số của pt: ax+b=0 Cho biết nghiệm của phương trình.
Các Cấu Trúc Suy Luận Cơ Bản Của Giải Thuật (1)
Giải thuật được thiết kế theo 3 cấu trúc suy luận cơ bản:
Tuần tự (Sequential):
Các công việc được thực hiện tuần tự, công việc này nối tiếp công việc kia.
Cấu trúc lựa chọn (Selection)
Lựa chọn một công việc để thực hiện căn cứ vào một điều kiện nào đó
Cấu trúc 1: Nếu < điều kiện> (đúng) thì thực hiện
Cấu trúc 2: Nếu < điều kiện> (đúng) thì thực hiện , ngược lại (điều kiện sai) thì thực hiện Cấu trúc 3: Trường hợp < i> thực hiện
Các Cấu Trúc Suy Luận Cơ Bản Của Giải Thuật (2) Cấu
trúc lặp (Repeating)
Lặp lại thực hiện một công việc không hoặc nhiều lần căn cứ vào một điều kiện nào đó. Có 2 dạng như sau:
Lặp với số lần xác định Lặp với số lần không xác định
Từ Giải Thuật Đến Chương Trình Cả
2 đều là tập các chỉ thị (instruction) – làm thế nào để giải quyết 1 công việc (task). Giải thuật
Nói chuyện với con người, dễ hiểu. Dùng ngôn ngữ đơn giản (English) – không viết bằng mã.
Chương
trình
Nói chuyện với máy tính. Có thể được xem như 1 diễn tả hình thức (formal expression) của 1 giải thuật.
Kiểu Dữ Liệu
Ví dụ: int x,y; float r=3.25;
“Kiểu dữ liệu là một tập hợp các giá trị có cùng một tính chất và tập hợp các phép toán thao tác trên các giá trị đó”. Có 2 loại
Kiểu dữ liệu sơ cấp Kiểu dữ liệu có cấu trúc
Kiểu Dữ Liệu Sơ Cấp “Kiểu
dữ liệu sơ cấp là kiểu dữ liệu mà giá trị của nó là đơn nhất”.
Ví
dụ: Kiểu int trong C
là kiểu sơ cấp gồm các số nguyên từ -32768..32767 và các phép toán: +, -, *, /, %…
Kiểu Dữ Liệu Có Cấu Trúc “Kiểu
dữ liệu có cấu trúc là kiểu dữ liệu mà các giá trị của nó là sự kết hợp của các giá trị khác”.
Ví
dụ : Kiểu chuỗi ký tự trong C.
là kiểu có cấu trúc. Ví dụ: char *chuoi = “Chao cac ban!”;
Ngôn Ngữ Lập Trình Khái
niệm về ngôn ngữ lập trình Chương trình dịch
Khái Niệm Về Ngôn Ngữ Lập Trình Ngôn
ngữ lập trình là một ngôn ngữ dùng để viết chương trình cho máy tính Ta có thể chia ngôn ngữ lập trình thành các loại sau:
Ngôn ngữ máy Hợp ngữ Ngôn ngữ cấp cao
Ngôn Ngữ Máy (machine language)
Là các chỉ thị dưới dạng nhị phân, can thiệp trực tiếp vào trong các mạch điện tử. Có thể được thực hiện ngay không cần qua bước trung gian nào. Tuy nhiên chương trình viết bằng ngôn ngữ máy dễ sai sót, cồng kềnh và khó đọc, khó hiểu vì toàn những con số 0 và 1.
Machine Language 10100110 01110110 00100110 00000000 11111010 11111010 01001110 10100110 11100110 10010110 11001110 00101110 10100110 01001110 11111010 01100110 01001110 10000110 etc... 3
Hợp Ngữ (Assembly language)
Bao gồm tên các câu lệnh và quy tắc viết các câu lệnh đó. Tên các câu lệnh bao gồm hai phần: Phần mã lệnh (English) chỉ phép toán cần thực hiện Phần địa chỉ chứa toán hạng của phép toán đó. Để máy thực hiện được một chương trình viết bằng hợp ngữ thì chương trình đó phải được dịch sang ngôn ngữ máy. Công cụ thực hiện việc dịch đó được gọi là Assembler.
Assembly Language MOV AL,a ; chuyển giá trị a vào thanh ghi ; AL ADD AL,b ; Cộng giá trị của thanh ghi AL ; với giá trị b
Ngôn Ngữ Cấp Cao (High level language )
Rất gần với ngôn ngữ con người.
Một chương trình viết bằng ngôn ngữ cấp cao được gọi là chương trình nguồn (source programs).
Để máy tính "hiểu" và thực hiện được các lệnh trong chương trình nguồn thì phải có một chương trình dịch để dịch chương trình nguồn thành dạng chương trình có khả năng thực thi.
Chương Trình Dịch Được
dùng để chuyển một chương trình nguồn sang chương trình đích. Có 2 dạng:
Thông dịch (interpreter):
Dịch từng lệnh một, dịch tới đâu thực hiện tới đó. Ví dụ: ngôn ngữ LISP.
Biên dịch (compiler):
Dịch toàn bộ chương trình nguồn thành chương trình đích rồi sau đó mới thực hiện. Ví dụ: Pascal, C...
Hết chương
LẬP TRÌNH CĂN BẢN Phần 2 - Chương 1 GIỚI THIỆU VỀ NGÔN NGỮ C & MÔI TRƯỜNG TURBO C 3.0 PDNghiệp
30
Nội dung Tổng
quan về ngôn ngữ lập trình C
Lịch sử Những đặc điểm của C
Môi
trường lập trình Turbo C
Lịch Sử (1)
Ngôn ngữ C được thiết kế bởi Dennis Ritchie ở phòng thí nghiệm Bell vào đầu những năm 1970. Sự phát triển của C dựa trên các ngôn ngữ đã có:
ALGOL 60 (1960), CPL (Cambridge, 1963), BCPL (Martin Richard, 1967), B (Ken Thompson, 1970)
C là ngôn ngữ lập trình cấp cao, được sử dụng rất phổ biến để lập trình hệ thống cùng với Assembler và phát triển các ứng dụng, dù rằng đang có sự chuyển đổi sang dùng C++.
90% của UNIX được viết bằng C
Lịch Sử (2) Dennis Ritchie(trái) và Ken Thompson trước hệ thống PDP-11 với 2 text-terminal (1972)
Lịch Sử (3)
Năm 1978, Dennis Ritchie và Brian Kernighan xuất bản 1 quyển sách mô tả ngôn ngữ C.
Dennis Ritchie (trái) và Kernighan
Lịch Sử (4) C
được chuẩn hóa vào năm 1989 bởi ANSI (American National Standards Institute), được biết như ANSI C. Được chuẩn hóa ISO (International standard) năm 1990 (chuẩn này cũng được ANSI chấp nhận và được biết như C89) Được cập nhật năm 1995 (C95) và 1999 (C99).
Những đặc điểm của C (1)
Tính cô đọng (compact):
Tính cấu trúc (structured):
C chỉ có 32 từ khóa chuẩn và 40 toán tử chuẩn. C có một tập hợp những chỉ thị lập trình: cấu trúc lựa chọn, lặp, … Đơn giản dễ hiểu.
Tính tương thích (compatible):
C có bộ tiền xử lý và Các thư viện chuẩn vô cùng phong phú Nên khi chuyển từ máy tính này sang máy tính khác các chương trình viết bằng C vẫn hoàn toàn tương thích.
Những đặc điểm của C (2)
Tính linh động (flexible):
Cú pháp rất uyển chuyển, chấp nhận nhiều cách thể hiện Có thể thu gọn kích thước của mã lệnh Làm chương trình chạy nhanh hơn
Biên dịch (compile):
C cho phép biên dịch nhiều tập tin chương trình riêng rẽ thành các tập tin đối tượng (object) và Liên kết (link) các đối tượng đó lại với nhau thành một chương trình có thể thực thi được (executable) thống nhất
Môi trường lập trình Turbo C Turbo
C do hãng Borland cung cấp. Có các chức năng: soạn thảo chương trình, dịch, thực thi chương trình, … Phiên bản được sử dụng ở đây là Turbo C 3.0
Gọi Turbo C
Soạn thảo chương trình mới
Vào menu File ->New
Gõ chương trình vào
#include <stdio.h> #include int main () { char ten[50]; printf(“Xin cho biet ten cua ban !”); scanf(“%s”,ten); printf(“Xin chao ban %s”,ten); getch(); return 0; }
Ghi chương trình đang soạn thảo vào đĩa
Sử dụng File->Save hoặc gõ phím F2 Lệnh Save As để lưu chương trình với tên khác
Tên hiện tại (tên cũ)
Tên mới ( kể cả tên thư mục)
Qui tắc đặt tên tập tin (file)
Theo quy tắc đặt tên tập tin của DOS. Tên của tập tin gồm 2 phần: phần tên và phần mở rộng.
Phần tên:
Phần mở rộng:
Bắt đầu là 1 ký tự từ a..z (không phân biệt hoa thường). Theo sau có thể là các ký tự từ a..z, các ký số từ 0..9 hay dấu gạch dưới (_), phần này dài tối đa là 8 ký tự. Dài tối đa 3 ký tự.
Ví dụ:
Tên đúng: CHAO.C, baitap2.c, chao_ban.c Tên sai: 1CHAO.C, chao+ban.c
Thực hiện chương trình + Mở một chương trình+ Thoát
Thực hiện chương trình
Mở một chương trình đã có trên đĩa
Nhấn Ctrl-F9 hoặc vào menu Run->Run
Vào menu File->Open hoặc nhấn F3
Thoát khỏi Turbo C
Vào menu File->Exit hoặc nhấn Alt-X
Các lệnh trên menu Option
Directories:
Include directories: chứa các tập tin ta muốn đưa vào chương trình (file .h trong dòng #include). Library directories: chứa các tập tin thư viện (file .lib) Output directory: chứa các tập tin “đối tượng “ .obj và .exe sau khi biên dịch chương trình. Source directories: chứa các tập tin “nguồn” (.obj và .lib).
Environment: dùng để thiết lập môi trường làm việc.
Hết chương
LẬP TRÌNH CĂN BẢN Phần 2 - Chương 2 CÁC THÀNH PHẦN CƠ BẢN CỦA NGÔN NGỮ C P.D.Nghiệp
Nội dung chương này Bộ
chữ viết trong C Các từ khóa Cặp dấu ghi chú thích Các kiểu dữ liệu sơ cấp chuẩn Tên và hằng Biến và biểu thức Cấu trúc của một chương trình C
Bộ chữ viết trong C Bộ
chữ viết trong ngôn ngữ C bao gồm các ký tự sau:
26 chữ cái latinh lớn A,B,C...Z 26 chữ cái latinh nhỏ a,b,c ...z. 10 chữ số thập phân 0,1,2...9. Các ký hiệu toán học: +, -, *, /, =, <, >, (, ) Các ký hiệu đặc biệt: :. , ; " ' _ @ # $ ! ^ [ ] { } ... Dấu cách hay khoảng trống.
Phân
biệt chữ in hoa và in thường
Các từ khóa trong C
Từ khóa là các từ dành riêng của C. Ta không được dùng từ khóa để đặt cho các tên của riêng mình.
Cặp dấu chú thích (comment) #include <stdio.h> #include int main (){ char ten[50]; /* khai bao bien ten kieu char 50 ky tu */ printf(“Xin cho biet ten cua ban !”); scanf(“%s”,ten); /*Doc vao 1 chuoi la ten ban*/ printf(“Xin chao ban %s\n ”,ten); //Dung chuong trinh, cho go phim getch(); return 0; }
Khi biên dịch các phần chú thích bị bỏ qua Dùng /* và */: chú thích dài nhiều dòng Dùng //: chú thích chỉ 1 dòng
Các kiểu dữ liệu sơ cấp chuẩn trong C Kiểu
số nguyên (integer) Kiểu số thực (real)
Kiểu số nguyên
Được dùng để lưu các giá trị nguyên hay còn gọi là kiểu đếm được.
Kiểu số nguyên 1 byte (8 bits)
Kiểu số nguyên 2 bytes (16 bits)
Kiểu số nguyên 4 byte (32 bits)
Kiểu số thực
Được dùng để lưu các số thực hay các số có dấu chấm thập phân
Kiểu void
Mang ý nghĩa là kiểu rỗng không chứa giá trị gì cả Ví dụ: void main(){ ….}
Dùng sizeof() Kích
thước 1 kiểu có thể được xác định lúc chạy chương trình (runtime), dùng sizeof:
Ví dụ: sizeof(double) =>8(byte) sizeof(long double)=>10(byte)
Kiểu enum (1)
enum gần giống với tiền xử lý #define. Nó cho phép ta định nghĩa 1 danh sách các bí danh (aliase) để trình bày các số nguyên. Ví dụ: #define MON 1 #define TUE 2 #define WED 3 có thể dùng enum: enum week { Mon=1, Tue, Wed, Thu, Fri Sat, Sun} days;
Ưu điểm của enum so với #define là nó có phạm vi (scope), nghĩa là 1 biến chỉ có tác dụng trong khối (block) nó được khai báo.
Kiểu enum (2)
Kiểu enum (3)
Tên và hằng trong C Tên
(identifier)
Được dùng để đặt cho chương trình, hằng, kiểu, biến, chương trình con, ... Có 2 loại:
Tên chuẩn: là tên do C đặt sẵn như tên kiểu: int, char, float,…; tên hàm: sin, cos... Tên do người lập trình tự đặt.
Chú ý khi đặt tên
Tên do người lập trình tự đặt
Ví dụ:
Tên đặt hợp lệ: Chieu_dai, Chieu_Rong, Chu_Vi Tên không hợp lệ: Do Dai, 12A2
Phải tuân thủ quy tắc:
Sử dụng bộ chữ cái, chữ số và dấu gạch dưới (_) Bắt đầu bằng một chữ cái hoặc dấu gạch dưới. Không có khoảng trống ở giữa tên. Không được trùng với từ khóa. Độ dài tối đa của tên là 32 ký tự, tuy nhiên cần đặt sao cho rõ ràng, dễ nhận biết và dễ nhớ. Không cấm việc đặt tên trùng với tên chuẩn nhưng khi đó ý nghĩa của tên chuẩn không còn giá trị nữa.
Hằng (Constant)
Là đại lượng không đổi trong suốt quá trình thực thi chương trình
=> không thể gán lạI giá trị cho hằng Hằng
có thể là:
1 con số 1 ký tự 1 chuỗi ký tự
Hằng số thực
Giá trị kiểu: float, double, long double 2 cách thể hiện
Cách 1: viết thông thường Ví
dụ: 123.34
-223.333 3.00 -56.0
Cách 2: viết theo số mũ hay số khoa học Một
số thực được tách làm 2 phần (phân cách bởi e/E)
Phần giá trị: như cách 1 Phần mũ: là một số nguyên
Ví
dụ: 1234.56e-3 = 1.23456 (là số 1234.56*10-3) -123.45E4 = -1234500 ( là -123.45*104)
Hằng số nguyên (1)
Hằng số nguyên 2 byte (int) hệ thập phân Sử dụng 10 ký số 0..9 Ví dụ: 123 (một trăm hai mươi ba) -242 (trừ hai trăm bốn mươi hai)
Hằng số nguyên 2 byte (int) hệ bát phân Sử dụng 8 ký số 0..7 Cách biểu diễn: 0 Số bát phân : 0d d d …d d ( d có giá trị từ 0..7) n n-1 n-2 1 0 i n
=> giá trị:
i d * 8 ∑ i i =0
Ví dụ: 020=2*81 + 0*80 =(16)10
Hằng số nguyên (2)
Hằng số nguyên 2 byte (int) hệ thập lục phân Là kiểu số nguyên dùng:
10 ký số 0..9 và 6 ký tự A, B, C, D, E ,F
Cách biểu diễn: 0x
Số thập lục phân : 0xdndn-1dn-2…d1d0 n
=> Giá trị thập phân=
Ví dụ:
i d * 16 ∑ i i =0
0x345=3*162 + 4*161 + 5*160 = (837)10 0x2A9= 2*162 + 10*161 + 9*160= (681)10
Hằng số nguyên (3) Ví
dụ: Kết quả của chương trình sau là gi?
Hằng số nguyên (4) Hằng
số nguyên 4 byte (long)
Được biểu diễn như số int trong hệ thập phân nhưng kèm theo ký tự l hoặc L. Ví dụ: 45345L hay 45345l hay 45345
Hằng ký tự (char)
Ví dụ: ‘a’, ‘A’, ‘0’, ‘9’ Là 1 ký tự được viết trong cặp dấu nháy đơn (‘). Mỗi một ký tự tương ứng với 1 giá trị trong bảng mã ASCII. Hằng ký tự cũng được xem như trị số nguyên. Chúng ta có thể thực hiện các phép toán số học trên 2 ký tự (dùng giá trị ASCII của chúng) ASCII = American Standard Code for Information Interchange
Hằng chuỗi ký tự
Ví dụ: “Ngon ngu lap trinh C” Là 1 chuỗi hay 1 xâu ký tự được đặt trong cặp dấu nháy kép (“). Chú ý: “” : chuỗi rỗng - không có nội dung Khi lưu trữ trong bộ nhớ, một chuỗi được kết thúc bằng ký tự NULL (‘\0’: mã Ascii là 0). Để biểu diễn ký tự đặc biệt bên trong chuỗi ta phải thêm dấu \ phía trước.
Ví
dụ:
Viết “I\’m a student” cho “I’m a student” Viết “Day la ky tu \“dac biet\”” cho “Day la ky tu “dac biet””
Biến và Biểu thức (variable and expression)
Biến dùng để chứa dữ liệu trong quá trình thực hiện chương trình. Giá trị của biến có thể bị thay đổi. Cú pháp khai báo biến: Danh sách các tên biến cách nhau bởi dấu phẩy;
Khởi tạo giá trị cho biến lúc khai báo
Ví dụ:
Cách viết giá trị cho biết luôn kiểu của nó:
Chú ý: 8864L có kiểu long, còn 8864 có kiểu int
Vị trí khai báo biến (1) Biến
ngoài
Được đặt bên ngoài tất cả các hàm Ảnh hưởng đến toàn bộ chương trình (biến toàn cục)
Vị trí khai báo biến (2) Biến
trong
Được đặt bên trong hàm, chương trình chính hay một khối lệnh Ảnh hưởng đến hàm, chương trình hay khối lệnh chứa nó (biến cục bộ).
Biểu thức (1)
Ví dụ: (-b + sqrt(Delta))/(2*a)
Biểu thức là một sự kết hợp giữa
Các toán tử (operator) và Các toán hạng (operand)
Các loại toán tử trong C
Toán tử số học Toán tử quan hệ và logic Toán tử Bitwise Toán tử ? Toán tử con trỏ & và * Toán tử dấu phẩy
Các toán tử số học (1)
Các toán tử số học (2)
• Tăng và giảm (++ & --) ++x hay x++ giống x = x + 1 --x hay x-- giống x = x – 1
• Tuy nhiên:
• Còn:
x = 10;
x = 10;
y = ++x; //y = 11, x=11
y = x++; //y = 10, x=11
Các toán tử số học (3)
Đâu
là sự khác nhau?
x++ trả về giá trị hiện hành của x và sau đó tăng x ++x tăng x trước và sau đó trả về giá trị mới của x
Biểu thức Boolean (boolean expression)
Chú ý! Không có kiểu Boolean rõ ràng trong C (điều này đã được giới thiệu ở C99). Thay vào đó C dùng các giá trị nguyên để tượng trưng cho giá trị Boolean, với qui ước: false
Giá trị 0
true
Bất kỳ giá trị nào ngoại trừ 0
Chú ý! C dùng “=” cho phép gán, và dùng “==“ cho phép so sánh. Nó trả về 1 nếu bằng và 0 nếu ngược lại
Các toán tử quan hệ và các toán tử Logic (1)
Các phép so sánh sau tạo ra các biểu thức logic có giá trị kiểu Boolean
Các toán tử quan hệ và các toán tử Logic (2)
Ví dụ:
Các
biểu thức logic trả về
0 nếu false(sai) 1 nếu true(đúng)
Các toán tử quan hệ và các toán tử Logic (3)
Bảng chân trị cho các toán tử Logic
Thứ tự ưu tiên
Ví dụ: 10>5&&!(10<9)||3<=4
=> đúng (1)
Các toán tử Bitwise
Toán tử Bitwise giúp kiểm tra, gán hay thay đổi các bit thật sự trong 1 byte của word. Chỉ dùng cho kiểu char và int.
Toán tử ?
Toán tử ? thực hiện như lệnh if-else.
Cú pháp:
E1 ? E2 : E3
Ví dụ:
X = (10 > 9) ? 100 : 200; =>X=100 X = (10 >15 )? 100 : 200; =>X=200
Toán tử con trỏ & và *
Ví dụ: int *p; //con tro so nguyen int count=5, x; p = &count; =>Đặt vào biến m địa chỉ bộ nhớ của biến count
Toán tử * trả về nội dung của ô nhớ mà một con trỏ đang chỉ vào
Ví dụ: x = *p; // x=5
Toán tử dấu phẩy
Ví dụ:
x = (y=3,y+1); Trước hết gán 3 cho y rồi gán 4 cho x.
Được sử dụng để kết hợp các biểu thức lại với nhau. Bên trái của dấu (,) luôn được xem là kiểu void. Biểu thức bên phải trở thành giá trị của tổng các biểu thức được phân cách bởi dấu phẩy.
Tổng kết về độ ưu tiên Tổng
kết về độ ưu tiên
Phép gán được viết gọn lại x= x y; có thể được viết gọn lại (short form):
Các tập tin thư viện thông dụng
stdio.h: Định nghĩa các hàm vào/ra chuẩn (standard input/output):printf(), scanf(), getc(), putc(), gets(), puts(), fflush(), fopen(), fclose(), fread(), fwrite(), getchar(), putchar(), getw(), putw()… conio.h: Định nghĩa các hàm vào ra trong chế độ DOS: clrscr(), getch(), getche(), getpass(), cgets(), cputs(), putch(), clreol(),… math.h: Định nghĩa các hàm tính toán: abs(), sqrt(), log(). log10(), sin(), cos(), tan(), acos(), asin(), atan(), pow(), exp(),… alloc.h: Định nghĩa các hàm liên quan đến việc quản lý bộ nhớ: calloc(), realloc(), malloc(), free(), farmalloc(), farcalloc(), farfree(), … io.h: Định nghĩa các hàm vào ra cấp thấp: open(), _open(), read(), _read(), close(), _close(), creat(), _creat(), creatnew(), eof(), filelength(), lock(),… graphics.h: Định nghĩa các hàm liên quan đến đồ họa: initgraph(), line(), circle(), putpixel(), getpixel(), setcolor(), …
Cấu trúc của 1 chương trình C (1)
Cấu trúc một chương trình C Tiền xử lý và biên dịch Prototype Các tập tin thư viện thông dụng
Cấu trúc của 1 chương trình C (2) Các chỉ thị tiền xử lý Định nghĩa kiểu mới
Chương trình chính
Prototype Khai báo biến ngoài
Cài đặt các hàm
Tiền xử lý và biên dịch (preprocess and compile)
Các chỉ thị định hướng (directive):
#include…, #define… Có thể chứa các lệnh phức tạp như if-else.
Bộ tiền xử lý (preprocessor) sẽ thông dịch các directive và xóa bỏ nó trước khi cung cấp cho trình biên dịch C.
#define
#define khai báo một tên macro (macro symbol). Sau đó, mỗi lần tên macro này xuất hiện, nó sẽ được thay thế bởi giá trị của nó.
Chia chương trình ra các module (1)
1 chương trình phức tạp có thể được chia ra vài module
Chia chương trình ra các module (2)
Vấn đề: testmodule.c phải biết các prototype của foor và bar. Giải pháp 1 (tệ):
Chèn tay các prototype vào các file .c có dùng nó. Bất lợi: Mỗi khi prototype bị thay đổi => phải chỉnh lại prototype trong tất cả các file .c dùng nó.
Giải pháp 2 (tốt):
Lưu các prototype vào 1 file riêng biệt mymodule.h (h: header). Dùng #include mymodule.h ở đầu các chương trình có dùng nó.
#include
Với #include, bộ tiền xử lý sẽ thêm và thay thế token #include filename bằng nội dung của filename.
Các header file sẽ được tìm ở đâu?
#include : tìm file.h trong thư mục đã được xác định trong INCLUDE DIRECTORIES. Hoặc trong /usr/include (linux) #include “C:\\TC\\file.h”: tìm file.h trong đường dẫn
Header file Các
header file có thể chứa:
Prototype cho các hàm (function) Định nghĩa kiểu (structs, unions, enums, typedefs) (Định nghĩa các class trong C++) #define macro #pragma cho compiler Các biến toàn cục Cài đặt trực tiếp các hàm
Hết chương
LẬP TRÌNH CĂN BẢN Phần 2 - Chương 3 CÁC CÂU LỆNH ĐƠN TRONG C P.D.Nghiệp
Nội dung chương này Câu
lệnh
Khái niệm câu lệnh Phân loại
Các lệnh đơn
Lệnh gán Lệnh nhập giá trị từ bàn phím cho biến Lệnh xuất giá trị của biểu thức lên màn hình
Khái niệm câu lệnh “1
câu lệnh xác định 1 công việc mà chương trình phải thực hiện” Kết thúc bởi ;
Phân loại Có
Lệnh đơn
2 loại Không chứa 1 lệnh nào khác Gồm: lệnh gán, nhập, xuất
Lệnh có cấu trúc
Chứa các lệnh khác Gồm:
cấu trúc điều kiện rẽ nhánh cấu trúc điều kiện lựa chọn cấu trúc lặp cấu trúc lệnh hợp thành
Các lệnh đơn Lệnh gán Lệnh nhập giá trị từ bàn phím cho biến Lệnh xuất giá trị của biểu thức lên màn hình
Lệnh gán (1)
Ví dụ:
Cú pháp: = ;
Ý nghĩa: Gán giá trị cho 1 biến
Gán giá trị ngay tại lúc khai báo:
Lệnh gán (2)
Kiểu của biểu thức và của biến phải giống nhau
Error: "Cannot convert ‘char *’ to ‘int’"
Lệnh gán (3)
Thường thì có sự chuyển đổi kiểu tự động nếu có thể.
Chuyển được
Lệnh gán (4)
Kết quả chương trình sau là gì?
Lệnh gán (5)
Trong C, các chuyển đổi kiểu sau được làm tự động.
Những chuyển đổi trên đảm bảo không làm mất đi sự chính xác (loss of precision). Việc chuyển đổi theo các hướng khác có thể làm mất sự chính xác Ví dụ:
Lệnh gán (6) Ép
kiểu (casting type)
Lệnh nhập giá trị từ bàn phím cho biến (1)
scanf đọc dữ liệu từ bàn phím và gán vào biến
Chuỗi định dạng (format string): để qui định kiểu dữ liệu, cách biểu diễn, độ rộng, số chữ số thập phân, …
Lệnh nhập giá trị từ bàn phím cho biến (2)
scanf phải lưu giá trị vào 1 biến
scanf(“%d”,anInt): không đúng, vì anInt xác định giá trị hiện hành của 1 biến. scanf(“%d”,&anInt): đúng, vì địa chỉ của anInt đã được xác định.
Ví dụ - Dùng Standard Input
Lệnh xuất giá trị của biểu thức lên màn hình (1)
Cần ít nhất 1 đối số. Đối số đầu tiên là 1 chuỗi Chuỗi có thể chứa:
Ví dụ:
Output
Lệnh xuất giá trị của biểu thức lên màn hình (2)
Nếu muốn in ra các biến và biểu thức, ta truyền nó vào printf như các đối số. Các định dạng (format) khác nhau cho các kiểu giá trị khác nhau (dùng %).
Lệnh xuất giá trị của biểu thức lên màn hình (3) Các
định dạng:
Ví dụ - Output từ C Hết chương
Giải thích thêm về printf
Hết chương
LẬP TRÌNH CĂN BẢN Phần 2 - Chương 4
CÁC LỆNH CÓ CẤU TRÚC P.D.Nghiệp
Nội dung chương này Khối
lệnh trong C Cấu trúc rẽ nhánh Cấu trúc lựa chọn Cấu trúc vòng lặp Các câu lệnh “đặc biệt”
Khối lệnh trong C (1) Là
1 dãy các khai báo cùng với các câu lệnh nằm trong cặp dấu ngoặc móc { và }.
Khối lệnh trong C (2) 1
khối lệnh có thể chứa nhiều khối lệnh khác gọi là khối lệnh lồng nhau (không hạn chế).
Phạm vi các biến Có thể khai báo các biến cùng tên trong các khối. Nếu một biến được khai báo bên ngoài khối lệnh và không trùng tên với biến bên trong khối lệnh thì nó cũng dùng được bên trong khối. Một khối lệnh con có thể sử dụng các biến bên ngoài, nhưng điều ngược lại không đúng.
Cấu trúc rẽ nhánh (if)
Statement được thực hiện nếu boolean_expression có giá trị đúng (true), !=0.
Khối else là tùy chọn
boolean_expression !=0 => Statement1 được thực hiện boolean_expression ==0 => Statement2 được thực hiện
Ví dụ - Lệnh if #include <stdio.h> #include int main (){ float a; printf("Nhap a = "); scanf("%f",&a); if (a !=0 ) printf("Nghich dao cua %f la %f",a,1/a); getch(); return 0; }
Ví dụ - Lệnh if-else #include <stdio.h> #include int main (){ float a; printf("Nhap a = "); scanf("%f",&a); if (a !=0 ) printf("Nghich dao cua %f la %f",a,1/a); else printf(“Khong a”); getch(); return 0; }
the
tim
duoc
nghich
dao
cua
Câu lệnh và khối lệnh
C cho phép nhóm các câu lệnh liên tiếp vào 1 khối. 1 khối lệnh có thể được dùng như 1 lệnh đơn. Ví dụ:
Nhầm lẫn khi dùng if
Chương trình trên sai ở đâu?
Chú ý khi dùng if-else
Câu lệnh if-else lồng nhau else sẽ kết hợp với if gần nhất chứa có else Trong trường if bên trong không có else thì phải viết nó trong cặp dấu {} để tránh sự kết hợp else if sai. Ví dụ
Cấu trúc lựa chọn (switch-case) (1)
C cung cấp 1 cấu trúc đẹp - dùng 1 dãy các câu lệnh if.
Cấu trúc lựa chọn (switch-case) (2)
switch-case có thể đưa đến mã máy (machine code) hiệu quả hơn (vì jump tables có thể được dùng)
Cấu trúc lựa chọn (switch-case) (3)
Cú pháp:
Tính giá trị của biểu thức expr trước. Nếu giá trị expr bằng value1 thì thực hiện statement_sequence1 rồi thoát. Nếu giá trị expr khác value1 thì so sánh nó với value2, nếu bằng value2 thì thực hiện statement_sequence2 rồi thoát. Cứ như thế, so sánh tới giá trị n. Nếu tất cả các phép so sánh trên đều sai thì thực hiện default_statements của trường hợp default.
Cấu trúc lựa chọn (switch-case) (4) Các
chú ý:
Kiểu của expr và các valuei phải là kiểu số nguyên (int, chat, long, …). Nếu break/return vắng mặt, câu lệnh trong các case bên dưới có thể được thực hiện cho đến khi gặp break/return hoặc kết thúc lệnh switch.
Ví dụ - switch-case (1)
Ví dụ - switch-case (2)
In ra số ngày của 1 tháng
Cấu trúc lặp
Cho phép lặp lại thực hiện 1 công việc nhiều lần. Có 2 loại:
Lặp với số lần xác định for Lặp với số lần không xác định while do-while
Vòng lặp for (1) for (Biểu thức 1; biểu thức 2; biểu thức 3) ;
Thứ tự thực hiện: B1: Tính giá trị biểu thức 1 B2: Tính giá trị biểu thức 2 Nếu
giá trị biểu thức 2 là sai (==0) => thoát khỏi for Nếu giá trị biểu thức 2 là đúng (!=0) => thực hiện B3: Tính giá trị biểu thức 3 rồi quay lại B2
Vòng lặp for (2)
Vòng lặp for (2) Chương
output
trình in dãy số nguyên từ 1..10
Vòng lặp for (3)
Nhập số nguyên n. Tính tổng các số nguyên từ 1..n.
output
Vòng lặp while (1) while (Biểu thức điều kiện) ;
: có thể là 1 câu lệnh hay 1 khối lệnh. Các bước thực hiện: - Kiểm tra Biểu thức điều kiện trước. - Nếu điều kiện sai (==0) thì thoát khỏi lệnh while. - Nếu điều kiện đúng (!=0) thì thực hiện công việc rồi quay lại kiểm tra điều kiện tiếp.
Vòng lặp while (2) Chương
output
trình in dãy số nguyên từ 1..10
Vòng lặp while (3)
Nhập số nguyên n. Tính tổng các số nguyên từ 1..n.
output
Vòng lặp do-while (1) do while ();
: có thể là 1 câu lệnh hay 1 khối lệnh. Các bước thực hiện:
Công việc được thực hiện trước, sau đó mới kiểm tra điều kiện. Nếu điều kiện sai thì thoát khỏi lệnh dowhile. Nếu điều kiện còn đúng thì thực hiện công việc rồi quay lại kiểm tra điều kiện tiếp.
Vòng lặp do-while (2) Chương
output
trình in dãy số nguyên từ 1..10
Vòng lặp do-while (3)
Nhập số nguyên n. Tính tổng các số nguyên từ 1..n.
output
So sánh các vòng lặp Vòng
Kiểm tra điều kiện trước thực hiện công việc sau. Công việc có thể không được thực hiện lần nào. Vòng lặp kết thúc khi nào điều kiện sai.
Vòng
lặp for/while:
lặp do-while
Thực hiện công việc trước kiểm tra điều kiện sau. Công việc được thực hiện ít nhất 1 lần. Vòng lặp kết thúc khi nào điều kiện sai.
Câu lệnh đặc biệt
Lệnh break
Dùng để thoát khỏi vòng lặp hoặc switch-case. Tiếp tục thực hiện lệnh liền sau đó.
Lệnh continue
Trong vòng lặp, khi gặp lệnh continue, chương trình sẽ bỏ qua các câu lệnh sau continue
for: quay lên tính trị cho biểu thức 3, rồi kiểm tra điều kiện coi có lặp tiếp không. while/do-while: kiểm tra điều kiện coi có lặp tiếp không.
Hết chương
LẬP TRÌNH CĂN BẢN Phần 2 - Chương 5
CHƯƠNG TRÌNH CON P.D.Nghiệp
Nội dung chương này Ví
dụ Khái niệm về hàm trong C Xây dựng một hàm Truyền tham số cho hàm Hàm đệ qui
Ví dụ (1)
In ra 50 ký tự ‘*’ và 50 ký tự ‘+’
Ví dụ (2) Đâu
là ưu điểm của việc dùng hàm?
Khái niệm về hàm trong C (1)
Để tránh rườm rà và mất thời gian khi viết chương trình, những đoạn chương trình lặp đi lặp lại nhiều lần được viết trong 1 module. Chia chương trình thành nhiều module, mỗi module giải quyết 1 công việc nào đó. Mỗi module như trên được gọi là 1 chương trình con. Các module dễ dàng được kiểm tra tính đúng đắn trước khi được ráp nối vào chương trình.
Khái niệm về hàm trong C (2) Ví
dụ: Tìm số lớn nhất trong 3 số a, b, và c.
Khái niệm về hàm trong C (3) Có
2 loại hàm:
Hàm chuẩn Hàm tự định nghĩa
Hàm chuẩn (hàm thư viện)
Được định nghĩa sẵn bởi ngôn ngữ lập trình và được chứa vào các thư viện. Muốn sử dụng phải khai báo #include Một số thư viện thường dùng trong C:
stdio.h : Thư viện chứa các hàm vào/ ra chuẩn (standard input/output): printf(), scanf(), getc(), putc(), gets(), puts(), fflush(), fopen(), fclose(), fread(), fwrite(), getchar(), putchar(), getw(), putw(), … conio.h : Thư viện chứa các hàm vào ra trong chế độ DOS (DOS console): clrscr(), getch(), getche(), getpass(), cgets(), cputs(), putch(), clreol(), … math.h: Thư viện chứa các hàm tính toán: abs(), sqrt(), log(). log10(), sin(), cos(), tan(), acos(), asin(), atan(), pow(), exp(), … alloc.h: Thư viện chứa các hàm liên quan đến việc quản lý bộ nhớ: calloc(), realloc(), malloc(), free(), farmalloc(), farcalloc(), farfree(), … io.h: Thư viện chứa các hàm vào ra cấp thấp: open(), _open(), read(), _read(), close(), _close(), creat(), _creat(), creatnew(), eof(), filelength(), lock(), … graphics.h: Thư viện chứa các hàm liên quan đến đồ họa:initgraph(), line(), circle(), putpixel(), getpixel(), setcolor(), …
Hàm tự định nghĩa (hàm người dùng) (1)
Do người lập trình tự tạo ra nhằm đáp ứng nhu cầu xử lý của mình.
Cấu trúc của một hàm tự thiết kế:
Hàm tự định nghĩa (hàm người dùng) (2) Cú
pháp gọi hàm:([Danh sách các tham số]) Ví dụ: Tìm UCLN của 2 số tự nhiên:
Nguyên tắc hoạt động của hàm Trong
chương trình, khi gặp một lời gọi hàm thì các bước sau được thực hiện:
Nếu hàm có tham số, trước tiên các tham số sẽ được gán giá trị thực tương ứng. Chương trình sẽ thực hiện tiếp các câu lệnh trong thân hàm bắt đầu từ lệnh đầu tiên đến câu lệnh cuối cùng. Khi gặp lệnh return hoặc dấu } cuối cùng trong thân hàm, chương trình sẽ thoát khỏi hàm để trở về chương trình gọi nó. Thực hiện tiếp tục những câu lệnh của chương trình.
Truyền tham số cho hàm (1)
Ví dụ: Hoán đổi nội dung của 2 biến
Truyền tham số cho hàm (2)
Ta vẫn chưa hoán vị được! Tại sao?
2 tham số a và b của hoanvi là tham số hình thức được truyền bằng giá trị (tham trị). 1
tham trị được coi như 1 biến cục bộ của hàm, chứa dữ liệu đầu vào cho hàm.
Còn 2 tham số a,b của hoanvi trong lời gọi hàm trong main() là tham số thực. Khi chương trình con được gọi để thi hành, tham trị được cấp ô nhớ và nhận giá trị là bản sao giá trị của tham số thực. Do đó, mọi sự thay đổi trên tham trị không ảnh hưởng gì đến tham số thực tương ứng.
Truyền tham số cho hàm (3)
Hãy xem chương trình sau
Truyền tham số cho hàm (4) Tại
sao ta đã hoán vị được?
2 tham số a và b của hoanvi là tham số hình thức được truyền bằng địa chỉ (tham biến) – con trỏ. Khi chương trình con (ctc) được gọi để thi hành, tham biến chứa địa chỉ tham số thực, ô nhớ của tham số thực được dùng trực tiếp trong ctc qua biến con trỏ. Do đó, mọi sự thay đổi trên tham biến đều ảnh hưởng đến tham số thực tương ứng.
Hàm đệ quy Một
hàm được gọi là đệ quy nếu bên trong thân hàm có lệnh gọi đến chính nó. Ví dụ:
unsigned int giaithua_dequy(int n)
1 nếu n=0 n!=
{
n*(n-1)! nếu n#0
if (n==0) return 1; else return n*giaithua_dequy(n-1); }
Đặc điểm cần lưu ý khi viết hàm đệ quy Hàm
Phần dừng: là trường hợp nguyên tố.
đệ quy phải có 2 phần:
Ví dụ: n=0 trong tính n!
Phần đệ quy: là phần có gọi lại hàm đang được định nghĩa.
Ví dụ: nếu n>0 thì n! = n * (n-1)!
Ưu và khuyết điểm của đệ quy
Làm chương trình dễ đọc, dễ hiểu và vấn đề được nêu bật rõ ràng hơn. Đệ quy tốn bộ nhớ nhiều hơn và tốc độ thực hiện chương trình chậm hơn không đệ quy. Tùy từng bài cụ thể mà ta quyết định có nên dùng đệ quy hay không. Có những trường hợp không dùng đệ quy thì không giải quyết được bài toán.
Hết chương Hết chương
LẬP TRÌNH CĂN BẢN Phần 2 - Chương 6
KIỂU MẢNG P.D.Nghiệp
Nội dung chương này Giới
thiệu kiểu mảng trong C Mảng 1 chiều Mảng nhiều chiều
Giới thiệu kiểu mảng trong C (1) Ví
dụ: int a[10]; => Hình ảnh của a trong bộ nhớ như sau:
Giới thiệu kiểu mảng trong C (2)
“Mảng là một tập hợp các phần tử cố định có cùng một kiểu, gọi là kiểu phần tử”.
Kiểu phần tử có thể là có kiểu bất kỳ:
ký tự số 1 struct 1 mảng khác (=> mảng của mảng hay mảng nhiều chiều) …;
Giới thiệu kiểu mảng trong C (3)
Ví dụ: Lưu trữ 1 đa giác trong đồ họa:
typedef struct { int x; int y; } Point;
Points[1]
Points[0]
typedef struct{ Point Points[100]; int nPoints; } Polygon;
Points[2]
Points[3]
Giới thiệu kiểu mảng trong C (4)
Ta có thể chia mảng làm 2 loại:
Mảng 1 chiều Mảng nhiều chiều
Mảng 1 chiều (1)
Xét dưới góc độ toán học, mảng 1 chiều giống như một vector. Mỗi phần tử của mảng 1 chiều có giá trị không phải là một mảng khác.
Khai báo mảng với số phần tử xác định Ví dụ: float a[100]; Cú pháp: <[số phần tử]>;
Khai báo mảng với số phần tử không xác định Ví dụ: float a[]; Cú pháp: <[]> ;
Mảng 1 chiều (2)
Vừa khai báo vừa gán giá trị []= {Các giá trị cách nhau bởi dấu phẩy} ;
=> Số phần tử có thể được xác định bằng sizeof() Số phần tử=sizeof(tên mảng)/sizeof(kiểu)
Khai báo mảng là tham số hình thức của hàm
không cần chỉ định số phần tử của mảng là bao nhiêu
Mảng 1 chiều (3)
Ví dụ: Gán giá trị ngay lúc khai báo int primes[] = {2,3,5,7,11,13}; Sẽ tương đương với: int primes[6]; primes[0] = 2; primes[1] = 3; =>sizeof(primes)/sizeof(int)=6 primes[2] = 5; primes[3] = 7; primes[4] = 11; primes[5] = 13;
Truy xuất từng phần tử của mảng (1) Cú
Ví
pháp: Tên biến mảng[Chỉ số]
dụ 1:
int a[10]; a[0]=5; a[1]=5; a[2]=33; a[3]=33; a[4]=15; printf(“%d %d %d %d %d”, a[0], a[1], a[2], a[3], a[4]);
Truy xuất từng phần tử của mảng (2)
Ví dụ 2: Vừa khai báo vừa gán trị cho 1 mảng 1 chiều các số nguyên. In mảng số nguyên này lên màn hình.
Truy xuất từng phần tử của mảng (3)
Ví dụ 3: Đổi một số nguyên dương thập phân thành số nhị phân.
Truy xuất từng phần tử của mảng (4)
Ví dụ 4: Nhập vào một dãy n số và sắp xếp các số theo thứ tự tăng.
Truy xuất từng phần tử của mảng (5)
Ví dụ 5: Chương trình sau sẽ hiển thị kết quả gì?
Sửa lỗi này thế nào?
Các phần tử của mảng a[0], …, a[11]. Việc truy cập a[12] sẽ vượt ra bên ngoài mảng, ô nhớ của biến b.
Mảng nhiều chiều
Mảng nhiều chiều là mảng có từ 2 chiều trở lên. Điều đó có nghĩa là mỗi phần tử của mảng là một mảng khác. Người ta thường sử dụng mảng nhiều chiều để lưu các ma trận, các tọa độ 2 chiều, 3 chiều…
Khai báo mảng 2 chiều tường minh Cú
pháp: <[Số phần tử chiều 1]><[Số phần tử chiều 2]> ;
Ví
dụ: float m[8][9]; // mảng 2 chiều có 8*9 phần tử là số thực
Khai báo mảng 2 chiều không tường minh
Để khai báo mảng 2 chiều không tường minh, ta vẫn phải chỉ ra số phần tử của chiều thứ hai (chiều cuối cùng).
Cú pháp: <[]><[Số phần tử chiều 2]>; Ví dụ:
float m[][9];
Cách khai báo này cũng được áp dụng trong trường hợp:
vừa khai báo vừa gán trị
mảng 2 chiều là tham số hình thức của 1 hàm.
Truy xuất từng phần tử của mảng 2 chiều
Dùng: Tên mảng[Chỉ số 1][Chỉ số 2]
Ví dụ (1)
Viết chương trình cho phép nhập 2 ma trận a, b có m dòng n cột, thực hiện phép toán cộng hai ma trận a,b và in ma trận kết quả lên màn hình.
Ví dụ (2)
Hết chương
Hết chương
LẬP TRÌNH CĂN BẢN Phần 2 - Chương 7
KIỂU CON TRỎ P.D.Nghiệp
Nội dung chương này Giới
thiệu kiểu dữ liệu con trỏ Khai báo và sử dụng biến con trỏ Con trỏ và mảng Con trỏ và tham số hình thức của hàm
Giới thiệu kiểu dữ liệu con trỏ (pointer) (1)
1 con trỏ là 1 biến được dùng để chứa địa chỉ của ô nhớ trong bộ nhớ. Kích thước của biến con trỏ luôn là 2 byte.
Ví dụ 1:
float a=3.145; float* ptr; //ptr is a pointer ptr=&a;
pointer ptr FFF2
variable a 3.145 FFF2 (address)
Giới thiệu kiểu dữ liệu con trỏ (2)
Ví dụ 2: In Linux
Khai báo và sử dụng biến con trỏ Khai
báo biến con trỏ Các thao tác trên con trỏ
Khai báo biến con trỏ int a, b, *pa, *pb; //pa và pb sẽ chỉ đến biến int float f, *pf; //pa và pb sẽ chỉ đến biến float void *ptr; //ptr sẽ chỉ vào bất kỳ biến kiểu gì Cú
pháp: *;
Ý nghĩa: Khai báo một biến có tên là Tên con trỏ dùng để chứa địa chỉ của các biến có kiểu Kiểu.
Các thao tác trên con trỏ
Gán địa chỉ của biến cho biến con trỏ Nội dung của ô nhớ con trỏ chỉ tới Cấp phát vùng nhớ cho biến con trỏ Cấp phát lại vùng nhớ cho biến con trỏ Giải phóng vùng nhớ cho biến con trỏ Một số phép toán trên con trỏ
Gán địa chỉ của biến cho biến con trỏ + Nội dung của ô nhớ con trỏ chỉ tới (1)
Dùng & để lấy ra địa chỉ bộ nhớ (memory address) của 1 biến int a=6; int* c= &a; // &a là địa chỉ bộ nhớ của biến a Dùng * để truy cập (access) đến nội dung (content) của biến mà 1 con trỏ đang chỉ đến int a=6; int* c= &a; *c=7; /*Thay đổi nội dung của biến a bằng cách dùng địa chỉ của nó được chứa trong con trỏ c*/ tương đương với a=7;
Gán địa chỉ của biến cho biến con trỏ + Nội dung của ô nhớ con trỏ chỉ tới (2)
Gán địa chỉ của biến cho biến con trỏ + Nội dung của ô nhớ con trỏ chỉ tới (3) Lưu
ý:
=> Error! Vì đã cho 1 con trỏ chỉ đến 1 biến khác kiểu với nó
Cấp phát vùng nhớ cho biến con trỏ(1)
Có 2 cách để dùng được biến con trỏ 1. Cho nó chứa địa chỉ của 1 vùng nhớ đang tồn tại int a=6; int* c= &a; // &a là địa chỉ bộ nhớ của biến a 1. Cấp phát 1 vùng nhớ mới, rồi cho con trỏ chỉ đến int* ptr; ptr = (int*)malloc(sizeof(int)); *ptr=6; pointer ptr FFFA
6 FFFA (address)
Cấp phát vùng nhớ cho biến con trỏ(2)
void *malloc(size_t size): Cấp phát vùng nhớ có kích thước là size (byte) void *calloc(size_t nitems, size_t size): Cấp phát vùng nhớ có kích thước là nitems*size (byte) Ví dụ: int a, *pa, *pb; pa = (int*)malloc(sizeof(int)); /* Cấp phát vùng nhớ có kích thước bằng với kích thước của một số nguyên */ pb= (int*)calloc(10, sizeof(int)); /* Cấp phát vùng nhớ có thể chứa được 10 số nguyên*/
Cấp phát lại vùng nhớ cho biến con trỏ
int a, *pa; pa = (int*)malloc(sizeof(int)); /*Cấp phát vùng nhớ có kích thước 2 byte*/ pa = realloc(pa, 6); /*Cấp phát lại vùng nhớ có kích thước mới là 6 byte*/ void *realloc(void *block, size_t size):
Ý nghĩa: Cấp phát lại 1 vùng nhớ do con trỏ block quản lý, vùng nhớ này có kích thước mới là size; khi cấp phát lại thì nội dung vùng nhớ trước đó được copy đến vùng nhớ mới. Kết quả trả về của hàm là địa chỉ đầu tiên của vùng nhớ mới. Địa chỉ này có thể khác với địa chỉ được chỉ ra khi cấp phát ban đầu. Kết quả là NULL nếu không cấp phát được.
Giải phóng vùng nhớ cho biến con trỏ void
free(void *block): Giải phóng vùng nhớ được quản lý bởi con trỏ block
Ví
dụ free(pa); free(pb); => giải phóng vùng nhớ do 2 biến con trỏ pa & pb đang chỉ đến
Một số phép toán trên con trỏ Phép
gán = Phép so sánh == và != Cộng, trừ con trỏ với 1 số nguyên Gán NULL cho 1 con trỏ
Phép gán và phép so sánh
Ví dụ: Hiện tại ta có: int a=10, b=15; int *p, *q; float *f; p=&a; q=&b;
p FFF2 q
10 FFF2 (address) b
FFFA
Bây giờ thì phép so sánh: (p!=q) => true (1)
a
15 FFFA (address)
p
Thực hiện tiếp lệnh gán: FFFA p=q; Bây giờ thì: q FFFA (p==q) => true (1) Lệnh f=p; =>Error, do khác kiểu Nhưng lệnh f=(float*)p; =>No error
a 10 FFF2 (address) b 15 FFFA (address)
Cộng, trừ con trỏ với 1 số nguyên
Ta có thể cộng (+), trừ (-) 1 con trỏ với 1 số nguyên N nào đó Kết quả trả về là 1 con trỏ. Con trỏ này chỉ đến vùng nhớ cách vùng nhớ của con trỏ hiện tại N phần tử. Ví dụ: Cho đoạn chương trình sau: int *pa; int *pb, *pc; pa = (int*) malloc(20); /*Cấp phát vùng nhớ 20 byte=10 số nguyên*/ pb = pa + 7; pc = pb - 3;
Lúc này hình ảnh của pa, pb, pc như sau:
Gán NULL cho 1 con trỏ Ví
dụ: int x=25; int *ptr; ptr=&x; ptr=NULL;
Lệnh
gán ptr=NULL => cho con trỏ ptr không trỏ vào (không chứa địa chỉ) vùng nhớ nào cả
Con trỏ và mảng (1)
Mảng và con trỏ có mối liên hệ với nhau Thay vì truy cập 1 phần tử mảng bằng chỉ số của nó, ta có thể dùng 1 con trỏ
Để truy cập phần tử thứ i, a[i]: y= *(pa+i); Chú ý: pa+1 không phải cộng 1 vào pa. Thay vào đó, địa chỉ là pa+sizeof(*pa)
Con trỏ và mảng (2)
1 mảng có thể được xem như một con trỏ. Con trỏ này đang chỉ đến phần tử đầu tiên của mảng. Do đó:
1 mảng có thể được dùng làm tham số cho 1 hàm
Con trỏ và mảng (3)
x sẽ có giá trị của a[i] nào, tại mỗi lệnh gán sau?
Con trỏ và tham số hình thức của hàm (1)
Ví dụ 1: Viết 1 hàm để tăng giá trị của biến lên 1
Con trỏ và tham số hình thức của hàm (2)
Đâu
là sự khác nhau giữa tham số a và b?
Con trỏ và tham số hình thức của hàm (3)
Ví dụ 2: Viết hàm hoán đổi nội dung 2 biến
Con trỏ và tham số hình thức của hàm (4)
Ví dụ 3: Viết lại hàm hoán vị như sau:
Con trỏ và tham số hình thức của hàm (5)
Tại sao hàm trên có thể hoán vị được?
Hết chương
Hết chương
LẬP TRÌNH CĂN BẢN Phần 2 - Chương 8
CHUỖI KÝ TỰ P.D.Nghiệp
Nội dung chương này Khái
niệm Khai báo Các thao tác trên chuỗi ký tự
Khái niệm Chuỗi ký tự là một dãy gồm các ký tự hoặc một mảng các ký tự được kết thúc bằng ký tự ‘\0’ (ký tự NULL trong bảng mã Ascii). Các hằng chuỗi ký tự được đặt trong cặp dấu nháy kép “”.
Khai báo Khai
báo theo mảng Khai báo theo con trỏ Vừa khai báo vừa gán giá trị
Khai báo theo mảng
Cú pháp: Ví dụ:
char [Chiều dài tối đa]; char Ten[12];
=> bộ nhớ sẽ cung cấp 12+1 bytes để lưu trữ nội dung của chuỗi ký tự Ten; byte cuối cùng lưu trữ ký tự ‘\0’ để chấm dứt chuỗi Ten:
‘\0’ Ten[0]
Ghi chú: Chiều dài tối đa của biến chuỗi: 1..255 bytes. Không nên khai báo thừa để tránh lãng phí bộ nhớ.
Ten[12]
Khai báo theo con trỏ
Cú pháp: Ví dụ:
char *; char *Ten;
Trong khai báo này, bộ nhớ sẽ dành 2 byte để lưu trữ địa chỉ của biến con trỏ Ten đang chỉ đến. Chưa cung cấp nơi để lưu trữ dữ liệu. Muốn có chỗ để lưu trữ dữ liệu, ta phải gọi đến hàm malloc() hoặc calloc() có trong “alloc.h”, sau đó mới gán dữ liệu cho biến.
Tieu Dong Tu
Vừa khai báo vừa gán giá trị
Cú pháp: char []=<”Hằng chuỗi”>;
Ví dụ:
Vua khai bao vua gan trị : Mau nang hay la mau mat em
Ghi chú: Chuỗi được khai báo là một mảng các ký tự nên các thao tác trên mảng có thể áp dụng đối với chuỗi ký tự.
Các thao tác trên chuỗi ký tự
Nhập xuất chuỗi
Nhập chuỗi từ bàn phím
Xuất chuỗi lên màn hình
Một số hàm xử lý chuỗi (trong string.h)
Nhập chuỗi từ bàn phím
Dùng hàm gets() Cú pháp: gets() Ví dụ: char Ten[20]; gets(Ten); Ta cũng có thể sử dụng hàm scanf() để nhập dữ liệu cho biến chuỗi, tuy nhiên lúc này ta chỉ có thể nhập được một chuỗi không có dấu khoảng trắng. Dùng hàm cgets() (trong conio.h)
Xuất chuỗi lên màn hình
Để xuất một chuỗi (biểu thức chuỗi) lên màn hình, ta sử dụng hàm puts(). Cú pháp: puts() Ví dụ: Nhập vào một chuỗi và hiển thị trên màn hình chuỗi vừa nhập:
Ngoài ra, ta có thể sử dụng hàm printf(), cputs() (trong conio.h) để hiển thị chuỗi lên màn hình.
Một số hàm xử lý chuỗi (trong string.h)
Cộng chuỗi - Hàm strcat() Xác định độ dài chuỗi - Hàm strlen() Đổi một ký tự thường thành ký tự hoa - Hàm toupper() Đổi chuỗi chữ thường thành chuỗi chữ hoa, hàm strupr() Đổi chuỗi chữ hoa thành chuỗi chữ thường, hàm strlwr() Sao chép một phần chuỗi, hàm strncpy() Trích một phần chuỗi, hàm strchr() Tìm kiếm nội dung chuỗi, hàm strstr() So sánh chuỗi, hàm strcmp() So sánh chuỗi, hàm stricmp() Khởi tạo chuỗi, hàm memset() Đổi từ chuỗi ra số, hàm atoi(), atof(), atol() (trong stdlib.h)
Cộng chuỗi - strcat() (1)
Cú pháp: char *strcat(char *des, const char *source)
Hàm này có tác dụng ghép chuỗi nguồn (source) vào chuỗi đích (des). Trả vể con trỏ chỉ đến chuỗi kết quả.
Cộng chuỗi - strcat() (2) Ví
dụ: Nhập vào họ lót và tên của một người, sau đó in cả họ và tên của họ lên màn hình.
Xác định độ dài chuỗi - strlen() Cú
pháp: int strlen(const char* s) Ví dụ: Xác định độ dài 1 chuỗi nhập từ bàn phím.
Đổi một ký tự thường thành ký tự hoa - toupper() Cú
pháp: char toupper(char c)
Hàm
này (trong ctype.h) được dùng để chuyển đổi 1 ký tự thường thành ký tự hoa.
Đổi chuỗi chữ thường thành chuỗi chữ hoa - strupr() (1) Cú
pháp: char *strupr(char *s)
Hàm này được dùng để chuyển đổi chuỗi chữ thường thành chuỗi chữ hoa.
Kết quả trả về là 1 con trỏ chỉ đến chuỗi kết quả.
Đổi chuỗi chữ thường thành chuỗi chữ hoa - strupr() (2)
Ví dụ: Nhập vào một chuỗi ký tự từ bàn phím. Sau đó sử dụng hàm strupr() để chuyển đổi chúng thành chuỗi chữ hoa.
Đổi chuỗi chữ hoa thành chuỗi chữ thường - strlwr() Cú
pháp: char *strlwr(char *s)
Hàm này được dùng để chuyển đổi chuỗi chữ hoa thành chuỗi chữ thường.
Kết quả trả về là 1 con trỏ chỉ đến chuỗi kết quả.
Sao chép chuỗi - strcpy() (1) Cú
pháp: char *strcpy(char *Des, const char *Source)
Hàm này được dùng để sao chép toàn bộ nội dung của chuỗi nguồn vào chuỗi đích.
Sao chép chuỗi - strcpy() (2)
Ví dụ: Viết chương trình cho phép chép toàn bộ chuỗi nguồn vào chuỗi đích
Sao chép một phần chuỗi - strncpy() và Trích một phần chuỗi - strchr()
Sao chép một phần chuỗi
Cú pháp: char *strncpy(char *Des, const char *Source, size_t n) Chép n ký tự đầu tiên của chuỗi nguồn sang chuỗi đích.
Trích một phần chuỗi, hàm strchr()
Cú pháp : char *strchr(const char *str, int c) Trích ra chuỗi con của str bắt đầu từ ký tự c cho đến hết chuỗi. Ghi chú:
Nếu ký tự c không có trong chuỗi, kết quả trả về là NULL. Kết quả trả về của hàm là một con trỏ, con trỏ này chỉ đến ký tự c đầu tiên trong chuỗi str.
Tìm kiếm nội dung chuỗi - strstr() (1) Cú
pháp: char *strstr(const char *s1, const char *s2)
Hàm này được dùng để tìm kiếm sự xuất hiện đầu tiên của chuỗi s2 trong chuỗi s1. Kết quả trả là 1 con trỏ chỉ đến phần tử đầu tiên của chuỗi s1 có chứa chuỗi s2 hoặc giá trị NULL nếu chuỗi s2 không có trong chuỗi s1.
Tìm kiếm nội dung chuỗi - strstr() (2)
Ví dụ: Viết chương trình sử dụng hàm strstr() để lấy ra một phần của chuỗi gốc bắt đầu từ chuỗi “hoc”.
So sánh chuỗi - strcmp() (1) Cú
pháp: int strcmp(const char *s1, const char *s2)
So sánh 2 chuỗi s1 và s2 với nhau. Kết quả trả về là 1 số int:
<0 nếu s1 < s2 ==0 nếu s1==s2 >0 nếu s1 > s2
Tương tự: int stricmp(const char *s1, const char *s2)
So sánh không phân biệt kí tự hoa/thường
So sánh chuỗi - strcmp() (2) Ví
dụ:
#include
#include
#include <stdio.h>
#include <stdio.h>
#inlude <string.h>
#inlude <string.h>
void main(){
void main(){
char s1[10]=“Chao”, s2[10]=“chao”;
char s1[10]=“chao”, s2[10]=“chao”;
printf(“%d”,strcmp(s1,s2));
printf(“%d”,strcmp(s1,s2));
getch();
getch();
}
}
-32
0
Khởi tạo chuỗi - memset() Cú
pháp:
void *memset(char *Des, int c, size_t n)
Đặt n ký tự đầu tiên của chuỗi Des là ký tự c. Giá trị trả về: chuỗi Des. Nằm trong thư viện: string.h và mem.h
Đổi từ chuỗi ra số - atoi(), atof(), atol() (trong stdlib.h) Cú
pháp :
int atoi(const char *s) : chuyển chuỗi thành số nguyên long atol(const char *s) : chuyển chuỗi thành số nguyên dài float atof(const char *s) : chuyển chuỗi thành số thực Nếu
chuyển đổi không thành công, kết quả trả về của các hàm là 0. Ví dụ: atoi(“1234”)=> 1234
Hết chương
LẬP TRÌNH CĂN BẢN Phần 2 - Chương 9
KIỂU CẤU TRÚC P.D.Nghiệp
Nội dung chương này Kiểu
cấu trúc trong C Các thao tác trên biến kiểu cấu trúc Con trỏ và cấu trúc
Kiểu cấu trúc trong C Khái
niệm Định nghĩa kiểu cấu trúc Khai báo biến cấu trúc
Khái niệm
Kiểu cấu trúc (struct) là kiểu dữ liệu bao gồm nhiều thành phần có kiểu khác nhau, mỗi thành phần được gọi là một trường (field) Nó khác với kiểu mảng (nơi mà các phần tử có cùng kiểu) Ví dụ: 1 struct:
1 mảng:
Định nghĩa kiểu cấu trúc + Khai báo biến cấu trúc (1)
Cách 1:
struct { ; ; …….. ; } [biến 1, biến 2];
struct SinhVien{ char MSSV[10]; char HoTen[40]; struct NgayThang NgaySinh; int Phai; char DiaChi[40]; };
Ví dụ:
⇒Khaibáo biến:
struct NgayThang{ unsigned char Ngay; unsigned char Thang; unsigned int Nam; };
struct NgayThang NgaySinh; struct SinhVien SV;
struct
tên_biến;
Định nghĩa kiểu cấu trúc + Khai báo biến cấu trúc (2) Chú
ý:
struct không tên: A và B là các struct có 2 thành phần x và y. struct này không có tên, nên ngoài A và B, ta không thể định nghĩa thêm các biến khác được.
Tuy nhiên A và B là các biến có kiểu struct point. Sau này ta có thể khai báo thêm các biến khác có kiểu struct point này.
Định nghĩa kiểu cấu trúc + Khai báo biến cấu trúc (3)
Cách 2: typedef struct { ; ; …….. ; } ;
Ví dụ: typedef struct{ unsigned char Ngay; unsigned char Thang; unsigned int Nam; } NgayThang;
typedef struct{ char MSSV[10]; char HoTen[40]; NgayThang NgaySinh; int Phai; char DiaChi[40]; } SinhVien;
⇒Khai báo biến: NgayThang NgaySinh; SinhVien SV;
tên_biến;
Các thao tác trên biến kiểu cấu trúc Truy
xuất đến từng trường của biến cấu trúc Khởi tạo cấu trúc
Truy xuất đến từng trường (field) của biến cấu trúc (1)
Cú pháp:
.
Ví dụ 1: Chương trình cho phép đọc dữ liệu từ bàn phím cho biến mẩu tin SinhVien và in biến mẩu tin đó lên màn hình:
Truy xuất đến từng trường (field) của biến cấu trúc (2)
Truy xuất đến từng trường (field) của biến cấu trúc (3) Kết
quả của 1 lần nhập:
Truy xuất đến từng trường (field) của biến cấu trúc (4) Lưu
ý:
Các biến cấu trúc có thể gán cho nhau Ví dụ: s=SV; // gán để lấy giá trị toàn bộ cấu trúc
Ta không thể thực hiện được các thao tác sau đây cho biến cấu trúc:
Sử dụng các hàm xuất nhập trên biến cấu trúc Các phép toán quan hệ, các phép toán số học và logic
Khởi tạo cấu trúc Biến
cấu trúc có thể được khởi tạo giá trị ban đầu lúc khai báo
Ví
dụ:
struct NgayThang NgaySinh ={29, 8, 1986};
Con trỏ và cấu trúc Khai
báo Sử dụng các con trỏ kiểu cấu trúc Truy cập các thành phần của cấu trúc đang được quản lý bởi con trỏ
Khai báo (1) Cú
pháp: struct * ;
Ví dụ 1: struct NgayThang *p; hoặc NgayThang *p;
// Nếu có dùng typedef
Khai báo (2) Ví
dụ 2:
Truy cập đến các trường:
Nếu dùng con trỏ thì:
Sử dụng các con trỏ kiểu cấu trúc Có
2 cách:
Phải cấp phát bộ nhớ cho nó Cho nó chỉ vào (chứa địa chỉ) biến đang tồn tại
Ví dụ: struct NgayThang *p; … p=(struct NgayThang *)malloc(sizeof(struct NgayThang)); p->Ngay=29; p->Thang=8; p->Nam=1986;
Hoặc struct NgayThang Ngay = {29,8,1986}; p = &Ngay;
Truy cập các thành phần của cấu trúc đang được quản lý bởi con trỏ (1)
Với khai báo sau: struct NgayThang *p;
Ta có thể truy cập đến các trường của nó như sau: p->Ngay
p->Thang
(*p).Ngay
(*p).Thang
hoặc
Truy cập các thành phần của cấu trúc đang được quản lý bởi con trỏ (3)
Ví dụ
Hết chương
LẬP TRÌNH CĂN BẢN Phần 2 - Chương 10
KIỂU TẬP TIN P.D.Nghiệp
Nội dung chương này Một
số khái niệm về tập tin Các thao tác trên tập tin Truy cập tập tin văn bản Truy cập tập tin nhị phân
Một số khái niệm về tập tin (file) (1) Tại
sao ta cần đến kiểu tập tin? Cho phép lưu trữ dữ liệu ở bộ nhớ ngoài (đĩa). Khi kết thúc chương trình thì dữ liệu vẫn còn do đó chúng ta có thể sử dụng nhiều lần. Kích thước lớn dữ liệu không hạn chế.
Một số khái niệm về tập tin (file) (2)
Có 3 loại dữ liệu kiểu tập tin:
Tập tin văn bản (Text File) Dùng để ghi các ký tự lên đĩa (dưới dạng mã Ascii) Có chứa: Ký hiệu ‘\n’ : xuống dòng Kí tự EOF (End Of File) có mã Ascii là 26: nằm ở cuối tập tin Tập tin định kiểu (Typed File) Gồm nhiều phần tử có cùng kiểu: char, int, long, struct … Được lưu trữ trên đĩa dưới dạng một chuỗi các byte liên tục. Tập tin không định kiểu (Untyped File) Gồm các cấu trúc dữ liệu mà ta không quan tâm đến nội dung hoặc kiểu của nó. Ta chỉ lưu ý đến các yếu tố vật lý của tập tin như độ lớn, ...
Một số khái niệm về tập tin (file)(3)
Biến tập tin
Được dùng để đại diện cho một tập tin Các thao tác lên tập tin sẽ được thực hiện thông qua biến này
Con trỏ tập tin
Tại mỗi thời điểm, sẽ có một vị trí của tập tin mà tại đó việc đọc/ghi thông tin sẽ xảy ra Ta hình dung có 1 con trỏ đang chỉ đến vị trí đó Sau khi đọc/ghi xong dữ liệu, con trỏ sẽ chuyển dịch thêm một phần tử về phía cuối tập tin. Sau phần tử dữ liệu cuối cùng của tập tin là dấu kết thúc tập tin EOF
Các thao tác trên tập tin Khai
báo biến tập tin Mở tập tin Đóng tập tin Kiểm tra đến cuối tập tin hay chưa? Di chuyển con trỏ tập tin về đầu tập tin - Hàm rewind()
Khai báo biến tập tin Cú
pháp: FILE ; Các biến trong danh sách phải là các con trỏ và được phân cách bởi dấu phẩy(,). Ví dụ: FILE *f1,*f2;
Mở tập tin (1) Cú
pháp: FILE *fopen(char *Path, const char *Mode)
Ý
nghĩa: Trả về con trỏ tập tin của tập tin được mở Trả về NULL nếu có lỗi
Mở tập tin (2)
Path: chuỗi chỉ đường dẫn đến tập tin trên đĩa Type: chuỗi xác định cách thức mà tập tin sẽ mở. Các giá trị có thể của Mode:
Mở tập tin (3)
Ví dụ: Mở một tập tin tên TEST.txt để ghi. FILE *f; f = fopen(“TEST.txt”, “w”); if (f!=NULL){ // Các câu lệnh để thao tác với tập tin // Đóng tập tin }
=> mở tập tin để ghi => nếu tập tin đã tồn tại rồi thì tập tin sẽ bị xóa và một tập tin mới được tạo ra
Đóng tập tin
Cú pháp:
Ghi dữ liệu còn lại trong vùng đệm vào tập tin và đóng lại tập tin f là con trỏ tập tin được mở bởi hàm fopen() Giá trị trả về là 0 báo rằng việc đóng tập tin thành công Giá trị trả về là EOF nếu có xuất hiện lỗi
Cú pháp:
int fclose(FILE *f)
int fcloseall()
Đóng tất cả các tập tin lại Trả về tổng số các tập tin được đóng lại Nếu không thành công, kết quả trả về là EOF
Kiểm tra đến cuối tập tin hay chưa? Cú
pháp: int feof(FILE *f) Ý nghĩa:
Kiểm tra xem đã chạm tới cuối tập tin hay chưa. Trả về EOF nếu cuối tập tin được chạm tới, ngược lại trả về 0.
Di chuyển con trỏ tập tin về đầu tập tin - Hàm rewind()
Cú pháp: void rewind(FILE *f)
Ý nghĩa:
Làm cho con trỏ quay về đầu tập tin như khi mở nó
Truy cập tập tin văn bản Ghi
dữ liệu lên tập tin văn bản Đọc dữ liệu từ tập tin văn bản
Ghi dữ liệu lên tập tin văn bản (1) Hàm
putc() int putc(int c, FILE *f)
Được dùng để ghi một ký tự lên một tập tin văn bản đang được mở (liên kết với con trỏ f) để làm việc c chứa mã Ascii của ký tự Hàm này trả về EOF nếu gặp lỗi
Ghi dữ liệu lên tập tin văn bản (2) Hàm
fputs() int fputs(const char *buffer, FILE *f)
Được dùng để ghi một chuỗi ký tự chứa trong vùng đệm lên tập tin văn bản Hàm này trả về giá trị 0 nếu buffer chứa chuỗi rỗng và trả về EOF nếu gặp lỗi
Ghi dữ liệu lên tập tin văn bản (3)
Ví dụ: Viết chương trình ghi chuỗi ký tự lên tập tin văn bản D:\\Baihat.txt
Ghi dữ liệu lên tập tin văn bản (3) Hàm
fprintf() fprintf(FILE *f, const char *format, varexpr)
Được dùng để ghi dữ liệu có định dạng lên tập tin văn bản. format: chuỗi định dạng (giống với các định dạng của hàm printf()) varexpr: danh sách các biểu thức, mỗi biểu thức cách nhau dấu phẩy (,)
Đọc dữ liệu từ tập tin văn bản (1) Hàm
getc() int getc(FILE *f)
Được dùng để đọc dữ liệu từ tập tin văn bản đang được mở để làm việc (liên kết với f) Hàm này trả về mã Ascii của một ký tự được đọc (kể cả EOF)
Đọc dữ liệu từ tập tin văn bản (2)
Hàm fgets() char *fgets(char *buffer, int n, FILE *f)
Được dùng để đọc 1 chuỗi ký tự từ tập tin văn bản đang được mở (liên kết với con trỏ f) Đọc cho đến khi đủ n ký tự hoặc gặp ký tự xuống dòng ‘\n’ (ký tự này cũng được đưa vào chuỗi kết quả) hay gặp ký tự kết thúc EOF (ký tự này không được đưa vào chuỗi kết quả) buffer: chỉ đến cùng nhớ đủ lớn chứa các ký tự nhận được Ký tự NULL (‘\0’) tự động được thêm vào cuối chuỗi kết quả lưu trong vùng đệm Hàm trả về địa chỉ đầu tiên của vùng đệm khi không gặp lỗi và chưa gặp ký tự kết thúc EOF. Ngược lại, hàm trả về giá trị NULL
Đọc dữ liệu từ tập tin văn bản (3) Hàm
fscanf() fscanf(FILE *f, const char *format, varlist)
Được dùng để đọc dữ liệu từ tập tin văn bản vào danh sách các biến theo định dạng. format: chuỗi định dạng (giống hàm scanf()) varlist: danh sách các biến mỗi biến cách nhau dấu phẩy (,).
Đọc dữ liệu từ tập tin văn bản (4)
Ví dụ: Viết chương trình chép tập tin D:\Baihat.txt ở trên sang tập tin D:\Baica.txt.
Truy cập tập tin nhị phân Ghi
dữ liệu lên tập tin nhị phân Đọc dữ liệu từ tập tin nhị phân Di chuyển con trỏ tập tin Ví dụ
Ghi dữ liệu lên tập tin nhị phân Hàm
fwrite()
size_t fwrite(const void *ptr, size_t size, size_t n, FILE *f)
ptr: con trỏ chỉ đến vùng nhớ chứa thông tin cần ghi lên tập tin. n: số phần tử sẽ ghi lên tập tin. size: kích thước của mỗi phần tử. f: con trỏ tập tin đã được mở. Giá trị trả về của hàm này là số phần tử được ghi lên tập tin. Giá trị này bằng n trừ khi xuất hiện lỗi.
Đọc dữ liệu từ tập tin nhị phân Hàm
fread()
size_t fread(const void *ptr, size_t size, size_t n, FILE *f)
ptr: con trỏ chỉ đến vùng nhớ sẽ nhận dữ liệu từ tập tin n: số phần tử được đọc từ tập tin size: kích thước của mỗi phần tử f: con trỏ tập tin đã được mở Giá trị trả về của hàm này là số phần tử đã đọc được từ tập tin. Giá trị này bằng n hay nhỏ hơn n nếu đã chạm đến cuối tập tin hoặc có lỗi xuất hiện
Di chuyển con trỏ tập tin
Hàm fseek() int fseek(FILE *f, long offset, int whence)
Được dùng để di chuyển con trỏ tập tin đến vị trí chỉ định f: con trỏ tập tin đang thao tác offset: số byte cần dịch chuyển con trỏ tập tin kể từ vị trí trước đó. Phần tử đầu tiên là vị trí 0. whence: vị trí bắt đầu để tính offset, ta có thể chọn điểm xuất phát là
Kết quả trả về của hàm là 0 nếu việc di chuyển thành công. Nếu không thành công, 1 giá trị khác 0 (đó là 1 mã lỗi) được trả về.
Ví dụ
Viết chương trình ghi lên tập tin CacSo.Dat 3 giá trị số (thực, nguyên, nguyên dài). Sau đó đọc các số từ tập tin vừa ghi và hiển thị lên màn hình
Hết chương
Related Documents