Bài giảng Kỹ thuât lập trình - Chương 3: Mảng, chuỗi và hàm cung cấp cho người học các kiến thức: Mảng, chuỗi, mảng chuỗi, hàm, đệ quy, hàm và mảng dữ liệu, tổ chức chương trình. Mời các bạn cùng tham khảo nội dung chi tiết.
Trang 1Chương III
Mảng, Chuỗi và Hàm
Trang 3• <tên kiểu> <tên mảng>[số thành phần] ; // không khởi tạo
• <tên kiểu> <tên mảng>[số thành phần] = { dãy giá trị } ;
/* có khởi tạo */
• <tên kiểu> <tên mảng>[ ] = { dãy giá trị } ; // có khởi tạo
Cách sử dụng: Để chỉ thành phần thứ i (hay chỉ số i) của một
mảng ta viết tên mảng kèm theo chỉ số trong cặp ngoặc vuông [].
Trang 4cout<< "Nhap so phan tu cua day: "; cin >> n;
for (i = 0; i<n; i++) { cout<< "a[" << i << "] = "; cin>>a[i] ; } min = a[0];
for (i = 1; i<n; i++)
if (a[i] < min) min = a[i];
cout << "So be nhat la " << min << '\n';
}
Trang 53.1 Mảng
B Mảng nhiều chiều
Để thuận tiện trong việc biểu diễn các loại dữ liệu phứctạp như ma trận hoặc các bảng biểu có nhiều chỉ tiêu, C++ đưa rakiểu dữ liệu mảng nhiều chiều Tuy nhiên, việc sử dụng mảngnhiều chiều rất khó lập trình vì vậy trong mục này chúng ta chỉbàn đến mảng hai chiều
Trang 6được sắp liên tiếp theo từng
dòng của mảng như minh hoạ
trong hình dưới đây
0 A[0][0] A[0][1] A[0][2] A[0][3]
1 A[1][0] A[1][1] A[1][2] A[1][3]
2 A[2][0] A[2][1] A[2][2] A[2][3]
A[0][0] A[0][1] A[0][2] A[0][3] A[1][0] A[1][1] A[1][2] A[1][3] A[2][0] A[2][1] A[2][2] A[2][3]
Trang 7Mảng hai chiều
Cú pháp khai báo:
<kiểu thành phần > <tên mảng>[m][n] ;
– m, n là số hàng, số cột của mảng.
– Kiểu thành phần là kiểu của m*n phần tử trong mảng.
– Trong khai báo cũng có thể được khởi tạo bằng dãy các dòng giá trị, các dòng cách nhau bởi dấu phẩy, mỗi dòng được bao bởi cặp ngoặc {} và toàn bộ giá trị khởi tạo nằm trong cặp dấu {}.
Sử dụng: Để truy nhập phần tử của mảng ta sử dụng tên mảng
kèm theo 2 chỉ số chỉ vị trí hàng và cột của phần tử Các chỉ số này có thể là các biểu thức thực, khi đó C++ sẽ tự chuyển kiểu sang nguyên.
Trang 8Ví dụ: Tìm phần tử nhỏ nhất của mảng hai chiều
cout<< "Nhap so hang va so cot:\n"; cin >> m>> n;
for (i = 0; i<m; i++)
for (j = 0; j<n; j++)
{ cout<< "a[" << i << "]["<<j<<"] = "; cin>>a[i][j]; }
min = a[0][0];//Gán min bằng phần tử đầu tiên
for (i = 1; i<n; i++)
for (j = 0; j < n; j++)
if (a[i][j] < min) min = a[i][j];
cout << "So be nhat la " << min << '\n';
Trang 93.2 Chuỗi
Chuỗi hay xâu kí tự là một mảng các kí tự bất kì được kết thúc bằng kí tự ‘\0’.
Hình vẽ trên minh hoạ 3 xâu, mỗi xâu được chứa trong mảng kí tự
có độ dài tối đa là 8 Nội dung xâu thứ nhất là “TINHOC" có độ dài thực tế là 6 kí tự, chiếm 7 ô trong mảng (thêm ô chứa kí tự kết thúc '\0') Xâu thứ hai có nội dung “TIN" với độ dài 3 (chiếm 4 ô) và xâu cuối cùng biểu thị một xâu rỗng (chiếm 1 ô).
Chú ý : Mảng kí tự được khai báo với độ dài 8 tuy nhiên các xâu
có thể chỉ chiếm một số kí tự nào đó trong mảng này và tối đa là 7 kí tự.
T I N H O C \0
T I N \0 H O C \0
\0 T I H O C \0
Trang 103.2 Chuỗi
Khai báo chuỗi:
char <tên chuỗi>[độ dài] ; // không khởi tạo char <tên chuỗi>[độ dài] = xâu kí tự ; // có khởi tạo char <tên chuỗi>[] = xâu kí tự ; // có khởi tạo
‒ Độ dài mảng là số kí tự tối đa có thể có trong xâu Độ dài thực sự của xâu chỉ tính từ đầu mảng đến dấu kết thúc xâu (không kể dấu kết thúc xâu ‘\0’) Do vậy trong khai báo độ dài của mảng cần phải khai báo thừa ra một phần tử.
‒ Cách khai báo thứ hai có kèm theo khởi tạo xâu, đó là dãy kí tự đặt giữa cặp dấu nháy kép.
‒ Cách khai báo thứ 3 tự chương trình sẽ quyết định độ dài của mảng bởi xâu khởi tạo (bằng độ dài xâu + 1).
Ví dụ:
char thang[] = "Muoi hai" ; // độ dài mảng = 9
Trang 113.2 Chuỗi
Cách sử dụng: Sử dụng tương tự như mảng các giá trị số
Nhập chuỗi với hàm cin.getline(s, n);
Ví dụ:
#include<iostream>
using namespace std;
int main() {
Trang 12Một số hàm xử lý chuỗi trong #include<string.h>
• strcpy(s, t) ;
Hàm sẽ sao chép toàn bộ nội dung của xâu t (kể cả kí tự kết thúc xâu ‘\0’) vào cho xâu s Để sử dụng hàm này cần đảm bảo độ dài của mảng s ít nhất cũng bằng độ dài của mảng t Trong trường hợp ngược lại
kí tự kết thúc xâu sẽ không được ghi vào s và điều này có thể gây treo máy khi chạy chương trình.
Ví dụ: #include<iostream>
#include<string.h>
using namespace std;
int main() {
Trang 13Một số hàm xử lý chuỗi trong #include<string.h>
• strncpy(s, t, n) ;
Sao chép n kí tự của t vào s Hàm này chỉ làm nhiệm vụ saochép, không tự động gắn kí tự kết thúc xâu cho s Do vậy NSDphải thêm lệnh đặt kí tự '\0' vào cuối xâu s sau khi sao chép xong
Ví dụ: #include<iostream>
#include<string.h>
using namespace std;
int main() {
char s[15], t[20] = "Tin hoc dai cuong";
strncpy(s, t, 3); // copy 3 kí tự "Tin" vào s
Trang 14Một số hàm xử lý chuỗi trong #include<string.h>
• strcat(s, t);
Nối một bản sao của t vào sau s (thay cho phép +) Hiển nhiênhàm sẽ loại bỏ kí tự kết thúc xâu s trước khi nối thêm t Việc nối
sẽ đảm bảo lấy cả kí tự kết thúc của xâu t vào cho s (nếu s đủ chỗ)
vì vậy NSD không cần thêm kí tự này vào cuối xâu
Ví dụ: #include<iostream>
#include<string.h>
using namespace std;
int main() {
char a[100] = "Nam", b[4] = "Bac";
strcat(a, " va ");
strcat(a, b);
cout << a; //Sẽ xuất ra “Nam va Bac”
}
Trang 15Một số hàm xử lý chuỗi trong #include<string.h>
• strncat(s, t, n);
Nối bản sao n kí tự đầu tiên của xâu t vào sau xâu s Hàm tựđộng đặt thêm dấu kết thúc xâu vào s sau khi nối xong
Tương tự, có thể sử dụng cách viết strncat(s, t+k, n) để nối n
kí tự từ vị trí thứ k của xâu t cho s
• strcmp(s, t);
Hàm so sánh 2 xâu s và t (thay cho các phép toán so sánh).Giá trị trả lại là hiệu 2 kí tự khác nhau đầu tiên của s và t Từ đó,nếu s1 < s2 thì hàm trả lại giá trị âm, bằng 0 nếu s1==s2, vàdương nếu s1 > s2 Trong trường hợp chỉ quan tâm đến so sánhbằng, nếu hàm trả lại giá trị 0 là 2 xâu bằng nhau và nếu giá trị trảlại khác 0 là 2 xâu khác nhau
Trang 16Một số hàm xử lý chuỗi trong #include<string.h>
Trang 18cout<<"Nhap vao ho va ten sinh vien thu " <<i+1<<" :\n";
cin.getline(Sinh_vien[i], 24);//Nhập tối đa 24 kí tự cho chuỗi Sinh_vien[i]
}
cout<<"Danh sach sinh vien vua nhap la: \n";
for( i=0; i<10; i++)
cout<<"Sinh vien thu "<<i+1<<": "<<Sinh_vien[i]<<"\n";
}
Trang 193.4 Hàm
Định nghĩa hàm:
Hoặc :
Lưu ý: C không cho phép các hàm lồng nhau, nghĩa là phần
định nghĩa của hàm này phải độc lập hoàn toàn với hàm khác.
Kiểu_trả_về tên_hàm (kiểu và danh_sách_tham_số)
Trang 203.4 Hàm
Khai báo nguyên mẫu hàm : Khai báo nguyên mẫu hàm sẽ
cung cấp cho trình biên dịch mô tả về một hàm sẽ được định nghĩa ở một vị trí nào đó trong chương trình:
Gọi hàm:
Trong danh_sách_đối_số không đưa ra kiểu dữ liệu của đối
số Nếu hàm cần truyền nhiều đối số thì chúng phải tách nhau bởi dấu phẩy Nếu đối số là mảng thì chỉ cần ghi tên mảng.
Kiểu_trả_về tên_hàm (kiểu và danh_sách_tham_số);
Tên_hàm (danh_sách_đối_số) ;
Trang 21Ví dụ 1: Định nghĩa và gọi hàm tính giai thừa
Trang 22cout<<"So lon nhat trong ba so vua nhap la: ";
t=max(x,y,z); //Gọi hàm max
cout<< t;
Trang 233.5 Đệ quy
Hàm đệ quy là hàm mà từ một điểm trong thân của nó có thể
gọi tên hàm của chính nó
Cấu trúc tổng quát của hàm đệ qui thường như sau:
if (trường hợp cơ sở) {
trình bày cách giải // giả định đã có cách giải
} else // trường hợp tổng quát
{
Gọi lại hàm với tham đối "bé" hơn
}
Trang 24Ví dụ 1: Hàm đệ quy tính UCLN của 2 số
#include<iostream>
using namespace std;
int UCLN(int a, int b)
{
if(a==b)return a; //Trường hợp cơ sở
if(a>b)return UCLN(a-b, b); //Thuật toán Euclid
if(a<b)return UCLN(a, b-a);
}
int main()
{
int x, y, uc;
cout<<"Nhap vao 2 so nguyen:\n"; cin>>x>>y;
cout<<"UCLL cua 2 so "<<x<<" va "<<y<<" la: "<< UCLN(x,y);
Trang 25Ví dụ 2: Tính số hạng thứ n của dãy Fibonaci
//Phần tử thứ n bằng tổng của (phần tử thứ n-1) và (phần tử thứ n-2) }
int main()
{
cout<<"Phan tu thu 7 cua day Fibonacci la: "; cout<<Fibo(7);
cout<<"\n8 phan tu dau tien cua day Fibonacci la:\n";
for(int i=1; i<=8; i++) cout<<Fibo(i)<<"\t";
Trang 26if(a[i]>a[j]) //Nếu phần tử a[i]>a[j] ( a[j] - Các phần tử sau a[i])
{ t=a[i]; a[i]=a[j]; a[j]=t; } //hoán đổi a[i] cho a[j]
Trang 27return mc; //Trả về mc (chính là giá trị lớn nhất của mảng) cho hàm MAX }
Trang 283.7 Tổ chức chương trình
Các loại biến và phạm vi
Biến cục bộ
Biến ngoài hay biến toàn cục
Biến với mục đích đặc biệt
Biến hằng và từ khóa const
Biến tĩnh và từ khóa static
Biến thanh ghi và từ khóa register
Biến ngoài và từ khóa extern
Các chỉ thị tiền xử lý
Chỉ thị bao hàm tệp #include
Chỉ thị macro #define
Chỉ thị #ifdef và #ifndef
Trang 29Bài tập chương III
Viết chương trình giải các bài tập sau ( nên dùng hàm) :
Bài 1 Nhập dữ liệu cho dãy số nguyên gồm n phần tử (n<=50).
A Xác định số phần tử là số chẵn mà lớn hơn 30 trong mảng
B Tìm giá trị nhỏ nhất trong mảng và số lần xuất hiện của nó
C Sắp xếp mảng tăng dần
D Xóa tất cả các phần tử có giá trị bằng x ở trong mảng
E Chèn vào mảng phần tử y sao cho mảng vẫn tăng dần
Bài 2 Nhập dữ liệu cho 2 ma trận số nguyên A và B đều gồm m
Trang 30Bài tập chương III
Bài 4 Nhập dữ liệu cho xâu kí tự str[100]
A Xuất ra màn hình xâu str
B Xâu str có bao nhiêu kí tự và trong đó bao nhiêu kí tự là số
C Loại bỏ các kí tự không phải là chữ hoặc không phải khoảng
trống trong xâu str
D Đổi chữ thường trong xâu str thành chữ in hoa
E Chèn vào xâu str một xâu str2 khác vào vị trí bất kì trong str
Bài 5 Nhập dữ liệu cho mảng chuỗi A gồm n sinh viên (n<=50).
A Xuất các chuỗi trong A ra màn hình
B Tìm xem trong A có bao nhiêu người có họ là “Nguyen”
C Dựa vào họ hãy sắp xếp A tăng dần (a z)
D Xuất ra màn hình tên của các sinh viên dưới dạng chữ in hoa
Trang 31Bài tập chương III
Bài 6 Viết hàm đệ qui tính n!
A Tính tổ hợp chập k của n phần tử ( Nếu tồn tại)
B Tính hệ số của số hạng thứ k trong khai triển nhị thức Newton
của : ( + )
C Xuất ra tất cả các hệ số của khai triển nhị thức ở câu B trên
D Xuất ra màn hình tam giác Pascal
Bài 7 Viết hàm đệ qui tính số fibonaci thứ n
A Xuất ra n phần tử đầu tiên của dãy Fibonacci
B Xuất ra màn hình k phần tử chẵn đầu tiên của dãy Fibonacci
C Xuất ra phần tử lẻ thứ m của dãy Fibonacci
( Cho dãy Fibonacci: 0,1, 1, 2, 3, 5, 8, 13, 21,….)
Trang 32www.themegallery.com