1.2 Ngôn ngữ lập trình Programming Language Phần này chúng ta sẽ tìm hiểu một số khái niệm căn bản về thuật toán, chương trình, ngôn ngữ lập trình.. thấy các hàm và thủ tục này nằm tron
Trang 1CHƯƠNG 1 TỔNG QUAN VỀ NGÔN NGỮ LẬP TRÌNH C 4
1.1 Lịch sử hình thành và phát triển của ngôn ngữ lập trình C 4
1.2 Ngôn ngữ lập trình (Programming Language) 4
1.2.1 Thuật giải (Algorithm) 4
1.2.2 Chương trình (Program) 6
1.2.3 Ngôn ngữ lập trình (Programming language) 7
1.2.4 Các bước lập trình 7
1.3 Cấu trúc một chương trình C cho vi điều khiển 7
1.4 Bộ chữ viết, từ khoá, tên 10
1.4.1 Bộ chữ viết 10
1.4.2 Từ khoá 10
1.4.3 Tên 10
CHƯƠNG 2 CƠ SỞ LẬP TRÌNH C CHO VI ĐIỀU KHIỂN 12
2.1 Một số kiểu dữ liệu cơ bản 12
2.1.2 Kiểu ký tự (Char) 12
2.1.3 Kiểu số nguyên 13
2.1.4 Kiểu số thực 13
2.2 Khai báo hằng, biến, mảng cho bộ nhớ của vi điều khiển 13
2.2.1 Khai báo hằng 13
2.2.1.1 Hằng số thực 13
2.2.1.2 Hằng số nguyên 14
2.2.1.3 Hằng ký tự 14
2.2.1.4 Hằng xâu ký tự 15
2.2.1.5 Cách khai báo một hằng 15
2.2.2 Khai báo biến 16
2.2.2.1 Biến kiểu xâu ký tự 17
2.2.3 Khai báo mảng 18
2.2.3.1 Cách khái báo mảng 18
2.2.3.2 Cách thức truy nhập các phần tử của mảng 18
2.2.2.3 Lấy địa chỉ phần tử của mảng 19
Trang 22.2.2.4 Ví dụ áp dụng: 19
2.3 Con trỏ 21
2.4 Cấu trúc dữ liệu 27
2.5 Biểu thức và Các phép toán 31
2.5.1 Phép toán số học hai ngôi 31
2.5.2.Phép quan hệ và logic 32
2.5.3 Sự chuyển đổi kiểu 32
2.5.4 Phép tăng giảm 33
2.5.5 Câu lệnh gán 33
2.5.6 Biểu thức điều kiện 34
2.6 Các toán tử điều khiển chương trình 34
2.6.1 Cấu trúc điều khiển if 34
2.6.1.1 Cấu trúc rẽ nhánh if dạng khuyết 34
2.6.1.2 Cấu trúc rẽ nhánh if dạng dầy đủ 35
2.6.2 Cấu trúc điều khiển switch 38
2.6.3 Cấu trúc lặp while 40
2.6.4 Cấu trúc lặp do while 42
2.6.5 Cấu trúc lặp for 43
2.6.6 Toán tử break và continue 46
2.6.6.1 Câu lênh break 46
2.6.6.2 Câu lệnh continue 46
2.6.6.Toán tử goto và nhãn 48
CHƯƠNG 3 HÀM VÀ LẬP TRÌNH HƯỚNG HÀM 50
3.1 Cách tạo một hàm(function) trong C 50
3.2 Cách xây dựng một hàm: 52
3.3 Các nguyên tắc xây dựng và sử dụng hàm trong C 52
3.4 Sự hoạt động của một hàm 52
3.5 Tổ chức và thực hiện hàm 56
3.6 Ứng dụng lập trình Mobile Robot 59
3.6.1 Phần cứng Mobile Robot 59
Trang 33.6.2 Lập trình di chuyển cho Mobile Robot 60 3.6.3 Điều khiển Mobile Robot theo âm thanh 65
Trang 4CHƯƠNG 1 TỔNG QUAN VỀ NGÔN NGỮ LẬP TRÌNH C
1.1 Lịch sử hình thành và phát triển của ngôn ngữ lập trình C
Ngôn ngữ lập trình C do Brian W.kerningham và Dennis M.Ritchice phát triển vào năm 1970 tại phòng thí nghiệm BELL (Hoa kỳ) với mục đích ban đầu để phát triển hệ điều hành UNIX
Phần lớn các ý tưởng quan trọng nhất của C xuất phát từ ngôn ngữ có tên BCPL do Martin Richards nghiên cứu ảnh hưởng của BCPL gián tiếp thông qua ngôn ngữ B do Ken Thompson viết vào năm 1970 cho hệ điều hành UNIX chạy trên họ máy tính PDP- 7
Từ khi ra đời ngôn ngữ lập trình C có nhiều loại chương trình dich C khác nhau như: Turbo C của hãng Borland, Quick C, Microsoft C,
Sự phát triển của ngôn ngữ lập trình trong những năm 1980 đã đưa đến phong cách lập trình hướng đối tượng (OOP – Object Oriented Programing) mà một trong những ngôn ngữ rất được ưa dùng là C++ một bổ sung mới các yếu tố hướng đối tượng và ngôn ngữ lập trình C
- Ngôn ngữ lập trình C là một ngôn ngữ lập trình vạn năng dùng để viết các ứng dụng thực tế như: Quản lý văn bản, cơ sở dữ liệu, ghép nối máy tính
- Ngôn ngữ lập trình C là ngôn ngữ lập trình uyển chuyển, có độ thích nghi cao
1.2 Ngôn ngữ lập trình (Programming Language)
Phần này chúng ta sẽ tìm hiểu một số khái niệm căn bản về thuật toán, chương trình, ngôn ngữ lập trình Thuật ngữ "thuật giải" và "thuật toán" dĩ nhiên có sự khác nhau song trong nhiều trường hợp chúng có cùng nghĩa
1.2.1 Thuật giải (Algorithm)
Là một dãy các thao tác xác định trên một đối tượng, sao cho sau khi thực hiện một số hữu hạn các bước thì đạt được mục tiêu Theo R.A.Kowalski thì bản chất của thuật giải:
Thuật giải = Logic + Điều khiển
- Logic: Đây là phần khá quan trọng, nó trả lời câu hỏi "Thuật giải làm gì, giải quyết vấn đề gì?", những yếu tố trong bài toán có quan hệ với nhau như thế nào
Trang 5v.v… Ở đây bao gồm những kiến thức chuyên môn mà bạn phải biết để có thể tiến hành giải bài toán
Ví dụ 1: Để giải một bài toán tính diện tích hình cầu, mà bạn không còn nhớ công thức tính hình cầu thì bạn không thể viết chương trình cho máy để giải bài toán này được
- Điều khiển: Thành phần này trả lời câu hỏi: giải thuật phải làm như thế nào? Chính là cách thức tiến hành áp dụng thành phần logic để giải quyết vấn đề
Để dễ hơn về quy trình xử lý, các nhà lập trình đưa ra dạng lưu đồ để minh họa từng bước quá trình xử lý một vấn đề (bài toán)
Dữ liệu vào (Input)
Xử lý (Process)
Dữ liệu ra (Output)
Quyết định (Decision), sử dụng điều kiện
Luồng xử lý (Flow lines)
Gọi CT con, hàm… (Procedure,
Function…)
Bắt đầu, kết thúc (Begin, End) Điểm ghép nối (Connector)
Trang 6Ví dụ: Điều khiển đèn sáng tắt bằng nút gạt
Bắt đầu
nút gạt ở trạng thái on
Đ
S
Bài tập
Vẽ lưu đồ cho các chương trình sau:
1 Điều khiển đèn led sáng tắt với thời gian sáng 5 s, thời gian tắt 7s
2 Điều khiển động cơ điện theo nút nhấn chạy/dừng và đảo chiều
3 Điều khiển đèn giao thông : Đèn xanh 5s vàng 9 s và đèn đỏ 12s
1.2.2 Chương trình (Program)
Là một tập hợp các mô tả, các phát biểu, nằm trong một hệ thống qui ước về ý nghĩa và thứ tự thực hiện, nhằm điều khiển máy tính làm việc Theo Niklaus Wirth thì:
Chương trình = Thuật toán + Cấu trúc dữ liệu Các thuật toán và chương trình đều có cấu trúc dựa trên 3 cấu trúc điều khiển cơ bản:
- Tuần tự (Sequential): Các bước thực hiện tuần tự một cách chính xác từ trên xuống, mỗi bước chỉ thực hiện đúng một lần
- Chọn lọc (Selection): Chọn 1 trong 2 hay nhiều thao tác để thực hiện
- Lặp lại (Repetition): Một hay nhiều bước được thực hiện lặp lại một số lần Muốn trở thành lập trình viên chuyên nghiệp bạn hãy làm đúng trình tự để có thói quen tốt và thuận lợi sau này trên nhiều mặt của một người làm máy tính Bạn hãy
Trang 7làm theo các bước sau: Tìm, xây dựng thuật giải (trên giấy) → viết chương trình trên máy → dịch chương trình → chạy và thử chương trình
1.2.3 Ngôn ngữ lập trình (Programming language)
Ngôn ngữ lập trình là hệ thống các ký hiệu tuân theo các qui ước về ngữ pháp
và ngữ nghĩa, dùng để xây dựng thành các chương trình cho máy tính
Một chương trình được viết bằng một ngôn ngữ lập trình cụ thể (ví dụ Pascal, C…) gọi là chương trình nguồn, chương trình dịch làm nhiệm vụ dịch chương trình nguồn thành chương trình thực thi được trên máy tính
1.2.4 Các bước lập trình
Bước 1: Phân tích vấn đề và xác định các đặc điểm (xác định I-P-O)
Bước 2: Lập ra giải pháp (đưa ra thuật giải)
Bước 3: Cài đặt (viết chương trình)
Bước 4: Chạy thử chương trình (dịch chương trình)
Bước 5: Kiểm chứng và hoàn thiện chương trình (thử nghiệm bằng nhiều số liệu
Serial port
TxD RxD
Counter Input
On-Chip Data RAM
Serial port
TxD RxD
Counter Input
On-Chip Data RAM
Trang 8P1_0=0// led tat delay(2000);
} }
void delay(long k)
{
long i;
for(i=0;i<k;i++) ; }
số hàm nằm trong chương trình, số khác nằm trong các thư viện chuẩn
Khai báo tệp tiêu đề
Trong ngôn ngữ lập trình Pascal chẳng hạn khi ta muốn sử dụng lệnh xoá
màn hình “ Clrscr;” hay lệnh di chuyển con trỏ màn hình “Gotoxy(x,y)” v.v Ta
Trang 9thấy các hàm và thủ tục này nằm trong thư viên chuẩn CRT do đó muốn chương
trình sử dụng được các hàm và thủ tục đó thì tại đầu chương trình ta phải khai báo
như sau
USES CRT;
Tưng tự như vậy trong ngôn ngữ lập trình C khi sử dụng các hàm chuẩn
trong các thư viện chuẩn chúng ta phải khai báo tệp tiêu đề(header file) chứa các
hàm nguyên mẫu tương ứng các hàm đó, các lệnh được bắt đầu bằng #include theo sau là tệp tiêu đề
Có hai cách viết như sau:
Cách 1: #include <[đường dẫn\] tentep>
Tác dụng: Trước khi dịch, chương trình dịch sẽ tìm tệp theo tentep và
đường dẫn đã chỉ ra trong #include Nếu tìm thấy thì nội dung của tệp này được
gọi ra và chèn vào tệp nguồn đang xét đúng vị trí của #include Nếu không tìm thấy thì thông báo lỗi
Hai cách khai báo trên khác nhau ở chỗ Nếu tentep được chỉ ra trong khai
báo #include không có đường dẫn thì
Cách 1 tự động tìm tentep trong thư mục INCLUDE
Cách 2 tự động tìm tentep trong thư mục hiện thời nếu không có thì tìm trong
Chú thích và dấu kết thúc câu lệnh
Trong ngôn ngữ lập trình C những phần được viết trong /* */ hoặc những
phần được viết sau // được gọi là phần chú thích Mọi ký tự nằm trong /* */ khi
dịch chương trình dich bỏ qua, ta được phép dùng chúng để minh hoạ cho các thành phần chương trình làm cho chương trình dễ hiểu, mạch lạc Lời chú thích có thể
xuất hiện bất kỳ đâu trong chương trình và có thể trải trên nhiều dòng khác nhau
trong chương trình
Trang 10Trong chương trình viết bằng ngôn ngữ C mỗi câu lệnh có thể viết trên một
hay nhiều dòng và phải kết thúc bằng dấu chấm phẩy(;)
1.4 Bộ chữ viết, từ khoá, tên
Các dấu chấm câu: , ; : / ? [ ] { } @ # $ % ^ * & ( ) + - = < > ‘ “
Các dấu ngăn cách không nhìn thấy như dấu cách, dấu nhảy cách tab, dấu xuống dòng
Dấu gạch nối dưới _
1.4.2 Từ khoá
- Là những từ có một ý nghĩa hoàn toàn xác định trong chương trình:
Ví dụ: void struct class while
- Không được dùng từ khoá để đặt tên cho các hằng, biến, mảng, hàm
- Từ khoá phải viết bằng chữ thường
Ví dụ từ khoá viết đúng: struct
Ví dụ từ khoá viết sai: Struct
1.4.3 Tên
- Là một dãy ký tự được dùng để chỉ tên hằng, tên biến, tên mảng, tên
hàm Tên được tạo thành từ các chữ cái a z, A Z, chữ số 0 9, dấu gạch dưới Tên không được bắt đầu bằng chữ số, chứa các kí tự đặc biệt như dấu cách, dấu phép
toán
- Tên không được đặt trùng với từ khoá
- Ví dụ các tên viết đúng: Giai_Phuong_Trinh_Bac2
abc123
- Ví dụ các tên viết sai: Baitap 1
Trang 11123abc
Chú ý:
- Trong ngôn ngữ lập trình C tên được phân biệt chữ hoa và chữ thường
- Thông thường chữ hoa thường được dùng để đặt tên cho các hằng, còn các
đại lượng khác thì dùng chữ thường
Trang 12CHƯƠNG 2 CƠ SỞ LẬP TRÌNH C CHO VI ĐIỀU KHIỂN
2.1 Một số kiểu dữ liệu cơ bản
Cấu trúc bộ nhơ vi điều khiển
89C51
Bộ nhớ dữ liệu RAM (Data Menmory)
Có thể chọn bank bằng bit RS1,RS0 trong thanh ghi PSW
Trang 132.1.3 Kiểu số nguyên
Một giá trị kiểu số nguyên là một phần tử của một tập các số nguyên mà máy tính có thể biểu diễn Trong ngôn ngữ lập trình C có nhiều kiểu dữ liệu số nguyên với dải giá trị khác nhau cụ thể:
2.2 Khai báo hằng, biến, mảng cho bộ nhớ của vi điều khiển
2.2.1 Khai báo hằng
Dữ liệu chứa trong máy tính có thể là biến hoặc hằng
+ biến là đại lượng có thể thay đổi được trong quá trình tính toán
+ hằng là đại lượng có giá trị cụ thể không thay đổi
Biến và hằng được lưu trữ trong bộ nhớ và thường được đặt tên cho dễ sử dụng, thay vì phải sử dụng địa chỉ ô nhớ cũng như giá trị cụ thể của chúng, rất khó
sử dụng
2.2.1.1 Hằng số thực
Được viết theo hai cách sau:
Trang 14- Dạng thập phân gồm:Phần nguyên, dấu chấm thập phân, phần thập phân
số hệ 8 mà giá trị của nố chính là mã ASCII của ký tự cần biểu diễn
Ví dụ: ‘a’ hay ‘\141’
Trang 15- Là một dãy các ký tự đặt trong hay dấu nháy “ ”
- Xâu ký được lưu trữ trong một mảng ô nhớ liền nhau song còn thêm ô nhớ cuối cùng chứa mã là 0(ký hiệu là ‘\0’ )
Ví dụ: “Nguyen Van Anh”
Đươc tổ chức trong bộ nhớ như sau:
Sự khác nhau giữa định nghĩa hằng số dùng #define và const ở chỗ:
+ Với const đây là hằng số cố định, một hằng số thực sự và chỉ có một hằng số chứa trong ô nhớ
Trang 16+ Với #define khi gặp hằng số này chương trình dịch sẽ lắp giá trị hằng số này vào trong biểu thức cần tính với số lần thoải mái Điều đó có nghĩa là mỗi khi gặp
hằng này máy sẽ lắp đủ ô nhớ chứa hằng số này vào đó
2.2.2 Khai báo biến
- Các biến trước khi sử dụng phải khai báo theo mẫu sau:
kieu_du_lieu danh_sach_cac_bien_can_khai_bao;
Ví dụ: int x,y;
float a;
- Khi khai báo một biến ta có thể khởi đầu giá trị cho nó theo mẫu sau:
kieu_du_lieu ten_bien = gia_tri;
Ví dụ: float x=5.;
int n=10;
- Để lấy địa chỉ của một biến ta dùng toán tử & cụ thể như sau:
&ten_bien
Ví dụ: &x lấy địa chỉ của biến a
&n lấy địa chỉ của biến n
VD: Chương trình xác định điện trở tương đương của 2 điện trở 1000 ôm và 500
lcd_gotoxy(1,1);
printf(lcd_putc,"Rtd=%5ld",Rtd);
while(1) ; }
Trang 172.2.2.1 Biến kiểu xâu ký tự
Xâu ký tự là một mảng nhưng đặc biệt hơn
a Khai báo xâu ký tự
char str[10]
+ Các phần tử của mảng là một ký tự
+ Xâu bao giờ cũng kết thúc bằng phần tử ký hiệu là NUL(‘\0’)
Một hằng xâu ký tự được đặt trong dấu nháy kép
VD: “DHSPKT” để lưu giữ xâu này thì hệ thống phải dùng 1 mảng có 7 ô
fflush(stdin) Dùng hàm này sẽ tránh được mọi hậu quả của các thao tác nhập số
Hàm gets() đọc từ bàn phím tất cả các ký tự và điền vào sâu str Việc đọc kết
thúc khi số ký tự đọc vào bằng chiều dài cực đại của xâu hoặc gặp ký tự xuống
dòng ’\n’ Kết thúc việc đọc ký tự một ký tự ‘\0’ được gắn thêm vào cuối xâu Khi
a
a \0
Trang 18lệnh gets() đi sau các chỉ thị khác nên sử dụng thêm fflush(stdin) phía trước để đảm bảo việc nhập không bị sai
Hàm puts() xuất ra một xâu văn bản tới lối ra chuẩn và gắn nó với một dòng
mới
2.2.3 Khai báo mảng
Mảng là một dãy biến liên tiếp cùng tên nhưng khác nhau bởi chỉ số Tất cả
các biến này có cùng một kiểu là kiểu của mảng
Chú ý:
- Chỉ số của mảng có thể là một hằng, biến, biểu thức và không được vượt
quá kích thước của mảng
Trang 19- Nếu chỉ số của mảng là một số thực Khi đó phần nguyên của số thực là chỉ
số của mảng
2.2.2.3 Lấy địa chỉ phần tử của mảng
- Đối với mảng một chiều: &tenmang[chiso]
- Đối với mảng hai chiều: &tenmang[chisohang][chisocot]
Chú ý:
- Tên mảng chính là địa chỉ địa chỉ phần tử đầu tiên của mảng
- Các phần tử của mảng được cấp phát các vùng nhớ liên tiếp nhau, nói cách khác chúng có địa chỉ liên tiếp nhau trong bộ nhớ Các phần tử của mảng hai chiều được sắp xếp theo hàng, hết hàng này đến hàng khác
2.2.2.4 Ví dụ áp dụng:
VD 1: Điều khiển Led đơn sáng dần từ giữa ra
Mạch phần cứng được thiết kế như sau:
Id (mA)
Maximal current If (mA)
Voltage drop
Ud (V)
Trang 20Từ yêu cầu đề ta có bảng mã cho các trạng thái của Led:
Trang 21C đã khiến con trỏ trở thành một côn cụ mạnh để thực hiện nhiều thao tác mà thiếu
nó thì không thể làm được hoặc làm rất khó khăn
Trang 22Để khai báo một biến trỏ cụ thể như sau:
Ở đây: px là tên con trỏ
*px dạng khai báo của con trỏ
- Sử dụng tên con trỏ: Con trỏ cũng là một biến nên khi tên của nó xuất hiện trong các biểu thức thì giá trị của nó sẽ được sử dụng trong biểu thức này Chỉ có một điều cần lưu ý ở đây: giá trị của một con trỏ là dịa chỉ của biến nào đó
Ví dụ: float a,*p,*h;
p=&a;/* Gán địa chỉ của biến a cho p hay nói cách khác cho con trỏ p trỏ tới biến a */
h=p;/* Gán con trỏ p cho con trỏ h */
- Sử dụng dạng khai báo của con trỏ: Một khi địa chỉ của đối tượng dt đã gán cho con trỏ ct thì ta có thể truy nhập tới đối tượng dt thông qua con trỏ ct theo quy tắc sau:
Ở bất kỳ chỗ nào trong chương trình hai các viết: dt và *ct có cùng tác dụng như nhau
Trang 23thế thì có thể viết là
*troy=5*x+z;
*troy=5*(*trox)+z;
Chú ý: Khi ta khai báo một biến trỏ thì nó chưa có giá trị xác định hay nói
cách khác nó chưa trỏ vào đâu cả Nếu ta muốn sử dụng biến trỏ thì ta phải cho nó trỏ vào một biến cụ thể nào đó:
Các phép toán trên con trỏ
Có bốn nhóm phép toán liên quan đến con trỏ và địa chỉ: Phép gán, phép tăng giảm địa chỉ, phép truy nhập bộ nhớ và phép so sánh
trox=(int *)(&z); ép kiểu
Phép tăng giảm địa chỉ
Một con trỏ có thể cộng với một giá trị nguyên (int, long) để cho kết quả là một con trỏ cùng kiểu
Ví dụ: int a[10], *tro1, *tro2, *tro3;
tro1=a; tương đương với tro1=a[0];
tro2=tro1+1;
tro3=tro1+9;
Cụ thể máy sẽ cung cấp các khoảng nhớ liên tiếp của mảng a như sau:
tro1 tro2 tro3
Một con trỏ có thể trừ với một giá trị nguyên (int, long) để cho kết quả là một con trỏ cùng kiểu
Ví dụ: float a[10], *tro, *tro1;
tro=&a[3]; tro là con trỏ float trỏ tới phần tử a[3]
tro1=tro-2;
Cụ thể máy sẽ cung cấp các khoảng nhớ liên tiếp của mảng a như sau:
Trang 24tro1 tro
Hiệu hai con trỏ
Hai con trỏ cùng kiểu trừ đi nhau cho ta một số nguyên
Không được lấy tổng, hiệu, tích, thương, % hai con trỏ
Liên hệ giữa con trỏ và mảng
Trong C, khái niệm con trỏ và mảng liên quan mật thiết với nhau Tất cả các thao tác mà chúng ta thực hiện thông qua chỉ số trên các mảng có thể thực hiện nhờ công cụ con trỏ Tuy nhiên, cùng một ý tưởng thuật toán, chương trình có sử dụng các con trỏ nói chung chạy nhanh hơn nhưng đồng thời khó hiểu hơn so với chương trình sử dụng các mảng
Xét ví dụ
int a[10], *p;
Ta thấy rằng với khai báo trên máy sẽ bố trí cho mảng a 10 khoảng nhớ liên tiếp (mỗi khoảng nhớ 2 byte) Như vậy nếu biết địa chỉ của một phần tử nào đó của mảng a, thì dễ dàng suy ra địa chỉ của các phần tử khác Như ta đã biết tên mảng chính là một hằng địa chỉ và chính là địa chỉ phần tử đầu tiên của mảng, với khai báo tên thì:
a a+1 a+9
a+1 tương đương với &a[1]
Trang 25thì bốn cách viết sau đây là tương đương
a[i], *(a+i), *(p+i), p[i]
Chú ý: a và p là khác nhau: ở đó a là một hằng địa chỉ của mảng tức là địa chỉ phần tử đầu tiên của mảng, còn p là một biến con trỏ Do đó có thể viết p++ nhưng không thể viết a++ hay a=a+1, a=a+2,
Ví dụ: hiển thị các số 1, 3, 5, 7 trên Led 7 thanh:
Trang 27P0 = *Point_Maled;// hien thi so 3 delay(2000);
dữ liệu này cho ta một khả năng kết hợp một nhóm các biến cùng thể hiện một đối
tượng chung Chẳng hạn để lưu giữ những thông tin liên quan đến một đối tượng
nhân viên, ta có thể cần thiết đến một biến nào đó có khả năng lưu trữ được cả tên, địa chỉ, ngày sinh, lẫn mã số nhân viên, lương v.v Để có thể xử lý biến này như
một phần tử thống nhất, thể hiện thông tin của một nhân viên cụ thể Ngôn ngữ lập trình C cho phép chúng ta tự xây dựng những kiểu dữ liệu phức hợp như vậy và sử dụng những kiểu dữ liệu này để khai báo cho các biến sử dụng sau đó Chúng ta gọi những kiệu dữ liệu như vậy là các cấu trúc
Khai báo
Khai báo hay định nghĩa một cấu trúc là xác định các kiểu dữ liệu đơn giản
hơn được nhóm lại trong cấu trúc đó Cấu trúc tổng quát để định nghĩa một cấu trúc như sau:
struct [tencautruc]
{
- Khai báo các thành phần của cấu trúc
Trang 28}[danhsachcacbiencautruc];
Trong đó:
- truct là từ khoá
- tencautruc là một tên hợp lệ dùng làm tên cấu trúc
- danhsachcacbiencautruc dùng liệt kê các biến cấu trúc
Chú ý: tencautruc, danhsachcacbiencautruc có thể vắng mặt nhưng ít nhất một
thành phần phải có mặt trong khai báo cấu trúc
Struct Tham_So_PID PID_vantoc;
Để khai báo các biến cấu trúc hay mảng cấu trúc sau khi đã khai báo cấu trúc Theo mẫu sau:
struct tencautruc danhsachcacbien;
Trang 29Các thành phần của cấu trúc được truy nhập thông qua tên biến cấu trúc và tên các thành phần cấu trúc Nguyên tắc chung
tenbiencautruc.tenthanhphan
Hoặc chúng ta có thể dùng con trỏ cấu trúc để truy xuất tới từng thành phần
của cấu trúc thông qua phép toán -> Nguyên tắc chung
Chú ý: Không nên sử dụng toán tử & đối với các thành phần cấu trúc ( đặc
biệt đối với các thành phần không nguyên) trong khi nhâph dữ liệu vì điều này có
thể dẫn đến treo máy
Có thể áp dụng phép gán cho các biến cấu trúc cùng kiểu
Mảng các cấu trúc:
Các kiểu cấu trúc có thể là kiểu thành phần cho các mảng Một mảng mà các
thành phần có kiểu cấu trúc được gọi là mảng cấu trúc Khai báo một mảng cấu trúc hoàn toàn tương tự như đối với khai báo một mảng bình thường, chỉ có một điểm
khác là thay cho tên các kiểu dữ liệu bình thường là một tên kiểu dữ liệu cấu trúc
Cách khai báo mảng cấu trúc một chiều:
struct tenkieucautruc tenmang[kichthuoc];
Cách khai báo mảng cấu trúc hai chiều:
struct tenkieucautruc tenmang[kichthuoc][kichthuoc];
Trang 30Việc sử dụng các mảng cấu trúc sẽ làm cho việc xử lý một tập hợp các biến
cấu trúc trở nên dễ nhìn hơn Các quy định về mảng cũng được áp dụng đối với
mảng cấu trúc
VD: Nhập danh sách các hoá đơn bán hàng, dữ liệu mỗi hoá đơn gồm:
+ tên hàng + Số lượng + Đơn giá Sau đó in hoá đơn có số tiền >=100000đ
printf("\nNhap danh sach hoa don");
printf("\nNhap vao so hoa don:");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
printf("Nhap hoa don thu %d",i);
printf("\nNhap ten hang:");
Trang 312.5.1 Phép toán số học hai ngôi
Các phép toán số học hai ngôi được thống kê ở bảng sau:
- Nếu phép chia hai toán hạng đều nguyên thì phép chia cho kết quả là phần
nguyên của thương hai toán hạng đó
Trang 32- Nếu một trong hai toán hạng là kiểu thực thì lúc này kết quả của phép chia cho ta giá trị đúng
- Phép toán lấy phần dư % chỉ áp dụng cho trường hợp hai toán hạng là số
nguyên
2.5.2.Phép quan hệ và logic
Trong ngôn ngữ lập trình C coi mọi giá trị khác không là đúng(“TRUE”) và
mọi giá trị bằng không là sai(“FALSE”)
Các phép toán quan hệ sau đây cho kết quả là 1 nếu điều khiện được thoả mãn
và bằng 0 trong trường hợp ngược lại:
Các phép toán logic được thể hiện dưới bảng sau:
2.5.3 Sự chuyển đổi kiểu
Việc chuyển đổi kiểu dữ liểu trong C thường diễn ra tự động trong các trường hợp sau:
- Khi toán hạng trong một phép toán có kiểu khác nhau thì kiểu thấp hơn được chuyển thành kiểu cao hơn: int->long->float->double
- Khi gán một giá trị kiểu này cho một biến(hoặc phần tử mảng) kiểu kia
Ví dụ: int c;
Trang 33c=2.45;/* c sẽ nhận giá trị là 2*/
- Khi truyền giá trị cho các đối số của hàm, trong câu lênh return của hàm
Ngoài ra ta có thể chuyển từ một kiểu giá trị này sang một kiểu giá trị khác bất
kỳ ta muốn bằng cách ép kiểu theo mẫu sau:
Trong ngôn ngữ lập trình C đưa ra hai phép toán một ngôi để tăng và giảm
các biến (nguyên và thực) Toán tử tăng ++ sẽ thêm 1 vào toán hạng của nó, toán tử giảm – sẽ trừ đi 1
Ví dụ: n đang có giá trị là 5 thì
Sau phép toán ++ n có giá trị là 6
Sau phép toán – n có giá trị là 4
Dấu phép toán ++ và có thể đứng trước hoặc đứng sau toán hạng Như vậy
ta có thể viết: ++n, n++, n, n
Sự khác nhau của ++n và n++ ở chỗ: Trong phép toán n++ thì n tăng sau khi
giá trị của nó được sử dụng, còn trong ++n thì giá trị của n tăng trước khi giá trị của
nó được sử dụng Trong phép toán n thì n giảm sau khi giá trị của nó được sử
dụng, còn trong n thì giá trị của n giảm trươc khi giá trị của nó được sử dụng
Ví dụ:int x=2,y=4,n=4,m=5;
x+=n++;/* cho kết quả x có gía trị 6*/
y*=++m;/* cho kết quả y có giá trị 24*/