Bài giảng Kỹ thuật lập trình - Chương 3: Các kỹ thuật xây dựng chương trình phần mềm cung cấp cho người học các kiến thức: Mở đầu, làm việc với biến, viết mã chương trình hiệu quả. Mời các bạn cùng tham khảo nội dung chi tiết.
Trang 1
-_ Với mỗi bài toán, làm thể nào để:
~ Thiết kế giải thuật nhằm giải quyết bài toán đó - Cài đặt giải thuật bằng một chương trình máy tỉnh
- Làm cho chương trình chạy đúng trước khi tăng tính hiệu quả của chương trình
Trang 2CHƯƠNG 111 CÁC KỸ THUẬT XÂY DỰNG CHUO'NG TRINH PHAN MEM I Mo dau
II Làm việc với biến
[H Viết mã chương trình hiệu quả IV Thiết kế chương trình
V Xay dung ham/thu tục
Trang 3I MO ĐẦU
Trang 4Một số khái niệm thường gặp Chương II Các kỹ thuật chương trình phan mem
1 Mở dau - Compile / build (dịch):
°_ Source code (mã nguồn):
- _Executable program (chương trình thực
thi):
* Language (ng6n ngữ):
* Library (thu vién):
Trang 5C: Từ khóa Chương II Các iy nes -_ Lưồng điều khiển (6) : a chương trinh Bs phần mêm ° Lặp (5): 1 Mé dau °Ò Từ khóa nên tránh (1) : * Kiéu co ban (5): * Kiéu dựng sẵn (7): * Cau trúc (3):
* Liệt kê và đo kích thước (2):
- Từ khóa cho khai báo biển (3):
Trang 6
C: Hello World
_ Lệnh tiền xử lý
_„Chú thích
/* My first C program which prints Hello World */
._—— mMain(): “start here”
int main (int argc, char *argv[])
#include <stdio.h> «~~
{
\ printf ("Hello World!\n")7; -~_
Trang 7I tý thuật chương trinh phan mem 1 Mớ đầu Chú ý khi đọc và viết mã nguồn
Trang 8
C: dịch từ mã nguôn sang mã máy
Trang 9
C: dịch từ mã nguôn sang mã máy
° Một số compilers co vai trò rất lớn trong việc tối ưu chương trình
— Chung phan tích sâu mã nguồn và làm mọi điều
"machinely“ có thể nhằm xác định nguồn gốc gây kém hiệu quả trong mã nguồn (dư thừa tính toán, dư thừa dữ
liệu)
~ Ví dụ GNU g++ compiler trên Linux/Cygwin cho chương trình viết bằng C
* g++ -O5 -o myprog myprog.c
có thể cải thiện hiệu năng tử 10% dén 300%
Trang 10cm Các kỹ thuật chương trinh phan mem 1 Mé dau Viết mã nguồn hiệu quả - LTV vẫn có thể thực hiện những cải tiến mà trình dịch không thể - LTV phải loại bỏ tất cả những chỗ bất hợp lý trong mã nguồn * LTV phải làm cho chương trình hiệu quả nhất có thể
- LTV có thể phải xem lại mã nguồn khi
thấy chương trình chạy chậm
-_ Vậy cần tập trung vào đâu để cải tiến
nhanh nhất, tốt nhất ?
Trang 12
Phong cách lập trình tốt
+ Phong cách lập trình (program style): cách trình bày một chương trình
+ VỊ sao program style lại quan trọng?
~ Lỗi thưởng xảy ra do sự nhầm lẫn cua LTV
- Biến này được dùng lam gi?
+ Hàm này được gọi như thế nào? - Mã nguồn hiệu qua (good code)
«Ổ Đỗ đọc
-_ Dễ hiểu (dễ kiếm tra}
¢ Oé sits (dé bảo trì, cấp nhặt, trảnh lỗi)
+ Làm thế nào để mã nguồn trở nên dễ đọc, dễ hiếu, dễ sửa ?
Trang 13
Phong cách lập trình tốt
- _ Để máy tính làm tốt các công việc nặng nhọc của nó, hãy
~ Viết CT rõ ý, với cấu trúc rồ ràng
~ Viết lại mã nguồn thay vi cỗ gắng chủ giải hay chắp vả các đoạn
mã khó hiểu
Tránh dùng goto
- _ Để lập trình viên giảm bớt công việc không đảng cỏ, hãy
Viết chương trình với khuôn đạng rõ ràng Chọn tên phủ hợp, gợi nhớ, không nhập nhằng
Cung cấp đầy đủ tài liệu liên quan đến các cấu trúc dữ liệu sử
dụng trong chương trình
Viết chú thích rõ rằng, cỏ ý nghĩa, sử dụng các thành ngữ phổ biến Dùng các thủ tục đệ quy cho những cấu trúc dữ liệu đệ quy ( list, cây phả hệ )
Trang 14
II CAC KY THUAT LAM VIỆC VỚI BIẾN
1 Khai bao bien
Đặt tên biến
Sử dụng các kiểu dữ liệu hợp lý cho biến 4 Khởi tao biến
5 Sử dụng biến trung gian
6 Sư dụng biến tro
Trang 15
Biến (variable)
Ndi dung Dia chi
Trang 17
2 Đặt tên
Chương a)
Các kỹ thuế! + Tên:
T LHÌNH ~ Dùng bảng chữ của mỗi ngôn ngữ lập trình dé đặt tên
phần mềm ~ Tên bắt đầu bằng chữ cái, tiếp theo là chữ cái, chữ số,
I Mở đầu hoặc ký tự khác (_, $, tùy theo ngôn ngữ lập trình)
11 Các kỹ - Tên biến:
aera oie ~ Phải ngắn qọn và cỏ tính chất gơi nhớ hay miềễu tả
1 Khal bao — Bat dau bang chữ In thưởng
~ Nên là đanh tử hoặc cụm danh từ, nếu là cụm danh tử
thì có thế viết hoa chữ cải đầu của các danh tử tiếp
theo
* int myfirstNumber, mySecondNunber;
~- Chỉ đặt tên biễn hằng 1 chữ cải cho các biến trung gian hoặc biến đếm
¢ int 1 = @; (i,ÍJ,k, ,n)
* char c; (c,d, e)
Trang 18
Đặt tên biến trong C
°Ò Đặt đúng tên cho biến là điều quan trọng -Ổ Nên có chú thích biến đó dùng làm gì trong
Trang 19
Đặt tên biến trong C
Trang 203 Sử dụng các kiểu dữ liệu hợp lý * Hay chọn các kiểu dữ liệu sao cho chương trình trở nên đơn giản — float: dung cho - Các phép tính toán cần kết quả là số thực ~ 3.8 /2.8~ 1.5 « Khi chấp nhận được sai số nhỏ ~ 8,9999999 trở thành 1.6 ~ double:
-_ Khi cần kết quả tính toán chính xác hơn nữa - Khi tốc đồ tính toán là tiêu chí quan trong ~ int:
-Ổ Đánh chỉ số
-_ Mã hóa các trạng thải
* V.V
~ Tốc độ tính toán phụ thuộc vào phần cứng máy tính > chưa chắc
dùng kiểu int là nhanh nhất
Trang 21Ví dụ #include <stdio.h> #include <stdlib.h> KILOMETRES PER_MILE = 1.609; YARDS PER_MILE = 1760.0; int main(void) { miles, yards; kilometres; miles = 26; yards = 385; kilometres = (miles + yards / YARDS PER_MILE) * KILOMETERS PER_MILE;
printf(“ miles and yards ”, miles, yards); printf (“equals kilometres.\n”, kilometres); return EXIT_SUCCESS;
Trang 22Chương nộ Các kỹ thuật chương trình phần mem I Mở đầu IL Các kỹ - thuật làm việc với biển 1 Khai báo 2 Đặt tên 3 Su dung các kiếu dữ liệu hợp lý Khai báo hạn chế các giá trị cùng kiểu
Hãy chọn các kiểu dữ liệu sao cho chương trình
trở nên đơn giản — unsigned: — Signed: — long: - short ) —- const:
short int small no; unsigned char uchar; long double precise_number;
short float not_so_precise;
onst short float pi = 3.14;
Trang 23
chuong Il Các kỹ thu chương trinh phan mềm I Mở đầu IL Các ký - thuật làm việc với biến 1 Khai báo 2 Đặt tên 3 Sử dụ các kiểu dữ liệu hợp lý Ép kiểu int total_candy = 9, number_of_people = 4; double candy_per_person;
candy_per_person = total_candy / number_of_people;
Trang 24Ề nv Ep kieu int total_candy = 9, number_of_people = 4; double candy_per_person;
candy _per_person = total_candy / number_of_people;
-_ Ép kiểu là việc chuyển từ 1 giá trị kiểu này sang 1 giá
trị kiểu khác tương đương
Trang 25
Ví dụ về ép kiểu
#include <stdio.h> #include <stdlib.h>
const float KILOMETRES PER_MILE = 1.609; const float YARDS PER_MILE = 1760.8; int main(void) { int miles, yards; float kilometres; miles = 26; yards = 385; kilometres =
printf(“%d miles and %d yards ”, miles, yards); printf(“equals %f kilometres.\n”, kilometres); return EXIT_SUCCESS;
Trang 28
Khởi tạo 1 lần, dùng nhiều lần
Lưu ý: việc khai báo và khởi tạo biến global cho phép
nhiều CTC trong chương trình truy nhập và thay đổi giá trị
biến
Với các chương trình được thiết kế theo modul, việc này
có thể làm cho
— cấu trúc chương trình bị phá vỡ
~ khó gỡ rỗi chương trinh
double defaultValue = sin(8.25);
float f() { ae value = defaultValue; — |
Trang 30
Chương mo Các kỹ thuật chương trinh phan mem 1 Md dau II Các kỹ - thuật làm việc với biển 1 Kha| báo 2 Đặt tên 3 Sử dụng các kiểu đữ liệu hợp lý 4 Khởi biến tạo Giá trị khởi tạo (initialized value)
+ - Khởi tạo biến: lần đầu tiên gán giá trị cho một biến,
+ Giá trị của một biến chưa khởi tạo là không biết trước,
có thể là giá trị còn lưu lại từ lần chạy chương trình trước đó trong các ô nhớ tương ứng hoặc giá trị rỗng
Trang 31
Khai báo biến tính (Static Variables)
* Cac bién khai báo trong chương trình con (CTC) được cã
phát bộ nhớ khi CTC được gọi và sẽ bị loại bỏ khi kết thúc CTC
- Khi gọi lại CTC, các biến cục bộ lại được cấp phát và khởi
tạo lại
* Nếu muốn 1 giá trị vẫn được lưu lại cho đến khi kết thúc toàn chương trình, cần khai bao bién cục bộ của CTC đó là static và khởi tạo cho nó 1 giá tri
~ Việc khởi tạo sẽ chỉ thực hiện lân đầu tiên chương trình được gọi và giá trị sau khi biến đối sẽ được lưu cho các lần gọi sau ~ Bằng cách nay 1 CTC có thế "nhớ” một vài thông tin sau mỗi lần
được gọi
* Dung bién static thay vi global :
- Khi khai báo 1 biến cục bộ của CTC là biến static, ta tránh được việc bị các phần khác của CT chính làm thay đổi trạng thái CTC
Trang 32void sumit() { static int sum = @; int num; printf(‘*Enter a number: ”); scanf(“Xd”, &num) ; sum += num; print#(“ The current total is %d\n”, sum); int main() { int count;
printf(“Please enter 5 numbers to be summed\n”); for (count = @; count < MAX; count++)
sumit(); return 9;
Trang 33
Stack, heap
* Khi thực hiện, vùng dữ liệu (data segment) của 1 chương trình được chia làm 3 phần :
— Static data: cac bién todn thé hay
bién tinh, vi dy array, Float_array — Stack data: các biến cục bộ của CTC, vi dy double_array — Heap data: -_ Dữ liệu được cấp phát đông {ví dụ pchar}
Trang 34
Bài tập
/* File: xyz.c */
static int count;
static char name[8]; int main() {
/* program body */
return @;
* Phan ma nguén nao
cua chương trình được
truy nhập và thay đổi
giá trị của các biến
count, name ?
«Ò Giá trị khởi tạo ngầm
định của 2 biến này là gì ?
Trang 355, Thêm biến trung gian —_ Chương HH:
aa - Str dung bién trung gian dé SN - phan biệt các bước tính toán
1 Mé dau — dien dat r6 rang logic nghiệp vụ của chương
II Các kỹ trình
wecvớibiến | ° ƯU điểm:
` ae ~ Làm rõ cấu trúc chương trình 3 Sử dụng các — Rất hiệu quả khi xem lại mã nguồn
nh si” °ồ Không nên lạm dụng việc dùng mã 4 Khởi tạo trung gian, điêu này làm chương trình
biến trở nên khó hiểu và kém hiệu quả
Trang 36
Ví dụ: Thêm biến trung gian
const float YARDS _PER_MILE = 1760.0;
int main(void) f int miles, yards;
float kilometres, yardsInMiles;
miles = 26; yards = 385;
yardsInMiles = (float)yards / YARDS _PER_MILE;
printf("%d yards = %f miles\n", yards, yardsInMiles); kilometres = ((float)miles + yardsInMiles) *
KILOMETRES PER_MILE;
printf(“%d miles and %d yards ”, miles, yards); phintf(“equals %f kilometres.\n”, kilometres); return EXIT SUCCESS;
Trang 375, Thêm biến trung gian
* Chu y su’ dung dung tính chất của biến đã khai báo ~ const : không được thay đổi giá trị của biến sau khi khởi tạo
const int FIVE = 5; const int FIVE = 5;
Trang 38
5, Thêm biến trung gian
„ _ Chú ý sử dụng đúng tính chất của biến đã khai báo ~ volatile : giá trị của biến có thể được 1 tiến trình bên ngoài
chương trình thay đổi, thường sử dụng để trao đổi dữ liệu
với thiết bị ngoại vi
obuf(void) ¢
Nếu không khai báo iobuf là volatile, trình dịch bỏ qua không thực hiện vòng lặp vi không có lệnh bên trong
Trang 396 Con trỏ (pointer) * Con tro la một biến mà giá trị của nó là địa chỉ của một vùng nhớ ~ Chứa địa chỉ của một đối tượng khác: biển, hàm fel Tš]
- Sử dụng con trỏ cho phép ta truy nhập tới 1 đối tượng gián tiếp qua địa chỉ của nó
-Ò Trong C/C++, con trỏ là một công cụ rất mạnh, linh hoạt
Trang 40
a Khai báo và sử dụng con trỏ
* Khai bao con trỏ: Biến Địa chỉ Giá trị
kieuDL *<tenBienConTro>; a FFEC | 3
« Vi du:
int a = 3;
int *p; p = &a;
- Có nhiều kiểu biến với các kích thước khác
nhau, nên có nhiêu kiểu con trỏ
— Con trỏ int dé trỏ tới biến hay hàm kiểu int
~ Chỉ có thể trỏ tới một đối tượng cùng kiểu
Trang 41
a Khai báo và sử dụng con trỏ
°Ò Toán tử & va *
— Toán tử s: Trả về địa chỉ của biến
~ Toản từ *: Trả về giá trị chứa trong vùng nhớ được trỏ bởi biến con trỏ
~- * và & có độ ưu tiên cao hơn tất cả các toán tử số học ngoại trừ
Trang 42ng III rg thuat chương trinh phan mem 1 Mở đầu II Các kỹ - thuật làm việc với biến 1 Khal báo 2 Đặt tên 3 Sử dụng các kiểu đữ liệu hợp lý 4 Khởi tạo biễn 5 Con tro
a Khai bao va su dụng con trỏ
- Một biến con trỏ có thể được gán bởi:
Trang 43
Ví dụ 1
° Có thể viết *p 0 thể v cho mọi nơi có đối tượng mà
Trang 46Chương mộ Các kỹ thuật chương trinh phần mềm 1 Mở đầu IL Các ký - thuật làm việc với biến 1 Khai báo 2 Đặt tên 3 Sử dụng các kiểu đữ liệu hợp lý 4 Khởi tạo biến 5 Con tro
b Cac phép toan trén con tro
= C6 thé céng hoac trir bién con tro vdi 1 sé
nguyên n
- Kết quả là 1 con trỏ củng kiểu
— La dja chi mới trỏ tới 1 đối tượng khác nằm cách
đổi tượng đang bị trỏ n phần tử
* Phép trừ giữa 2 con trỏ cho ta khoảng cách (số
phần tử) giữa 2 con trỏ
° _ Không có phép cộng, nhân, chia, lấy số dư 2 con trỏ
°‹ Ví dụ:
~ char c, *pchar = &C;
— shorts, *pshort = &s;
~ long |, *plong = &l; - pchar ++;
— pshort +4;
~ plong ;
Trang 47
b Các phép toán trên con trỏ
Trang 48
b Các phép toán trên con trỏ
-Ò Có thể dùng các phép gán, so sánh các con trỏ,
nhưng cần chú ý đến sự tương thích về kiểu
-Ổ Cần ép kiểu nếu gán không đúng kiểu
double x = 1.5;
char *cPtr = &x; //Error: type mismatch char *cPtr (char *)&x;
// OK: cPtr points to the first byte of x
Trang 49Chương [IÍ xây đưng b chương trinh phan mem I Mở đầu II Các kỹ - thuật làm việc với biến 1 Kha| báo 2 Đặt tên 3 Sử dụng các kiểu đữ liệu hợp lý 4 Khởi tạo biến 5 Con trỏ
c Con tro void
* Con tré dac biét, khéng dinh kiéu * C6 thé nhan gia trị là địa chỉ của một
Trang 50
c Con trỏ void
* Thuc chat con tro void chỉ chứa một địa chỉ bộ nhớ mà
không biết tại địa chỉ đó có đối tượng kiêu dữ liệu gì - _ Không thể truy cập nội dung của một đối tượng thông qua
con tro void
* Phai ép kiéu vé con tré cé dinh kiéu cua kiéu déi tung
float x; int y;
void *p; p = &x;
*b = 2.5; // báo lỗi vì p là con trỏ void
/* cần phải ép kiếu con trỏ void trước khi truy cập đối
tượng qua con trỏ */
*((float*)p) = 2.5; // x = 2.5
p = &y; // p chứa địa chỉ số nguyên y
*((int*)p) = 2; // y = 2