Giáo trình Ngôn ngữ lập trình C++ (Phần 1)

Ngôn ngữ lập trình C do Dennis Ritchie và Brian Kernighan xây dựng

năm 1970, thể hiện đ-ợc tất cả các đặc tr-ng của ngôn ngữ lập trình bậc cao

nh-ng cũng có khá đầy đủ các khả năng của ngôn ngữ lập trình bậc thấp.

Cùng với sự phát triển mạnh mẽ của công nghệ thông tin (CNTT), ngôn

ngữ C có rất nhiều phiên bản của các hãng khác nhau nh-C chuẩn, Turbo C,

Microsoft C . Sau ngôn ngữ C là C++ ngoài các tính năng nh-C, C++ còn

đ-ợc bổ sung nhiều tính năng khác, một trong đó làkỹ thuật lập trình h-ớng

đối t-ợng, một h-ớng lập trình rất quan trọng.

pdf51 trang | Chuyên mục: C/C++ | Chia sẻ: dkS00TYs | Lượt xem: 1953 | Lượt tải: 2download
Tóm tắt nội dung Giáo trình Ngôn ngữ lập trình C++ (Phần 1), để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
ào i”. 
Câu lệnh (4): j = *p; 
đ−a vào j nội dung của biến đ−ợc p trỏ tới (* 
là toán tử chỉ h−ớng). 
Câu lệnh (5): *p = j + 4; 
đ−a (nội dung của j) + 4 vào biến đ−ợc p trỏ 
vào. 
Ví dụ ch−ơng trình 5.1: Ch−ơng trình hoàn thiện sa
giải thích ở trên, nh−ng chú ý là các địa chỉ thực của 
giả thiết đã nêu trong nhận xét trên. 
 14 100 p 
00 9 i 14 100 p 
00 5 i 14 p 
00 5 i 14 p 
00 5 i 
00 i 02 5 j 
14 100 p 
u sẽ minh hoạ cho các 
i, j , p ở hệ 16 và khác 
45
Đại học Thái Nguyên-Tr−ờng ĐHSP. Khoa Toán-Tin 
 Nguyễn Mạnh Đức – Ngôn ngữ lập trình C++ 
# include 
# include 
void main() 
{ 
 int i, j, *p; 
 i = 5; 
 p = &i; 
 j = *p; 
 *p = j + 4; 
 clrscr(); 
 cout << "i = " << i << " dia chi = " << &i << endl; 
 cout << "j = " << j << " dia chi = " << &j << endl; 
 cout << "p tro toi dia chi " << p << endl; 
 cout << "p tro vao gia tri " << *p; 
 getch(); 
} 
5.1.5. Các phép toán con trỏ 
• Các giá trị con trỏ có thể xuất dữ liệu với toán tử chèn <<. 
• Các con trỏ không thể nhập dữ liệu. Nếu p là con trỏ thì lệnh nhập sau 
là sai: 
 cin >> p; // Error 
• Các con trỏ có thể đ−ợc gán cho những con trỏ khác cùng kiểu. 
Ví dụ: 
float *px, *py, x; 
px = &x; 
py = px; 
• Các con trỏ có thể đ−ợc tăng hay giảm. 
Ví dụ: 
char st[] = “ABCDEFGH”; 
char p = &st[3]; // p trỏ tới st[3] 
cout << “*p = “ << *p << endl; 
++p; // p trỏ tới st[4] 
cout << “*p = “ << *p << endl; 
p += 3; // p trỏ tới st[7] 
cout << “*p = “ << *p << endl; 
p -=6; // p trỏ tới st[1] 
 46
Đại học Thái Nguyên-Tr−ờng ĐHSP. Khoa Toán-Tin 
 Nguyễn Mạnh Đức – Ngôn ngữ lập trình C++ 
cout << “*p = “ << *p << endl; 
--p; // p trỏ tới st[0] 
cout << “*p = “ << *p << endl; 
Kết quả của đoạn ch−ơng trình trên sẽ là: 
*p = D 
*p = E 
*p = H 
*p = B 
*p = A 
5.2. Con trỏ và mảng 
5.2.1. Con trỏ và mảng một chiều 
Con trỏ th−ờng đ−ợc sử dụng khi xử lý các mảng. 
Chúng ta phân tích ch−ơng trình 5.2 sau đây: 
void main() 
{ 
int a[10], *pa, x; 
 a[0] = 11; a[1] = 22; a[2] = 33; a[3] = 44; 
 pa = &a[0]; 
 x = *pa; 
pa++; 
 x = *pa; 
x = *pa + 1; 
x = *(pa + 1); 
x = *++pa; 
x = ++*pa; 
x = *pa++; 
getch(); 
} 
int a[10], *pa, x; Khai báo mảng 10 số nguyên a[0], a[1], ... a[9], con 
trỏ pa chỉ vào số nguyên và biến nguyên x. 
a[0] = 1; ... khởi đầu các phần tử của mảng. Các phần tử từ a[4] 
tới a[9] còn ch−a đ−ợc khởi đầu, chúng tình cờ chứa 
các giá trị có sẵn trong bộ nhớ. 
pa = &a[0]; Đ−a địa chỉ của phần tử đầu tiên của mảng a vào pa. 
Lệnh này có thể đ−ợc viết đơn giản hơn là: pa = a; 
 47
Đại học Thái Nguyên-Tr−ờng ĐHSP. Khoa Toán-Tin 
 Nguyễn Mạnh Đức – Ngôn ngữ lập trình C++ 
x = *pa; Lấy nội dung của số nguyên đ−ợc pa trỏ vào (tức là 
a[0]) gán cho biến x. Do đó x có giá trị bằng 11. 
pa++; pa đ−ợc tăng một đơn vị, bây giờ nó chứa địa chỉ của 
phần tử thứ hai, đó là địa chỉ của a[1] tức là pa trỏ 
vào a[1]. 
x = *pa; *pa là nội dung của a[1], do đó x có giá trị băng 22. 
x = *pa + 1; Cho x giá trị a[1] + 1, do đó x có giá trị là 22 + 1 = 
23. 
x = *(pa + 1); Tr−ớc tiên hệ thống thực hiện phép toán: pa + 1 
điều đó cho kết quả là địa chỉ của a[2], số nguyên ở 
địa chỉ này đ−ợc đ−a vào x, do vậy x bằng 33. 
Chú ý rằng nếu pa tham gia vào phép toán nó không 
bị thay đổi. 
x = *++pa; Theo độ −u tiên của các toán tử, phép toán ++pa đ−ợc 
thực hiện tr−ớc, do đó pa chứa địa chỉ của a[2]. 
Sau đó thực hiện phép toán *, x chứa địa chỉ a[2] tức 
là x = 33. 
x = ++*pa; Đầu tiên thực hiện *pa, pa đang trỏ vào a[2] nên *pa 
bằng 33, do đó ++*pa bằng 34, do vậy x bằng 34. 
x = *pa++; Nội dung của *pa đ−ợc đặt vào biến x tr−ớc nên x 
bằng 34, sau đó pa đ−ợc tăng một đơn vị và bây giờ 
nó trỏ vào a[3]. 
Qua phân tích ví dụ trên ta thấy rằng: Nếu con trỏ pa trỏ tới phần tử a[k] 
nào đó thì: 
pa + i trỏ tới phần tử thứ i sau a[k], tức là phần tử a[k+i]. 
pa – i trỏ tới phần tử thứ i tr−ớc a[k], tức là phần tử a[k-i]. 
*(pa + i) t−ơng đ−ơng với pa[i]. 
5.2.2. Con trỏ và mảng hai chiều 
Trong mảng nhiều chiều nói chung phép toán lấy địa chỉ & không sử 
dụng đ−ợc, chẳng hạn câu lệnh: 
 48
Đại học Thái Nguyên-Tr−ờng ĐHSP. Khoa Toán-Tin 
 Nguyễn Mạnh Đức – Ngôn ngữ lập trình C++ 
&a[i][j]; 
là không hợp lệ và gây ra lỗi (riêng đối với mảng hai chiều nguyên thì có thể 
sử dụng đ−ợc câu lệnh trên). 
Nh− ta đã biết trong bộ nhớ mảng là các ô nhớ xếp theo thứ tự liên tiếp 
nhau, chẳng hạn nếu khai báo: 
float a[2][3]; 
thì sẽ có 6 phần tử đ−ợc xếp thứ tự (theo hàng) nh− sau: 
phần tử: a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2]
địa chỉ : 1 2 3 4 5 6 
Để lần l−ợt duyệt trên các phần tử của mảng hai chiều, có thể dùng con 
trỏ theo cách sau: 
float *pa, a[2][3]; 
pa = (float*) a; 
Khi đó: 
pa + 0 trỏ tới a[0][0] 
pa + 1 trỏ tới a[0][1] 
pa + 2 trỏ tới a[0][2] 
pa + 3 trỏ tới a[1][0] 
pa + 4 trỏ tới a[1][1] 
pa + 5 trỏ tới a[1][2] 
Ví dụ ch−ơng trình 5.3 sau đây sẽ minh hoạ cho các điều trên. 
# include 
# include 
void main() 
{ 
 float *pa, a[2][3] = {{ 1, 3, 5 }, 
 { 2, 4, 6 }}; 
 pa = (float*) a; 
 clrscr(); 
 for (int i=0; i<6; i++) 
 cout << pa+i << " " << *(pa+i) << endl; 
 getch(); 
} 
 49
Đại học Thái Nguyên-Tr−ờng ĐHSP. Khoa Toán-Tin 
 Nguyễn Mạnh Đức – Ngôn ngữ lập trình C++ 
5.2.3. Mảng con trỏ 
Mảng con trỏ là sự mở rộng của khái niệm con trỏ. Mảng con trỏ là một 
mảng mà mỗi phần tử của nó có thể chứa đ−ợc một địa chỉ nào đó. Cũng 
giống nh− con trỏ, mảng con trỏ có nhiều kiểu, mỗi phần tử của nó chứa đ−ợc 
các địa chỉ kiểu t−ơng ứng. 
Mảng con trỏ đ−ợc khai báo nh− sau: 
type *name[N]; 
Trong đó type là kiểu có thể là: int, float, double, char ..., name là tên của 
mảng, N là hằng số nguyên chỉ độ lớn của mảng. 
Khi gặp khai báo trên, máy sẽ cấp phát N khoảng nhớ liên tiếp cho N 
phần tử của mảng. Mỗi phần tử name[i] sẽ l−u trữ một địa chỉ theo kiểu đã 
khai bái. 
Ví dụ ch−ơng trình 5.4: Tìm tên trên mảng con trỏ. 
# include 
# include 
# include 
# define max 5 
void find(char *name) 
{ 
 char *list[max] = { "Lan", 
 "Nam", 
 "Hung", 
 "Tien", 
 "Van" }; 
 char ok = 0; 
 for (int i=0; i<max; i++) 
 if (strcmp(list[i], name) == 0) ok = 1; 
 if (ok == 1) 
 cout << "\nBan da co trong danh sach."; 
 else 
 cout << "\nBan chua co trong danh sach."; 
} 
void main() 
{ 
 char ten[7]; 
 clrscr(); 
 cout > ten; 
 find(ten); 
 getch(); 
} 
 50
Đại học Thái Nguyên-Tr−ờng ĐHSP. Khoa Toán-Tin 
 Nguyễn Mạnh Đức – Ngôn ngữ lập trình C++ 
5.3. Hàm có đối con trỏ 
Nếu đối của hàm là con trỏ kiểu int (float, double ...) thì tham số thực 
t−ơng ứng phải là địa chỉ của biến hoặc địa chỉ của phần tử mảng kiểu int 
(float, double ...). 
Ví dụ ch−ơng trình 5.5: Xây dựng ch−ơng trình hoán vị hai số bằng cách 
sử dụng đối con trỏ. 
# include 
# include 
void hoan_vi(int *x, int *y) 
{ 
 int z; 
 z = *x; 
 *x = *y; 
 *y = z; 
} 
void main() 
{ 
 int a =5 ,b = 10; 
 clrscr(); 
 hoan_vi(&a, &b); 
 cout << "\na = " << a ; 
 cout << "\nb = " << b; 
 getch(); 
} 
5.4. Con trỏ tới hàm 
Con trỏ hàm dùng để chứa địa chỉ của hàm. Muốn vậy ta phải thực hiện 
phép gán tên hàm cho con trỏ hàm. Để phép gán có nghĩa thì kiểu hàm và kiểu 
con trỏ phải t−ơng thích nhau. Sau phép gán, ta có thể dùng tên con trỏ thay 
cho tên hàm. 
Ví dụ ch−ơng trình 5.6: Xây dựng ch−ơng trình tìm số lớn hơn bằng cách 
sử dụng con trỏ hàm. 
# include 
double fmax(double x, double y) // ham tinh max 
 { return (x>y ? x:y); } 
// khai bao con tro ham 
double (*pf)(double, double) = fmax; 
void main() 
 { cout << "\nmax = " << pf(5.5, 99.75); } 
 51
Đại học Thái Nguyên-Tr−ờng ĐHSP. Khoa Toán-Tin 
 Nguyễn Mạnh Đức – Ngôn ngữ lập trình C++ 
5.5. Con trỏ void 
Con trỏ void là một dạng đặc biệt của khái niệm con trỏ, đó là con trỏ 
không có kiểu và nó có thể nhận bất kỳ kiểu địa chỉ nào. 
Con trỏ void th−ờng đ−ợc dùng để làm đối trong các hàm, để nhận bất kỳ 
kiểu địa chỉ nào từ tham số thật, vì thế trong thân hàm phải dùng phép quy hồi 
kiểu để chuyển sang dạng địa chỉ cần xử lý. 
Ví dụ ch−ơng trình 5.7: Xây dựng ch−ơng trình nhập các ma trận rồi tính 
tổng của chúng. 
# include 
# include 
# include 
const N = 50; 
void NHAP(char name, float *a, int n, int m); 
void INRA(float *a, int n, int m); 
void CONG(void *a, void *b, void *c, int n, int m); 
void FORMAT(int n); // qui dinh so chu so thap phan 
void main() 
{ 
 float x[N][N], y[N][N], z[N][N]; 
 int n = 3, m = 4; // so hang, cot thuc te cua MT 
 clrscr(); 
 NHAP('x', *x, n, m); 
 NHAP('y', *y, n, m); 
 CONG(*x, *y, *z, n, m); 
 clrscr(); 
 FORMAT(3); 
 cout << "\nMa tran X:"; 
 INRA(*x, n, m); 
 cout << "\nMa tran Y:"; 
 INRA(*y, n, m); 
 cout << "\nMa tran tong X + Y:"; 
 INRA(*z, n, m); 
 getch(); 
} 
void NHAP(char name, float *a, int n, int m) 
{ 
 cout << "\n"; 
 for (int i=0; i<n; i++) 
 for (int j=0; j<m; j++) 
 52
Đại học Thái Nguyên-Tr−ờng ĐHSP. Khoa Toán-Tin 
 Nguyễn Mạnh Đức – Ngôn ngữ lập trình C++ 
 53
 { 
 cout<<name<<"["<<i+1<<"]["<<j+1<<"] = "; 
 cin >> *(a+i*m+j); 
 } 
} 
void INRA(float *a, int n, int m) 
{ 
 for (int i=0; i<n; i++) 
 { 
 cout << "\n"; 
 for (int j=0; j<m; j++) 
 cout << setw(12) << *(a+i*m+j); 
 } 
} 
void CONG(void *a, void *b, void *c, int n, int m) 
{ 
 float *pa, *pb, *pc; 
 // quy hoi kieu 
 pa=(float*)a; pb=(float*)b; pc=(float*)c; 
 for (int i=0; i<n; i++) 
 for (int j=0; j<m; j++) 
 *(pc+i*m+j) = *(pa+i*m+j) + *(pb+i*m+j); 
} 
void FORMAT(int n) 
{ 
 cout << setprecision(n) << setiosflags(ios::fixed); 
 cout.setf(ios::showpoint); 
} 

File đính kèm:

  • pdfGiáo trình Ngôn ngữ lập trình C++ (Phần 1).pdf
Tài liệu liên quan