Bài giảng Lập trình - Chương 2: Tổng quan về C/C++

#include

#include

int gthua(int);

void main() {

char c = 'N';

int N = 1;

do {

cout < “\nnhap="" mot="" so="" nguyen="" duong:="">

cin >> N;

int kq = gthua(N);

cout < “\ngiai="" thua="" cua="" ”="">< n="">< “="" la="" “=""><>

cout < “\nban="" co="" muon="" tiep="" tuc="" khong?="">

c = getch();

} while (c == 'y' || c == 'Y');

}

int gthua(int n) {

int kq = 1;

while (n > 1)

kq *= n--;

return kq;

}

1. Tên biến, tên hàm, tên kiểu mới:

 Tránh sử dụng các từ khóa và tên kiểu cơ sở

 Chỉ được dùng các ký tự sau: ‘A’.’Z’, ‘a’.’z’, ‘0’.’9’, ‘_’

 Chỉ được bắt đầu bằng chữ cái hoặc dấu _

 Phân biệt giữa chữ hoa và chữ thường.

 Nên đặt tên ngắn gọn và có ý nghĩa (có tính mô tả)

2. Sau mỗi câu lệnh có chấm phảy (;)

3. Đoạn { } được coi là nhóm lệnh, không có dấu

chấm phảy sau đó, trừ khi khai báo kiểu

4. Cấu trúc mã nguồn theo kiểu phân cấp => dễ đọc

5. Bổ sung chú thích hợp lý (/*chú thích một đoạn*/hoặc

//chú thích một dòng)

6. Chia một file lớn thành nhiều file nhỏ

Bài giảng Lập trình - Chương 2: Tổng quan về C/C++ trang 1

Trang 1

Bài giảng Lập trình - Chương 2: Tổng quan về C/C++ trang 2

Trang 2

Bài giảng Lập trình - Chương 2: Tổng quan về C/C++ trang 3

Trang 3

Bài giảng Lập trình - Chương 2: Tổng quan về C/C++ trang 4

Trang 4

Bài giảng Lập trình - Chương 2: Tổng quan về C/C++ trang 5

Trang 5

Bài giảng Lập trình - Chương 2: Tổng quan về C/C++ trang 6

Trang 6

Bài giảng Lập trình - Chương 2: Tổng quan về C/C++ trang 7

Trang 7

Bài giảng Lập trình - Chương 2: Tổng quan về C/C++ trang 8

Trang 8

Bài giảng Lập trình - Chương 2: Tổng quan về C/C++ trang 9

Trang 9

Bài giảng Lập trình - Chương 2: Tổng quan về C/C++ trang 10

Trang 10

Tải về để xem bản đầy đủ

pdf 83 trang duykhanh 6880
Bạn đang xem 10 trang mẫu của tài liệu "Bài giảng Lập trình - Chương 2: Tổng quan về C/C++", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

Tóm tắt nội dung tài liệu: Bài giảng Lập trình - Chương 2: Tổng quan về C/C++

Bài giảng Lập trình - Chương 2: Tổng quan về C/C++
 4 is 36
 { 9 times 5 is 45
 cout<<i<< “ times”<<j<<“ is”<<i*j<“\n”; 9 times 6 is 54
 } 9 times 7 is 63
 }
 9 times 8 is 72
 9 times 9 is 81
Chương 2: Tổng quan về C và C++ 48
 2.6 Hàm và thư viện
 Hàm là gì?
 . Một đơn vị tổ chức chương trình, một đoạn mã 
 chương trình có cấu trúc để thực hiện một chức 
 năng nhất định, cógiá trị sử dụng lại
 . Các hàm có quan hệ với nhau thông qua lời gọi, các 
 biến tham số (đầu vào, đầu ra) và giá trị trả về
 . Cách thực hiện cụ thể một hàm phụ thuộc nhiều vào 
 dữ kiện (tham số, đối số của hàm):
 – Thông thường, kết quả thực hiện hàm mỗi lần đều giống 
 nhau nếu các tham số đầu vào như nhau
 – Một hàm không có tham số thì giá trị sử dụng lại rất thấp
 . Trong C/C++: Không phân biệt giữa thủ tục và hàm, 
 cả đoạn mã chương trình chính cũng là hàm
Chương 2: Tổng quan về C và C++ 49
 Ví dụ
 . Yêu cầu bài toán: Tính tổng một dãy số nguyên (liên 
 tục) trong phạm vi do người sử dụng nhập. In kết quả 
 ra màn hình.
 . Các nhiệm vụ:
 – Nhập số nguyên thứ nhất: 
  Yêu cầu người sử dụng nhập
  Nhập số vào một biến 
 – Nhập số nguyên thứ hai
  Yêu cầu người sử dụng nhập
  Nhập số vào một biến 
 – Tính tổng với vòng lặp
 – Hiển thị kết quả ra màn hình
Chương 2: Tổng quan về C và C++ 50
 Ví dụ: Cách 1
 #include 
 void main() {
 int a, b;
 char c;
 do {
 cout << “Nhap so nguyen thu nhat: ";
 cin >> a;
 cout << “Nhap so nguyen thu hai: ";
 cin >> b;
 int tong = 0;
 for (int i = a; i <= b; ++i)
 tong += i;
 cout << "Tong tu " << a << " den " << b
 << " la " << tong << endl;
 cout << “ban co muon tinh tiep? (Y/N):";
 cin >> c;
 } while (c == 'y' || c == 'Y');
 }
Chương 2: Tổng quan về C và C++ 51
 Cách 2 (phân hoạch hàm)
 #include 
 int Nhap();
 int Tinh_tong(int,int);
 void Hien_thi(int a, int b, int kq);
 void main() {
 char c;
 do {
 int a = Nhap();
 int b = Nhap();
 int T = Tinh_tong(a,b);
 Hien_thi(a,b,T);
 cout << “Ban co muon tinh tiep? (Y/N):";
 cin >> c;
 } while (c == 'y' || c == 'Y');
 }
Chương 2: Tổng quan về C và C++ 52
 Cách 2 ()
 int Nhap() {
 cout << “Nhap mot so nguyen: ";
 int N;
 cin >> N;
 return N;
 }
 int Tinh_tong(int a, int b) {
 int T = 0;
 for (int i = a; i <= b; ++i)
 T += i;
 return T;
 }
 void Hien_thi (int a, int b, int kq) {
 cout << "Tong tu " << a << " den " << b
 << " la " << kq << endl;
 }
Chương 2: Tổng quan về C và C++ 53
 Ưu nhược điểm của phân hoạch hàm
 . Chương trình dễ đọc hơn => dễ phát hiện lỗi
 . Chương trình dễ mở rộng hơn
 . Có giá trị sử dụng lại
 . Mã nguồn dài hơn
 . Mã chạy lớn hơn
 . Chạy chậm hơn
  Không phải cứ phân hoạch thành nhiều hàm là tốt, 
 mà vấn đề nằm ở cách phân hoạch và thiết kế hàm 
 làm sao cho tối ưu!
Chương 2: Tổng quan về C và C++ 54
 3.2 Khai báo và định nghĩa hàm
 . Định nghĩa hàm: tạo mã thực thi hàm
Kiểu trả về Tên hàm Tham biến (hình thức)
 int Tinh_tong(int a, int b) {
 int T = 0;
 for (int i = a; i <= b; ++i)
 T += i;
 return T;
 }
 . Khai báo hàm thuần túy: không tạo mã hàm
 int Tinh_tong (int a, int b);
Kiểu trả về Tên hàm Kiểu tham biến
 . Tại sao và khi nào cần khai báo hàm?
 Chương 2: Tổng quan về C và C++ 55
Khai báo hàm và lời gọi hàm
 . Ý nghĩa của khai báo hàm:
 – Khi cần sử dụng hàm (gọi hàm)
 – Trình biên dịch cần lời khai báo hàm để kiểm tra lời gọi hàm 
 đúng hay sai về cú pháp, về số lượng các tham số, kiểu các 
 tham số và cách sử dụng giá trị trả về.
 int Tinh_tong(int a, int b);
 – Có thể khai báo hàm độc lập với việc định nghĩa hàm (tất 
 nhiên phải đảm bảo nhất quán)
 . Có thể định nghĩa hàm sau lời gọi hàm
 . Gọihàm: yêu cầu thực thi mã hàm với tham số thực tế (tham 
 trị)
 int x = 5;
 int k = Tinh_tong(x, 10);
 Tên hàm Tham số (gọi hàm)
Chương 2: Tổng quan về C và C++ 56
Khai báo hàm C/C++ ở đâu?
 . Ở phạm vi toàn cục (ngoài bất cứ hàm nào)
 . Một hàm phải được khai báo trước lời gọi đầu tiên 
 trong một tệp tin mã nguồn
 . Nếu sử dụng nhiều hàm thì sẽ cần rất nhiều dòng mã 
 khai báo (mất công viết, dễ sai và mã chương trình 
 lớn lên?):
 – Nếu người xây dựng hàm (định nghĩa hàm) đưa sẵn tất cả 
 phần khai báo vào trong một tệp tin => Header file (*.h, 
 *.hx,...) thì người sử dụng chỉ cần bổ sung dòng lệnh
 #include 
 – Mã chương trình không lớn lên, bởi khai báo không sinh mã!
 . Một hàm có thể khai báo nhiều lần tùy ý!
Chương 2: Tổng quan về C và C++ 57
Định nghĩa hàm ở đâu?
 . Ở phạm vi toàn cục (ngoài bất cứ hàm nào)
 . Có thể định nghĩa trong cùng tệp tin với mã chương trình chính, 
 hoặc tách ra một tệp tin riêng. Trong Visual C++: 
 *.c => C compiler, 
 *.cpp => C++ compiler
 . Một hàm đã có lời gọi thì phải được định nghĩa chính xác 1 lần 
 trong toàn bộ (dự án) chương trình, trước khi gọi trình liên kết 
 (lệnh Build trong Visual C++)
 . Đưa tệp tin mã nguồn vào dự án, không nên: 
 #include “xxx.cpp”
 . Một hàm được địnhnghĩa sẵn bằng C, C++, hợp ngữ hoặc bằng 
 một ngôn ngữ khác và dùng trong C/C++ => Sử dụng hàm 
 không cần mã nguồn!
 . Một thư viện cho C/C++ bao gồm:
 – Header file (thường đuôi *.h, *.hxx, ..., nhưng không bắt buộc) 
 – Tệp tin mã nguồn (*.c, *.cpp, *.cxx,...) hoặc mã đích 
 (*.obj, *.o, *.lib, *.dll, ...)
Chương 2: Tổng quan về C và C++ 58
Tham biến hình thức và tham số thực tế 
 int Tinh_tong (int a, int b) {
 ...
 } Tham biến
 (hình thức)
 int x = 5;
 int k = Tinh_tong (x, 10);
 ...
 Tham số 
 (thực tế)
 int a = 2;
 k = Tinh_tong (a,x);
Chương 2: Tổng quan về C và C++ 59
Truyền giá trị
 int Tinh_tong (int, int);
 void main() {
 int x = 5;
 int k = Tinh_tong(x, 10);
 SP
 ... b = 10
 } a = 5
 SP
 k =k 45
 // Dinh nghia ham x = 5
 int Tinh_tong(int a, int b) { Ngăn xếp
 ...
 }
Chương 2: Tổng quan về C và C++ 60
Ví dụ
 #include 
 void Nhap(int N) {
 cin >> N;
 }
 void main() {
 int x = 5;
 cout<< “Hay nhap so nguyen: ”;
 Nhap(x);
 cout << “Bay gio x la " << x;
 ...
 }
 . Kết quả: x không hề thay đổi sau đó.
Chương 2: Tổng quan về C và C++ 61
 Truyền giá trị (...)
 . Truyền giá trị là cách thông thường trong C
 . Tham biến chỉ nhận được bản sao của biến đầu vào 
 (tham số thực tế)
 . Thay đổi tham biến chỉ làm thay đổi vùng nhớ cục bộ, 
 không làm thay đổi biến đầu vào
 . Tham biến chỉ có thể mang tham số đầu vào, không 
 chứa được kết quả (tham số ra)
 . Truyền giá trị trong nhiều trường hợp kém hiệu quả 
 do mất công sao chép dữ liệu
Chương 2: Tổng quan về C và C++ 62
 Truyền địa chỉ
 int Tong_mang(int* p, int N);
 // Goi ham
 void main() {
 SP
 int a[] = {1, 2, 3, 4}; k =k 10
 int k = Tong_mang(a,4); N=4
 p=00A0 
 ... SP
 } k =k 10
 a[3]=4
 a[2]=3
 // Dinh nghia ham
 a[1]=2
 int Tong_mang(int* p, int N) { a[0]=1
 int *p2 = p + N, k = 0; 00A0
 while (p < p2) 
 k += *p++;
 return k;
 }
Chương 2: Tổng quan về C và C++ 63
Truyền mảng tham số?
 int Tong_mang(int p[4], int N);
 // Goi ham
 void main() {
 int a[] = {1, 2, 3, 4};
 int k = Tong_mang(a,4);
 Bản chất giống truyền 
 ...
 địa chỉ
 }
 // Dinh nghia ham
 int Tong_mang(int p[4], int N) {
 int *p2 = p + N, k = 0;
 while (p < p2) 
 k += *p++;
 return k;
 }
Chương 2: Tổng quan về C và C++ 64
Thử lại ví dụ trước
 #include 
 void Nhap(int* pN) {
 cin >> *pN;
 }
 void main() {
 int x = 5;
 cout<<“Nhap so nguyen:“;
 Nhap(&x);
 cout << “Bay gio x la " << x;
 ...
 }
 . Kết quả: x thay đổi giá trị sau đó
Chương 2: Tổng quan về C và C++ 65
 Khi nào sử dụng truyền địa chỉ?
 . Khi cần thay đổi "biến đầu vào" (truy nhập trực tiếp 
 vào ô nhớ, không qua bản sao)
 . Khi kích cỡ kiểu dữ liệu lớn => tránh sao chép dữ liệu 
 vào ngăn xếp
 . Truyền tham số là một mảng => bắt buộc truyền địa 
 chỉ
 . Lưu ý: Sử dụng con trỏ để truyền địa chỉ của vùng 
 nhớ dữ liệu đầu vào. Bản thân con trỏ có thể thay đổi 
 được trong hàm nhưng địa chỉ vùng nhớ không thay 
 đổi (nội dung của vùng nhớ đó thay đổiđược) 
Chương 2: Tổng quan về C và C++ 66
 Truyền tham chiếu (C++)
 #include 
 void Nhap(int& N) {
 cin >> N;
 }
 void main() {
 int x = 5;
 cout<<“Nhap so nguyen:“;
 Nhap(x);
 cout << “Bay gio x la " << x;
 ...
 }
 . Kết quả: x thay đổi giá trị sau đó
Chương 2: Tổng quan về C và C++ 67
Ví dụ hàm hoán vị
 . Viết một hàm hoán đổi giá trị của hai phần tử nguyên, sau đó 
 viết chương trình ứng dụng hàm đó.
 . Còn cách nào giải quyết bài toán trên?
Chương 2: Tổng quan về C và C++ 68
 Khi nào sử dụng truyền tham chiếu?
 . Truyền tham chiếu chỉ dùng trongC++ 
 . Khi cần thay đổi "biến đầu vào" (truy nhập trực tiếp 
 vào ô nhớ, không qua bản sao)
 . Một tham biến tham chiếu có thể đóng vai trò là đầu 
 ra (chứa kết quả), hoặc có thể vừa là đầu vào và đầu 
 ra
 . Khi kích cỡ kiểu dữ liệu lớn => tránh sao chép dữ liệu 
 vào ngăn xếp.
Chương 2: Tổng quan về C và C++ 69
 Kiểu trả về
 . Kiểu trả về gần như tùy ý.
 . Không thể trả về trực tiếp một mảng
 . Có thể trả về kiểu:
 – Giá trị
 – Con trỏ (địa chỉ)
 – Tham chiếu
 . Tuy nhiên, cần rất thận trọng với trả về địa chỉ hoặc 
 tham chiếu:
 – Không bao giờ trả về con trỏ hoặc tham chiếu vào biến cục 
 bộ
 – Không bao giờ trả về con trỏ hoặc tham chiếu vào tham 
 biến truyền qua giá trị
Chương 2: Tổng quan về C và C++ 70
 Cơ chế trả về
 int Tinh_tong(int a, int b) {
 int k = 0;
 for (int i=a; i <= b; ++i)
 k +=i;
 SP
 return k; k =45
 } b = 10
 a = 5
 SP
 void main() { k k= =450
 int x = 5, k = 0; x = 5
 k = Tinh_tong(x,10); Ngăn xếp
 ...
 } 45
Chương 2: Tổng quan về C và C++ 71
Trả về con trỏ 
 . Viết hàm tìm giá trị lớn nhất của một mảng?
 . Viết hàm trả về địa chỉ của phần tử lớn nhất trong một mảng?
 . Viết chương trình ứng dụng các hàm trên.
Chương 2: Tổng quan về C và C++ 72
Lý do trả về con trỏ hoặc tham chiếu
. Tương tự như lý do truyền địa chỉ hoặc truyền tham 
 chiếu: 
 – Tránh sao chép dữ liệu lớn không cần thiết
 – Để có thể truy cập trực tiếp và thay đổi giá trị đầu ra
. Có thể trả về con trỏ hoặc tham chiếu vào đâu?
 – Vào biến toàn cục
 – Vào tham số truyền cho hàm qua địa chỉ hoặc qua tham chiếu
 – Nói chung: vào vùng nhớ mà còn tiếp tục tồn tại sau khi kết 
 thúc hàm
Chương 2: Tổng quan về C và C++ 73
 Tham số mặc định của hàm
 . VD: 
 void func(int a, int b=0, int c=0)
 {  }
 void main()
 {
 int x=4, y=5, z=6;
 func(x,y,z);//OK
 func(x,y);//OK
 func(x);//OK
 }
Chương 2: Tổng quan về C và C++ 74
 Tham biến mặc định của hàm (tiếp)
 . Các tham biến mặc phải nằm ở cuối cùng của dãy tham 
 số (tính từ trái sang phải)
 . Tham số thiếu vắng trong lời gọi hàm sẽ tương ứng với 
 các tham biến mặc định cuối cùng (tính từ trái sang 
 phải)
Chương 2: Tổng quan về C và C++ 75
 Ví dụ tìm min, max của mảng 
 . Viết một hàm đồng thời tìm giá trị lớn nhất và giá trị 
 nhỏ nhất của một mảng. Viết một chương trình ứng 
 dụng hàm đó?
Chương 2: Tổng quan về C và C++ 76
 Nạp chồng tên hàm trong C++
 . Trong C++ có thể xây dựng nhiều hàm có cùng tên, ví 
 dụ:
 int max(int a, int b);
 double max(double a, double b);
 double max(double a, double b, double c);
 double max(double *seq, int n);
 . Mục đích củanạp chồng tên hàm:
 – Đơn giản hóa cho người xây dựng hàm trong việc chọn tên 
 (thay vì maxInt, maxDouble, maxDouble3, 
 maxDoubleSequence,...)
 – Đơn giản hóa cho người sử dụng hàm, chỉ cần nhớ1 tên quen 
 thuộc thay cho nhiều tên phức tạp
Chương 2: Tổng quan về C và C++ 77
Ví dụ: định nghĩa các hàm max()
 int max(int a, int b) { // (1)
 return (a > b)? a : b; 
 }
 double max(double a, double b) { // (2)
 return (a > b)? a : b; 
 }
 double max(double a, double b, double c); { // (3)
 if (a < b) a = b;
 if (a < c) a = c;
 return a; 
 }
 double max(double *seq, int n) { // (4)
 int i = 0, kq = seq[0];
 while (i < n) {
 if (kq < seq[i])kq = seq[i];
 ++i;
 }
 return kq;
 }
Chương 2: Tổng quan về C và C++ 78
Ví dụ: sử dụng các hàm max()
 int max(int a, int b); // (1)
 double max(double a, double b); // (2)
 double max(double a, double b, double c); // (3)
 double max(double *seq, int n); // (4)
 void main() {
 int k = max(5,7); // call?
 double d = max(5.0,7.0); // call?
 double a[] = {1,2,3,4,5,6};
 d = max(d, a[1], a[2]); // call?
 d = max(a, 5); // call?
 d = max(5,7); // call?
 d = max(d, 5); // call?
 }
  Đẩy trách nhiệm kiểm tra và tìm hàm phù hợp cho 
 compiler!
Chương 2: Tổng quan về C và C++ 79
Một số qui tắc về nạp chồng tên hàm
 . Các hàm cùng tên được định nghĩa cùng trong 
 một file/ trong một thư viện hoặc sử dụng trong 
 cùng một chương trình phải khác nhau ít nhất về:
 – Số lượng các tham số, hoặc
 – Kiểu của ít nhất một tham số (int khác short, const int
 khác int, int khác int&, ...)
  Không thể chỉ khác nhau ở kiểu trả về
 . Tại sao vậy? 
 – Compiler cần có cơ sở để quyết định gọi hàm nào
 – Dựa vào cú pháp trong lời gọi (số lượng và kiểu các tham số 
 thực tế) compiler sẽ chọn hàm có cú pháp phù hợp nhất
 – Khi cần compiler có thể tự động chuyển đổi kiểu theo chiều 
 hướng hợp lý nhất (vd short=>int, int => double)
Chương 2: Tổng quan về C và C++ 80
 Hàm inline trong C++
 . Vấn đề: Hàm tiện dụng, nhưng nhiều khi hiệu suất 
 không cao, đặc biệt khi mã thực thi hàm ngắn vì
 – Các thủ tục như nhớ lại trạng thái chương trình, cấp phát bộ 
 nhớ ngăn xếp, sao chép tham số, sao chép giá trị trả về, khôi 
 phục trạng thái chương trình mất nhiều thời gian
 – Nếu mã thực thi hàm ngắn thì sự tiện dụng không bõ so 
 với sự lãng phí thời gian
Chương 2: Tổng quan về C và C++ 81
Dùng hàm inline trong C++
 . Điều duy nhất cần làm là thêm từ khóa inline vào 
 đầu dòng khai báo và định nghĩa hàm
 inline int max(int a, int b) {
 return (a > b)? a : b; 
 }
 . Hàm inline khác gì hàm bình thường?
 – "Hàm inline" thực chất không phải là một hàm!
 – Khi gọi hàm thì lời gọi hàm đượcthay thế một cách thông 
 minh bởi mã nguồn định nghĩa hàm, không thực hiện 
 các thủ tục gọi hàm
Chương 2: Tổng quan về C và C++ 82
Khi nào nên dùng hàm inline
 . Ưu điểm của hàm inline:
 – Tiện dụng như hàm bình thường
 – Hiệu suất như viết thẳng mã, không gọi hàm
 – Tin cậy, an toàn.
 . Nhược điểm của hàm inline:
 – Nếu gọi hàm nhiều lần trong chương trình, mã chương trình 
 có thể lớn lên nhiều (mã thực hiện hàm xuất hiện nhiều lần 
 trong chương trình)
 – Mã định nghĩa hàm phải để mở => đưa trong header file
 . Lựa chọn xây dựng và sử dụng hàm inline khi:
 – Mã định nghĩa hàm nhỏ (một vài dòng lệnh, không chứa 
 vòng lặp)
 – Yêu cầu về tốc độ đặt ra trước dung lượng bộ nhớ
Chương 2: Tổng quan về C và C++ 83

File đính kèm:

  • pdfbai_giang_lap_trinh_chuong_2_tong_quan_ve_cc.pdf