1. Trang chủ
  2. » Công Nghệ Thông Tin

Các mở rộng của C++ so với C

29 807 9
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Các Mở Rộng Của C++ So Với C
Tác giả Lờ Thị Mỹ Hạnh
Trường học Đại học Bỏch Khoa – Đại học Đà Nẵng
Chuyên ngành Công Nghệ Thông Tin
Thể loại bài viết
Thành phố Đà Nẵng
Định dạng
Số trang 29
Dung lượng 1,51 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Các mở rộng của C++ so với C

Trang 1

Lê Thị Mỹ Hạnh

Khoa CNTT Đại học Bách khoa – Đại học Đà Nẵng

Trang 2

 Các từ khóa mới này là :

asm catch class delete friend inline

new operator private protected public

template this throw try virtual

Trang 4

Khai bỏo biến

 Trong C tất cả các câu lệnh khai báo biến, mảng cục bộ

phải đặt tại đầu khối

 vị trí khai báo và vị trí sử dụng của biến có thể ở cách khá xa

nhau, điều này gây khó khăn trong việc kiểm soát ch-ơng trình

 C++ đã khắc phục nh-ợc điểm này bằng cách cho phép

các lệnh khai báo biến có thể đặt bất kỳ chỗ nào trong

ch-ơng trình tr-ớc khi các biến đ-ợc sử dụng

 Phạm vi hoạt động của các biến kiểu này là khối trong đó

biến đ-ợc khai báo

Trang 5

 PhÐp chuyÓn kiÓu nµy cã d¹ng nh- mét hµm sè chuyÓn

kiÓu ®ang ®-îc gäi C¸ch chuyÓn kiÓu nµy th-êng ®-îc sö dông trong thùc tÕ.

Trang 6

Vào ra trong C++

 Cú pháp: cout << biểu thức 1<< .<< biểu thức N;

Trong đó cout đ-ợc định nghĩa tr-ớc nh- một đối t-ợng biểu diễn cho thiết

bị xuất chuẩn của C++ là màn hình, cout đ-ợc sử dụng kết hợp với toán tử

chèn << để hiển thị giá trị các biểu thức 1, 2, , N ra màn hình.

 Cú pháp: cin >>biến 1>> >>biến N;

Toán tử cin đ-ợc định nghĩa tr-ớc nh- một đối t-ợng biểu diễn cho thiết bị vào chuẩn của C++ là bàn phím, cin đ-ợc sử dụng kết hợp với toán tử trích

>> để nhập dữ liệu từ bàn phím cho các biến 1, 2, , N.

 Để nhập một chuỗi không quá n ký tự và l-u vào mảng một chiều a (kiểu char) có thể dùng hàm cin.get nh- sau: cin.get(a,n);

 Toán tử nhập cin>> sẽ để lại ký tự chuyển dòng ’\n’ trong bộ đệm Ký tự này

có thể làm trôi ph-ơng thức cin.get Để khắc phục tình trạng trên cần dùng ph-ơng thức cin.ignore(1) để bỏ qua một ký tự chuyển dòng.

 Để sử dụng các loại toán tử và ph-ơng thức nói trên cần khai báo tập tin dẫn h-ớng iostream.h

Trang 7

 Hàm này cần đặt trong toán tử xuất và nó chỉ có hiệu lực cho một giá trị đ-ợc

in gần nhất Các giá trị in ra tiếp theo sẽ có độ rộng tối thiểu mặc định là 0, nh- vậy câu lệnh:

cout<<setw(6)<<“Khoa”<<“CNTT”

sẽ in ra chuỗi “ KhoaCNTT”.

Trang 8

Toán tử định phạm vi (::)

 Toán tử định phạm vi (scope resolution operator) ký hiệu là ::,

nó được dùng truy xuất một phần tử bị che bởi phạm vi hiện thời

cout<< "Bien X ben trong = "<<X<<"\n";

cout<< "Bien X ben ngoai = "<<::X<<"\n";

return 0;

}

Trang 9

Cấp phỏt và giải phúng bộ nhớ

 Trong C để cấp phát bộ nhớ dùng: malloc(), calloc() và để giải phóng bộ nhớ đ-ợc cấp phát dùng hàm free().

 C++ đ-a thêm một cách thức mới để thực hiện việc cấp

phát và giải phóng bộ nhớ bằng cách dùng hai toán tử new

và delete.

Trang 10

Cấp phỏt và giải phúng bộ nhớ

Toán tử new để cấp phát bộ nhớ

new Tên kiểu ; hoặc new Tên kiểu(Giá trị khởi tạo);

 Trong đó Tên kiểu là kiểu dữ liệu của biến con trỏ, nó có thể là: các kiểu dữ liệu chuẩn nh- int, float, double, char, hoặc các kiểu do ng-ời lập trình định nghĩa nh- mảng, cấu trúc, lớp,

 Để cấp phát bộ nhớ cho mảng một chiều, dùng cú pháp nh- sau:

Biến con trỏ = new kiểu[n];

 Trong đó n là số nguyên d-ơng xác định số phần tử của mảng.

Ví dụ: float *p = new float; //cấp phát bộ nhớ cho biến con trỏ p có kiểu int

int *a = new int[100]; //cấp phát bộ nhớ để l-u trữ mảng một chiều a gồm 100 phần tử

 Khi sử dụng toán tử new để cấp phát bộ nhớ, nếu không đủ bộ nhớ để cấp phát, new sẽ trả lại giá trị NULL cho con trỏ Đoạn ch-ơng trình sau minh họa cách kiểm tra lỗi cấp phát bộ nhớ:

exit(0);

}

Trang 11

Cấp phỏt và giải phúng bộ nhớ

Toán tử delete để giải phóng bộ nhớ

 Toán tử delete thay cho hàm free() của C, nó có cú pháp nh-

Trang 12

Hàm inline

 Việc tổ chức ch-ơng trình thành các hàm có -u điểm ch-ơng trình

đ-ợc chia thành các đơn vị độc lập, điều này giảm đ-ợc kích th-ớc ch-ơng trình, vì mỗi đoạn ch-ong trình thực hiện nhiệm vụ của hàm

đ-ợc thay bằng lời gọi hàm

 Tuy nhiên hàm cũng có nh-ợc điểm là làm là chậm tốc độ thực hiện ch-ơng trình vì phải thực hiện một số thao tác có tính thủ tục mỗi khi gọi hàm nh-: cấp phát vùng nhớ cho các đối số và biến cục bộ,

truyền dữ liệu của các tham số cho các đối, giải phóng vùng nhớ

tr-ớc khi thoát khỏi hàm.

 C++ cho khả năng khắc phục đ-ợc nh-ợc điểm nói trên bằng cách dùng hàm nội tuyến Để biến một hàm thành hàm nội tuyến ta viết

thêm từ khóa inline vào tr-ớc khai báo nguyên mẫu hàm

Trang 13

int s ;s=f(5,6);

cout<<s;

getch();

}

Trang 14

Biến tham chiếu

 Trong C có 2 loại biến là:

 Biến giá trị dùng để chứa dữ liệu (nguyên, thực, ký tự, ) và biến con trỏdùng để chứa địa chỉ

 Các biến này đều đ-ợc cung cấp bộ nhớ và có địa chỉ

 C++ cho phép sử dụng loại biến thứ ba là biến tham chiếu

Biến tham chiếu là một tên khác (bí danh) cho biến đã định nghĩa tr-ớc

đó

 Cú pháp khai báo biến tham chiếu nh- sau:

Kiểu &Biến tham chiếu = BiếnHằng;

 Biến tham chiếu có đặc điểm là nó đ-ợc dùng làm bí danh cho một biến (kiểu giá trị) nào đó và sử dụng vùng nhớ của biến này

Trang 15

Biến tham chiếu

Ví dụ: Với câu lệnh: int a, &tong=a; thì tong là bí danh của biến a và biến tong dùng

chung vùng nhớ của biến a Lúc này, trong mọi câu lệnh, viết a hay viết tong đều có ý

nghĩa nh- nhau, vì đều truy nhập đến cùng một vùng nhớ Mọi sự thay đổi đối với biến

tong đều ảnh h-ởng đối với biến a và ng-ợc lại.

Ví dụ: int a, &tong =a;

tong =1; //a=1 cout<< tong; //in ra số 1 tong++; //a=2 ++a; //a=3 cout<<tong; //in ra số 3

Chú ý:

 Trong khai báo biến tham chiếu phải chỉ rõ tham chiếu đến biến nào

 Biến tham chiếu có thể tham chiếu đến một phần tử mảng, nh-ng không cho phép khai báo mảng tham chiếu.

 Biến tham chiếu có thể tham chiếu đến một hằng Khi đó nó sử dụng vùng nhớ của hằng và có thể làm thay đổi giá trị chứa trong vùng nhớ này.

 Biến tham chiếu th-ờng đ-ợc sử dụng làm đối của hàm để cho phép hàm truy nhập đến các tham biến trong lời gọi hàm

Trang 16

Hằng tham chiếu

 Cú pháp khai báo hằng tham chiếu nh- sau:

const Kiểu dữ liệu &Hằng = Biến/Hằng;

const int &m = n;

const int &p = 123;

 Hằng tham chiếu có thể tham chiếu đến một biến hoặc một hằng

 Biến tham chiếu và hằng tham chiếu khác nhau ở chỗ: không cho phép dùng hằng tham chiếu để làm thay đổi giá trị của vùng nhớ mà nó tham chiếu.

Ví dụ: int y=12, z;

const int &p = y //Hằng tham chiếu p tham chiếu đến biến y

p = p + 1; //Sai, trình biên dịch sẽ thông báo lỗi

 Hằng tham chiếu cho phép sử dụng giá trị chứa trong một vùng nhớ, nh-ng không cho phép thay đổi giá trị này.

 Hằng tham chiếu th-ờng đ-ợc sử dụng làm đối số của hàm để cho phép sử dụng giá trị của các tham số trong lời gọi hàm, nh-ng tránh làm thay đổi giá trị tham số.

Trang 17

Truyền tham số cho hàm theo tham chiếu

 Trong C chỉ có một cách truyền dữ liệu cho hàm là truyền theo theo giá trị

 Ch-ơng trình sẽ tạo ra các bản sao của các tham số thực sự trong lời gọi hàm và sẽ thao tác trên các bản sao này chứ không xử lý trực tiếp với các tham số thực sự

 Cơ chế này rất tốt nếu khi thực hiện hàm trong ch-ơng trình

không cần làm thay đổi giá trị của biến gốc

 Tuy nhiên, nhiều khi ta lại muốn những tham số đó thay đổi khi thực hiện hàm trong ch-ơng trình

 C++ cung cấp thêm cách truyền dữ liệu cho hàm theo tham

chiếu bằng cách dùng đối là tham chiếu

 Cách làm này có -u diểm là không cần tạo ra các bản sao của các tham số, do dó tiết kiệm bộ nhớ và thời gian chạy máy

 Mặt khác, hàm này sẽ thao tác trực tiếp trên vùng nhớ của các tham số, do đó dễ dàng thay đổi giá trị các tham số khi cần.

Trang 18

Truyền tham số theo tham chiếu – Ví dụ

void Hoanvi(double &x,double &y)

Trang 19

Trong tr-ờng hợp này biểu thức đ-ợc trả lại trong câu lệnh return phải là tên của một

biến xác định từ bên ngoài hàm, bởi vì khi đó mới có thể sử dụng đ-ợc giá trị của hàm

 Khi ta trả về một tham chiếu đến một biến cục bộ khai báo bên trong hàm, biến cục

bộ này sẽ bị mất đi khi kết thúc thực hiện hàm Do vậy tham chiếu của hàm sẽ không còn ý nghĩa nữa Vì vậy, nếu hàm trả về là tham chiếu đến biến cục bộ thì biến cục

bộ này phải khai báo static.

Trang 20

Hàm trả về là một tham chiếu

 Khi giá trị trả về của hàm là tham chiếu, ta có thể gặp các câu lệnh gán hơi khác th-ờng, trong đó vế trái là một lời gọi hàm chứ không phải là tên của một biến

Trang 21

Hàm với đối số mặc đinh

 Một trong các đặc tính nổi bật nhất của C++ là khả năng định nghĩa các giá trị tham số mặc định cho các hàm

 Bình thường khi gọi một hàm, chúng ta cần gởi một giá trị cho mỗi tham số

đã được định nghĩa trong hàm đó, chẳng hạn chúng ta có đoạn chương trình sau:

void MyDelay(long Loops); //prototype

 Mỗi khi hàm MyDelay() được gọi chúng ta phải gởi cho nó một giá trị cho tham số Loops

 Tuy nhiên, trong nhiều trường hợp chúng ta có thể nhận thấy rằng chúng ta luôn luôn gọi hàm MyDelay() với cùng một giá trị Loops nào đó Muốn vậy chúng ta sẽ dùng giá trị mặc định cho tham số Loops, giả sử chúng ta muốn giá trị mặc định cho tham số Loops là 1000

 Khi đó đoạn mã trên được viết lại như sau :

void MyDelay(long Loops = 1000); //prototype

 Mỗi khi gọi hàm MyDelay() mà không gởi một tham số tương ứng thì trình biên dịch sẽ tự động gán cho tham số Loops giá trị 1000

MyDelay(); // Loops có giá trị là 1000

MyDelay(5000); // Loops có giá trị là 5000

Trang 22

Hàm với đối số mặc định

 Quy tắc xây dựng hàm với đối số mặc định nh- sau:

 Các đối có giá trị mặc định cần là các đối số cuối cùng tính từ trái qua phải

int MyFunc(int a=1, int b, int c=3, int d=4); //prototype sai!!!

int MyFunc(int a, int b=2, int c=3, int d=4); //prototype đỳng

 Nếu ch-ơng trình sử dụng khai báo nguyên mẫu hàm thì các đối số mặc định cần đ-ợc khởi gán trong nguyên mẫu hàm, không đ-ợc khởi gán khởi gán lại cho các đối mặc định trong dòng đầu của định nghĩa hàm

 Khi xây dựng hàm, nếu không khai báo nguyên mẫu, thì các đối mặc định

đ-ợc khởi gán trong dòng đầu của định nghĩa hàm

 Đối với các hàm có đối số mặc định thì lời gọi hàm cần viết theo quy định: Các tham số vắng mặt trong lời gọi hàm t-ơng ứng với các đối số mặc định cuối cùng (tính từ trái sang phải),

MyFunc(); // Lỗi do tham số a khụng cú giỏ trị mặc định

MyFunc(1);// OK, cỏc tham số b, c và d lấy giỏ trị mặc định

MyFunc(5, 7); // OK, cỏc tham số c và d lấy giỏ trị mặc định

MyFunc(5, 7, , 8); // Lỗi do cỏc tham số bị bỏ phải liờn tiếp nhau

Trang 23

Đa năng hóa (Overloading)

 Với ngôn ngữ C++, chúng ta có thể đa năng hóa các hàm

 Có hai hình thức đa năng hóa:

 Đa năng hóa hàm

 Đa năng hóa toán tử

Trang 24

Đa năng hóa hàm(Function Overloading)

 Trong ngôn ngữ C cũng như mọi ngôn ngữ máy tính khác, mỗi hàm đều

phải có một tên phân biệt

 Như trong ngôn ngữ C, có rất nhiều hàm trả về trị tuyệt đối của một tham số là

số, vì cần thiết phải có tên phân biệt nên C phải có hàm riêng cho mỗi kiểu dữ liệu số,

 do vậy có tới ba hàm khác nhau để trả về trị tuyệt đối của một tham số :

int abs(int i);

long labs(long l);

double fabs(double d);

 Tất cả các hàm này đều cùng thực hiện một chứa năng nên chúng ta thấy điều

này nghịch lý khi phải có ba tên khác nhau

 C++ giải quyết điều này bằng cách cho phép chúng ta tạo ra các hàm khác

nhau có cùng một tên Đây chính là đa năng hóa hàm

 Như vậy, trong C++ chúng ta có thể định nghĩa lại các hàm trả về trị tuyệt

đối để thay thế các hàm trên như sau :

int Myabs(int i);

long Myabs(long l);

double Myabs(double d);

Trang 25

Đa năng hóa hàm(Function Overloading)

 Trình biên dịch dựa vào sự khác nhau về số các tham số, kiểu của các tham số để có thể xác định chính xác phiên bản cài

đặt nào của hàm MyAbs() thích hợp với một lệnh gọi hàm

được cho,

MyAbs(-7); //Gọi hàm int MyAbs(int)

MyAbs(-7l); //Gọi hàm long MyAbs(long)

MyAbs(-7.5); //Gọi hàm double MyAbs(double)

 Quá trình tìm hàm đa năng hóa :

 nếu tìm thấy một phiên bản định nghĩa nào đó của một hàm được

đa năng hóa mà có kiểu dữ liệu các tham số của nó trùng với

kiểu các tham số đã gởi tới trong lệnh gọi hàm thì phiên bản hàm

đó sẽ được gọi

 Nếu không trình biên dịch C++ sẽ gọi đến phiên bản nào cho

phép chuyển kiểu dễ dàng nhất

MyAbs(„c‟); //Gọi int MyAbs(int)

MyAbs(2.34f); //Gọi double MyAbs(double)

Bất kỳ hai hàm nào trong tập các hàm đã đa năng phải có các tham số khác nhau

Trang 26

Đa năng hóa toán tử (Operators overloading)

 Trong C, khi tạo ra một kiểu dữ liệu mới, để thực hiện các thao tác liên quan đến kiểu dữ liệu đó thường thông qua các hàm

Complex SetComplex(double R,double I);

Complex AddComplex(Complex C1,Complex C2);

Complex SubComplex(Complex C1,Complex C2);

=> C3 = AddComplex(C1,C2); //Hơi bất tiện !!!

C4 = SubComplex(C1,C2);

 Điều này trở nên không thoải mái vì thực chất thao tác cộng và trừ là các toán tử chứ không phải là hàm

Trang 27

Đa năng hóa toán tử (Operators overloading)

 Để khắc phục yếu điểm này, trong C++ cho phép chúng ta có thể

định nghĩa lại chức năng của các toán tử đã có sẵn một cách tiện lợi

và tự nhiên hơn rất nhiều

 Điều này gọi là đa năng hóa toán tử

 Ví dụ:

Complex operator + (Complex C1,Complex C2);

Complex operator - (Complex C1,Complex C2);

=> C3 = C1 + C2;

C4 = C1 - C2;

 Như vậy trong C++, các phép toán trên các giá trị kiểu số phức được thực hiện bằng các toán tử toán học chuẩn chứ không phải bằng các tên hàm như trong C

 Chẳng hạn chúng ta có lệnh sau:

C4 = AddComplex(C3, SubComplex(C1,C2));

thì ở trong C++, chúng ta có lệnh tương ứng như sau:

C4 = C3 + C1 - C2;

Trang 28

Đa năng hóa toán tử (Operators overloading)

operator_symbol: Ký hiệu của toán tử

parameters: Các tham số (nếu có).

 Các toán tử được đa năng hóa sẽ được lựa chọn bởi trình biên dịch:

 khi gặp một toán tử làm việc trên các kiểu không phải là kiểu

có sẵn, trình biên dịch sẽ tìm một hàm định nghĩa của toán tử nào đó có các tham số đối sánh với các toán hạng để dùng.

Trang 29

Đa năng hóa toán tử (Operators overloading)

 Các giới hạn của đa năng hóa toán tử:

 Chúng ta không thể định nghĩa các toán tử mới

 Hầu hết các toán tử của C++ đều có thể được đa năng hóa

 Các toán tử sau không được đa năng hóa là :

:: Toán tử định phạm vi

.* Truy cập đến con trỏ là trường của struct hay thành viên của class

. Truy cập đến trường của struct hay thành viên của class

?: Toán tử điều kiện

sizeof

 và chúng ta cũng không thể đa năng hóa bất kỳ ký hiệu tiền xử lý nào

 Chúng ta không thể thay đổi thứ tự ưu tiên của một toán tử hay không thể thay đổi số các toán hạng của nó

 Chúng ta không thể thay đổi ý nghĩa của các toán tử khi áp dụng cho các kiểu có sẵn

 Đa năng hóa các toán tử không thể có các tham số có giá trị mặc định

 Các toán tử có thể đa năng hoá:

+ - * / % ^ ! = < > += -=

^= &= |= << >> <<= <= >= && || ++

() [] new delete & | ~ *= /= %= >>= == != , -> ->*

Ngày đăng: 17/08/2012, 08:39

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w