P. 1
Lap Trinh Can Ban

Lap Trinh Can Ban

5.0

|Views: 2,625|Likes:
Được xuất bản bởispy004

More info:

Published by: spy004 on Aug 17, 2009
Bản quyền:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PPT, PDF, TXT or read online from Scribd
See more
See less

07/19/2012

pdf

text

original

Sections

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

kết thúc xác định

Số bước là hữu hạn 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
 

 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ông việc> Cấu trúc 2: Nếu < điều kiện> (đúng) thì thực hiện <công việc 1>, ngược lại (điều kiện sai) thì thực hiện <công việc 2> Cấu trúc 3: Trường hợp < i> thực hiện <công việc i>

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”. 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: +, -, *, /, %…

 Ví

  

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”. dụ : Kiểu chuỗi ký tự trong C.
là kiểu có cấu trúc. Ví dụ: char *chuoi = “Chao cac ban!”;

 Ví

 

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. 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...

Biên dịch (compiler):

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):
 

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. 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.

Tính cấu trúc (structured):
 

Tính tương thích (compatible):
  

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 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

Biên dịch (compile):

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
#include <stdio.h> #include<conio.h> int main () { char ten[50]; printf(“Xin cho biet ten cua ban !”); scanf(“%s”,ten); printf(“Xin chao ban %s”,ten); getch(); return 0; }

Gõ chương trình vào

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:
 

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ự. Tên đúng: CHAO.C, baitap2.c, chao_ban.c Tên sai: 1CHAO.C, chao+ban.c

Phần mở rộng:

Ví dụ:
 

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

Nhấn Ctrl-F9 hoặc vào menu Run->Run

Mở một chương trình đã có trên đĩa

Vào menu File->Open hoặc nhấn F3 Vào menu File->Exit hoặc nhấn Alt-X

Thoát khỏi Turbo C

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<conio.h> 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<các ký số từ 0 đến 7>  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
=> giá trị:

d i * 8i ∑
i =0

n

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 0x<các ký số từ 0 đến 9 và 6 ký tự từ A đến F>

Cách biểu diễn: Số thập lục phân : 0xdndn-1dn-2…d1d0 => Giá trị thập phân=

d i * 16 i ∑
i =0

n

Ví dụ:

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:
<Kiểu dữ liệu> 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) 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 loại toán tử trong C
     

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:
x = 10; y = ++x; //y = 11, x=11

• Còn:
x = 10; 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 true Giá trị 0 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 X = (10 > 9) ? 100 : 200; =>X=100 X = (10 >15 )? 100 : 200; =>X=200

Ví dụ:

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 <phép toán> 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 Prototype Khai báo biến ngoài Cài đặt các hàm Chương trình chính

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ó. 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ó.

Giải pháp 2 (tốt):
 

#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 <file.h>: 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 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

Các lệnh đơn
  

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ó

 

2 loại
Không chứa 1 lệnh nào khác Gồm: lệnh gán, nhập, xuất Chứa các lệnh khác Gồm:
   

Lệnh đơn

Lệnh có cấu trúc
 

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: <Tên biến> = <biểu thức>;

Ý 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 <conio.h> 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 <conio.h> 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) <Công việc>;

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 <Công việc>
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

trình in dãy số nguyên từ 1..10

output

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ông việc>;
 

<Công việc>: 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

trình in dãy số nguyên từ 1..10

output

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 <Công việc> while (<Biểu thức điều kiện>);
 

<Công việc>: 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

trình in dãy số nguyên từ 1..10

output

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
  

lặp for/while:

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 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 <tên thư viện.h> 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:<Tên 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ụ:
1 nếu n=0 n!= n*(n-1)! nếu n#0 { if (n==0) return 1; else

unsigned int giaithua_dequy(int n)

return n*giaithua_dequy(n-1); }

Đặc điểm cần lưu ý khi viết hàm đệ quy
 Hàm

đệ quy phải có 2 phần:

Phần dừng: là trường hợp nguyên tố.

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] Points[2]

typedef struct{ Point Points[100]; int nPoints; } Polygon;

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: <Kiểu> <Tên mảng ><[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: <Kiểu> <Tên mảng> <[]> ;

Mảng 1 chiều (2)

Vừa khai báo vừa gán giá trị
<Kiểu> <Tên mảng> []= {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ú

pháp: Tên biến mảng[Chỉ số]

 Ví

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ú  Ví

pháp:
<Kiểu> <Tên mảng><[Số phần tử chiều 1]><[Số phần tử chiều 2]> ;

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: <Kiểu> <Tên mảng> <[]><[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:
<Kiểu> *<Tên con trỏ>;

Ý 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 dụ
free(pa); free(pb); => giải phóng vùng nhớ do 2 biến con trỏ pa & pb đang chỉ đến

 Ví

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 FFFA p

a 10 FFF2 (address) b 15 FFFA (address) a 10 FFF2 (address) b 15 FFFA (address)

Bây giờ thì phép so sánh:
(p!=q) => true (1)

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

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 <Biến> [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: Ten[0]

‘\0’ Ten[12]

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ớ.

Khai báo theo con trỏ
 

Cú pháp: Ví dụ:

char *<Biến>; 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 <Biến>[]=<”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(<Biến chuỗi>) 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(<Biểu thức chuỗi>) 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 <conio.h> #include <stdio.h> #inlude <string.h> void main(){ char s1[10]=“chao”, s2[10]=“chao”; printf(“%d”,strcmp(s1,s2)); getch(); }

#include <conio.h> #include <stdio.h> #inlude <string.h> void main(){ char s1[10]=“Chao”, s2[10]=“chao”; printf(“%d”,strcmp(s1,s2)); 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 SinhVien{ char MSSV[10]; char HoTen[40]; struct NgayThang NgaySinh; int Phai; char DiaChi[40]; };

struct <Tên cấu trúc> { <Kiểu> <Trường 1>; <Kiểu> <Trường 2>; …….. <Kiểu> <Trường n>; } [biến 1, biến 2];

Ví dụ:
struct NgayThang{ unsigned char Ngay; unsigned char Thang; unsigned int Nam; };

⇒Khaibáo biến:
struct NgayThang NgaySinh; struct SinhVien SV;

struct <Tên cấu trúc>

tên_biến;

Định nghĩa kiểu cấu trúc + Khai báo biến cấu trúc (2)
 Chú

ý:
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.

struct không tên:

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 { <Kiểu> <Trường 1> ; <Kiểu> <Trường 2> ; …….. <Kiểu> <Trường n> ; } <Tên cấu trúc>;
typedef struct{ char MSSV[10]; char HoTen[40]; NgayThang NgaySinh; int Phai; char DiaChi[40]; } SinhVien;

Ví dụ:
typedef struct{ unsigned char Ngay; unsigned char Thang; unsigned int Nam; } NgayThang;

⇒Khai báo biến:
NgayThang NgaySinh; SinhVien SV;

<Tên cấu trúc>

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:

<Biến cấu trúc>.<Tên trường>

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 dụ:

 Ví

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 <Tên cấu trúc> * <Tên biến con trỏ>;

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 hoặc (*p).Ngay (*p).Thang p->Thang

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 <Danh sách các biến con trỏ>;  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:
   

int fclose(FILE *f)

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 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

You're Reading a Free Preview

Tải về
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->