CÁC MỞ RỘNG CỦA C++ - Pdf 63

Giáo trình môn Lập trình hướng đối tượng Trang
Biên soạn: Lê Thị Mỹ Hạnh
12
CHƯƠNG 2
CÁC MỞ RỘNG CỦA C++
I. LỊCH SỬ CỦA C++
Vào những năm đầu thập niên 1980, người dùng biết C++ với tên gọi "C with Classes" được mô tả trong
hai bài báo của Bjarne Stroustrup (thuộc AT&T Bell Laboratories) với nhan đề "Classes: An Abstract Data
Type Facility for the C Language" và "Adding Classes to C : AnExercise in Language Evolution". Trong
công trình này, tác giả đã đề xuất khái niệm lớp, bổ sung việc kiểm tra kiểu tham số của hàm, các chuyển đổi
kiểu và một số mở rộng khác vào ngôn ngữ C. Bjarne Stroustrup nghiên cứu mở rộng ngôn ngữ C nhằm đạt
đến một ngôn ngữ mô phỏng (simulation language) với những tính năng hướ
ng đối tượng.
Trong năm 1983, 1984, ngôn ngữ "C with Classes" được thiết kế lại, mở rộng hơn rồi một trình biên
dịch ra đời. Và chính từ đó, xuất hiện tên gọi "C++". Bjarne Stroustrup mô tả ngôn ngữ C++ lần đầu tiên
trong bài báo có nhan đề "Data Abstraction in C". Sau một vài hiệu chỉnh C++ được công bố rộng rãi trong
quyển "The C++ Programming Language" của Bjarne Stroustrup xuất hiện đánh dấu sự hiện diện thực sự
của C++, người lập tình chuyên nghiệp từ đ
ây đã có một ngôn ngữ đủ mạnh cho các dữ án thực tiễn của
mình.
Về thực chất C++ giống như C nhưng bổ sung thêm một số mở rộng quan trọng, đặc biệt là ý tưởng về
đối tượng, lập trình định hướng đối tượng.Thật ra các ý tưởng về cấu trúc trong C++ đã xuất phát vào các
năm 1970 từ Simula 70 và Algol 68. Các ngôn ngữ này đã đưa ra các khái niệm về lớp và đơn thể. Ada là
m
ột ngôn ngữ phát triển từ đó, nhưng C++ đã khẳng định vai trò thực sự của mình.
II. CÁC MỞ RỘNG CỦA C++
II.1. Các từ khóa mới của C++
Để bổ sung các tính năng mới vào C, một số từ khóa (keyword) mới đã được đưa vào C++ ngoài các từ
khóa có trong C. Các chương trình bằng C nào sử dụng các tên trùng với các từ khóa cần phải thay đổi trước
khi chương trình được dịch lại bằng C++. Các từ khóa mới này là :
asm catch class delete friend inline

được dùng cho các chú thích một dòng.
II.3. Dòng nhập/xuất chuẩn
Trong chương trình C, chúng ta thường sử dụng các hàm nhập/xuất dữ liệu là printf() và scanf(). Trong
C++ chúng ta có thể dùng dòng nhập/xuất chuẩn (standard input/output stream) để nhập/xuất dữ liệu thông
qua hai biến đối tượng của dòng (stream object) là cout và cin.
Ví dụ 2.2:
Chương trình nhập vào hai số. Tính tổng và hiệu của hai số vừa nhập.
//Chuong trinh 2.2
#include <iostream.h>
int main()
{
int X, Y;
cout<< "Nhap vao mot so X:";
cin>>X;
cout<< "Nhap vao mot so Y:";
cin>>Y;
cout<<"Tong cua chung:"<<X+Y<<"\n";
cout<<"Hieu cua chung:"<<X-Y<<"\n";
return 0;
}
Để thực hiện dòng xuất chúng ta sử dụng biến cout (console output) kết hợp với toán tử chèn (insertion
operator) << như ở các dòng 5, 7, 9 và 10. Còn dòng nhập chúng ta sử dụng biến cin (console input) kết hợp
với toán tử trích (extraction operator) >> như ở các dòng 6 và 8. Khi sử dụng cout hay cin, chúng ta phải kéo
file iostream.h như dòng 1. Chúng ta sẽ tìm hiểu kỹ về dòng nhập/xuất ở chương 8. Chúng ta chạy ví dụ 2.2
,
kết quả ở hình 2.2.

Hình 2.2: Kết quả của ví dụ 2.2
Giáo trình môn Lập trình hướng đối tượng Trang
Biên soạn: Lê Thị Mỹ Hạnh

Ví dụ 2.4:
Chương trình mô phỏng một máy tính đơn giản
1: #include <iostream.h>
2: int main()
3: {
4: int X;
Giáo trình môn Lập trình hướng đối tượng Trang
Biên soạn: Lê Thị Mỹ Hạnh
15
5: cout<< "Nhap vao so thu nhat:";
6: cin>>X;
7: int Y;
8: cout<< "Nhap vao so thu hai:";
9: cin>>Y;
10: char Op;
11: cout<<"Nhap vao toan tu (+-*/):";
12: cin>>Op;
13: switch(Op)
14: {
15: case ‘+’:
16: cout<<"Ket qua:"<<X+Y<<"\n";
17: break;
18: case ‘-’:
19: cout<<"Ket qua:"<<X-Y<<"\n";
20: break;
21: case ‘*’:
22: cout<<"Ket qua:"<<long(X)*Y<<"\n";
23: break;
24: case ‘/’:
25: if (Y)

Phạm vi của các biến const giữa ANSI C và C++ khác nhau. Trong ANSI C, các biến const được khai
báo ở bên ngoài mọi hàm thì chúng có phạm vi toàn cục, điều này nghĩa là chúng có thể nhìn thấy cả ở bên
ngoài file mà chúng được định nghĩa, trừ khi chúng được khai báo là static. Nhưng trong C++, các biến
const được hiểu mặc định là static.
II.7. Về struct, union và enum
Trong C++, các struct và union thực sự các các kiểu class. Tuy nhiên có sự thay đổi đối với C++. Đó là
tên của struct và union được xem luôn là tên kiểu giống như khai báo bằng lệnh typedef vậy.
Trong C, chúng ta có thể có đoạn mã sau :
struct Complex
{
float Real;
float Imaginary;
};
…………………..
struct Complex C;
Trong C++, vấn đề trở nên đơn giản hơn:
struct Complex
{
float Real;
float Imaginary;
};
…………………..
Complex C;
Quy định này cũng áp dụng cho cả union và enum. Tuy nhiên để tương thích với C, C++ vẫn chấp nhận
cú pháp cũ.
Một kiểu union đặc biệt được thêm vào C++ gọi là union nặc danh (anonymous union). Nó chỉ khai báo
một loạt các trường(field) dùng chung một vùng địa chỉ bộ nhớ. Một union nặc danh không có tên tag, các
trường có thể được truy xuất trực tiếp bằng tên của chúng. Chẳng hạn như đoạn mã sau:
union
{

khai báo lớp chủ của các phương thức đang được định nghĩa đó. Toán tử định phạm vi còn có thể được dùng
để phân biệt các thành phần trùng tên của các lớp cơ sở khác nhau.
II.9. Toán tử new và delete
Trong các chương trình C, tất cả các cấp phát động bộ nhớ đều được xử lý thông qua các hàm thư viện
như malloc(), calloc() và free(). C++ định nghĩa một phương thức mới để thực hiện việc cấp phát động bộ
nhớ bằng cách dùng hai toán tử new và delete. Sử dụng hai toán tử này sẽ linh hoạt hơn rất nhiều so với các
hàm thư viện của C.
Đoạn chươ
ng trình sau dùng để cấp phát vùng
nhớ động theo lối cổ điển của C.
int *P;
P = malloc(sizeof(int));
if (P==NULL)
printf("Khong con du bo nho de cap phat\n");
else
{
*P = 290;
printf("%d\n", *P);
free(P);
}
Trong C++, chúng ta có thể viết lại đoạn chương
trình trên như sau:
int *P;
P = new int;
if (P==NULL)
cout<<"Khong con du bo nho de cap phat\n";
else
{
*P = 290;
cout<<*P<<"\n";

Để cấp phát một mảng, chúng ta làm như sau :
int *P;
P = new int[10]; //Cấp phát mảng 10 số nguyên
if (P!=NULL)
{
for(int I = 0;I<10;++)
P[I]= I;
for(I = 0;I<10;++)
cout<<P[I]<<"\n";
delete []P;
}else cout<<"Khong con du bo nho de cap phat\n";
Chú ý
: Đối với việc cấp phát mảng chúng ta không thể vừa cấp phát vừa khởi động giá trị cho chúng,
chẳng hạn đoạn chương trình sau là sai :
int *P;
P = new (int[10])(3); //Sai !!!
Ví dụ 2.6:
Chương trình tạo một mảng động, khởi động mảng này với các giá trị ngẫu nhiên và sắp xếp
chúng.
1: #include <iostream.h>
2: #include <time.h>
3: #include <stdlib.h>
4: int main()
5: {
6: int N;
7: cout<<"Nhap vao so phan tu cua mang:";
8: cin>>N;
9: int *P=new int[N];
10: if (P==NULL)
11: {

Chúng ta có thể xem mảng hai chiều như mảng một chiều như hình 2.8

Hình 2.8: Mảng hai chiều có thể xem như mảng một chiều.
Gọi X là mảng hai chiều có kích thước m dòng và n cột.
A là mảng một chiều tương ứng.
Nếu X[i][j] chính là A[k] thì k = i*n + j
Chúng ta có chương trình như sau :
1: #include <iostream.h>
2: #include <conio.h>
3: //prototype
4: void AddMatrix(int * A,int *B,int*C,int M,int N);
5: int AllocMatrix(int **A,int M,int N);
6: void FreeMatrix(int *A);
7: void InputMatrix(int *A,int M,int N,char Symbol);
8: void DisplayMatrix(int *A,int M,int N);
9:
10: int main()
11: {
12: int M,N;
13: int *A = NULL,*B = NULL,*C = NULL;
14:
15: clrscr();
16: cout<<"Nhap so dong cua ma tran:";
17: cin>>M;
18: cout<<"Nhap so cot cua ma tran:";
19: cin>>N;
20: //Cấp phát vùng nhớ cho ma trận A
21: if (!AllocMatrix(&A,M,N))
22: { //endl: Xuất ra kí tự xuống dòng (‘\n’)
23: cout<<"Khong con du bo nho!"<<endl;

51: cout<<"Tong hai ma tran"<<endl;
52: DisplayMatrix(C,M,N);
53: FreeMatrix(A);//Giải phóng vùng nhớ A
54: FreeMatrix(B);//Giải phóng vùng nhớ B
55: FreeMatrix(C);//Giải phóng vùng nhớ C
56: return 0;
57: }
68: //Cộng hai ma trận
69: void AddMatrix(int *A,int *B,int*C,int M,int N)
70: {
71: for(int I=0;I<M*N;++I)
72: C[I] = A[I] + B[I];
73: }
74: //Cấp phát vùng nhớ cho ma trận
75: int AllocMatrix(int **A,int M,int N)
76: {
77: *A = new int [M*N];
78: if (*A == NULL)
79: return 0;
80: return 1;
81: }
82: //Giải phóng vùng nhớ
83: void FreeMatrix(int *A)
84: {
85: if (A!=NULL)
86: delete [] A;
87: }
88: //Nhập các giá trị của ma trận
89: void InputMatrix(int *A,int M,int N,char Symbol)
90: {

for(int I=0;I<M;++I)
{
A[I]=Tmp;
Tmp+=N;
}
//Thao tác trên mảng hai chiều A
…………………..
delete [] *A;
delete [] A;
Toán tử new còn có một thuận lợi khác, đó là tất cả các lỗi cấp phát động đều có thể bắt được bằng một
hàm xử lý lỗi do người dùng tự định nghĩa. C++ có định nghĩa một con trỏ (pointer) trỏ đến hàm đặc biệt.


Nhờ tải bản gốc

Tài liệu, ebook tham khảo khác

Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status