Bài 1 : Cấu Trúc Của Một Chương Trình C++



tải về 448.29 Kb.
trang14/14
Chuyển đổi dữ liệu02.09.2016
Kích448.29 Kb.
#31125
1   ...   6   7   8   9   10   11   12   13   14

Bộ nhớ động trong ANSI-C


Toán tử newdelete là độc quyền C++ và chúng không có trong ngôn ngữ C. Trong ngôn ngữ C, để có thể sử dụng bộ nhớ động chúng ta phải sử dụng thư viện stdlib.h. Chúng ta sẽ xem xét cách này vì nó cũng hợp lệ trong C++ và nó vẫn còn được sử dụng trong một số chương trình.

Hàm malloc
Đây là một hàm tổng quát để cấp phát bộ nhớ động cho con trỏ. Cấu trúc của nó như sau:

void * malloc (size_t nbytes);

trong đó nbytes là số byte chúng ta muốn gán cho con trỏ. Hàm này trả về một con trỏ kiểu void*, vì vậy chúng ta phải chuyển đổi kiểu sang kiểu của con trỏ đích, ví dụ:

char * ronny;
ronny = (char *) malloc (10);

Đoạn mã này cấp phát cho con trỏ ronny một khối nhớ 10 byte. Khi chúng ta muốn cấp phát một khối dữ liệu có kiểu khác char (lớn hơn 1 byte) chúng ta phải nhân số phần tử mong muốn với kích thước của chúng. Thật may mắn là chúng ta có toán tử sizeof, toán tử này trả về kích thước của một kiểu dữ liệu cụ thể.

int * bobby;
bobby = (int *) malloc (5 * sizeof(int));

Đoạn mã này cấp phát cho bobby một khối nhớ gồm 5 số nguyên kiểu int, kích cỡ của kiểu dữ liệu này có thể bằng 2, 4 hay hơn tùy thuộc vào hệ thống mà chương trình được dịch.



Hàm calloc.
calloc hoạt động rất giống với malloc, sự khác nhau chủ yếu là khai báo mẫu của nó:

void * calloc (size_t nelements, size_t size);

nó sử dụng hai tham số thay vì một. Hai tham số này được nhân với nhau để có được kích thước tổng cộng của khối nhớ cần cấp phát. Thông thường tham số đầu tiên (nelements) là số phần tử và tham số thức hai (size) là kích thước của mỗi phần tử. Ví dụ, chúng ta có thể định nghĩa bobby với calloc như sau:

int * bobby;
bobby = (int *) calloc (5, sizeof(int));

Một điểm khác nhau nữa giữa malloccalloccalloc khởi tạo tất cả các phần tử của nó về 0.



Hàm realloc.
Nó thay đổi kích thước của khối nhớ đã được cấp phát cho một con trỏ.

void * realloc (void * pointer, size_t size);

tham số pointer nhận vào một con trỏ đã được cấp phát bộ nhớ hay một con trỏ null, và size chỉ định kích thước của khối nhớ mới. Hàm này sẽ cấp phát size byte bộ nhớ cho con trỏ. Nó có thể phải thay đổi vị vị trí của khối nhớ để có thể đủ chỗ cho kích thước mới của khối nhớ, trong trường hợp này nội dung hiện thời của khối nhớ được copy tới vị trí mới để đảm bảo dữ liệu không bị mất. Con trỏ mới trỏ tới khối nhớ được hàm trả về. Nếu không thể thay đổi kích thước của khối nhớ thì hàm sẽ trả về một con trỏ null nhưng tham số pointer và nội dung của nó sẽ không bị thay đổi.



Hàm free.
Hàm này giải phóng một khối nhớ động đã được cấp phát bởi malloc, calloc hoặc realloc.

void free (void * pointer);

Hàm này chỉ được dùng để giải phóng bộ nhớ được cấp phát bởi các hàm malloc, calloc and realloc.

Bài 11 : Các Cấu Trúc

Các cấu trúc dữ liệu.


Một cấu trúc dữ liệu là một tập hợp của những kiểu dữ liệu khác nhau được gộp lại với một cái tên duy nhất. Dạng thức của nó như sau:

struct model_name {

type1 element1;

type2 element2;

type3 element3;

.

.

} object_name;

trong đó model_name là tên của mẫu kiểu dữ liệu và tham số tùy chọn object_name một tên hợp lệ cho đối tượng. Bên trong cặp ngoặc nhọn là tên các phần tử của cấu trúc và kiểu của chúng.

Nếu định nghĩa của cấu trúc bao gồm tham số model_name (tuỳ chọn), tham số này trở thành một tên kiểu hợp lệ tương đương với cấu trúc. Ví dụ:

struct products {

char name [30];

float price;

} ;
products apple;

products orange, melon;

Chúng ta đã định nghĩa cấu trúc products với hai trường: nameprice, mỗi trường có một kiểu khác nhau. Chúng ta cũng đã sử dụng tên của kiểu cấu trúc (products) để khai báo ba đối tượng có kiểu đó : apple, orangemelon.

Sau khi được khai báo, products trở thành một tên kiểu hợp lệ giống các kiểu cơ bản như int, char hay short.

Trường tuỳ chọn object_name có thể nằm ở cuối của phần khai báo cấu trúc dùng để khai báo trực tiếp đối tượng có kiểu cấu trúc. Ví dụ, để khai báo các đối tượng apple, orangemelon như đã làm ở phần trước chúng ta cũng có thể làm theo cách sau:

struct products {

char name [30];

float price;

} apple, orange, melon;

Hơn nữa, trong trường hợp này tham số model_name trở thành tuỳ chọn. Mặc dù nếu model_name không được sử dụng thì chúng ta sẽ không thể khai báo thêm các đối tượng có kiểu mẫu này.

Một điều quan trọng là cần phân biệt rõ ràng đâu là kiểu mẫu cấu trúc, đâu là đối tượng cấu trúc. Nếu dùng các thuật ngữ chúng ta đã sử dụng với các biến, kiểu mẫu là tên kiểu dữ liệu còn đối tượng là các biến.

Sau khi đã khai báo ba đối tượng có kiểu là một mẫu cấu trúc xác định (apple, orange and melon) chúng ta có thể thao tác với các trường tạo nên chúng. Để làm việc này chúng ta sử dụng một dấu chấm (.) chèn ở giữa tên đối tượng và tên trường. Ví dụ, chúng ta có thể thao tác với bất kì phần tử nào của cấu trúc như là đối với các biến chuẩn :

apple.name
apple.price
orange.name
orange.price
melon.name
melon.price

mỗi trường có kiểu dữ liệu tương ứng: apple.name, orange.namemelon.name có kiểu char[30], và apple.price, orange.pricemelon.price có kiểu float.

Chúng ta tạm biệt apples, oranges và melons để đến với một ví dụ về các bộ phim:


// example about structures

#include

#include

#include


struct movies_t {

char title [50];

int year;

} mine, yours;


void printmovie (movies_t movie);
int main ()

{

char buffer [50];


strcpy (mine.title, "2001 A Space Odyssey");

mine.year = 1968;


cout << "Enter title: ";

cin.getline (yours.title,50);

cout << "Enter year: ";

cin.getline (buffer,50);

yours.year = atoi (buffer);
cout << "My favourite movie is:\n ";

printmovie (mine);

cout << "And yours:\n ";

printmovie (yours);

return 0;

}
void printmovie (movies_t movie)

{

cout << movie.title;



cout << " (" << movie.year << ")\n";

}


Enter title: Alien
Enter year: 1979
 
My favourite movie is:
 2001 A Space Odyssey (1968)
And yours:
 Alien (1979)

Ví dụ này cho chúng ta thấy cách sử dụng các phần tử của một cấu trúc và bản thân cấu trúc như là các biến thông thường. Ví dụ, yours.year là một biến hợp lệ có kiểu int cũng như mine.title là một mảng hợp lệ với 50 phần tử kiểu chars.

Chú ý rằng cả mine and yours đều được coi là các biến hợp lệ kiểu movie_t khi được truyền cho hàm printmovie().Hơn nữa một lợi thế quan trọng của cấu trúc là chúng ta có thể xét các phần tử của chúng một cách riêng biệt hoặc toàn bộ cấu trúc như là một khối.

Các cấu trúc được sử dụng rất nhiều để xây dựng cơ sở dữ liệu đặc biệt nếu chúng ta xét đến khả năng xây dựng các mảng của chúng.


// array of structures

#include

#include
#define N_MOVIES 5
struct movies_t {

char title [50];

int year;

} films [N_MOVIES];


void printmovie (movies_t movie);
int main ()

{

char buffer [50];



int n;

for (n=0; n

{

cout << "Enter title: ";



cin.getline (films[n].title,50);

cout << "Enter year: ";

cin.getline (buffer,50);

films[n].year = atoi (buffer);

}

cout << "\nYou have entered these movies:\n";



for (n=0; n

printmovie (films[n]);

return 0;

}
void printmovie (movies_t movie)

{

cout << movie.title;



cout << " (" << movie.year << ")\n";

}


Enter title: Alien
Enter year: 1979
Enter title: Blade Runner
Enter year: 1982
Enter title: Matrix
Enter year: 1999
Enter title: Rear Window
Enter year: 1954
Enter title: Taxi Driver
Enter year: 1975
 
You have entered these movies:
Alien (1979)
Blade Runner (1982)
Matrix (1999)
Rear Window (1954)
Taxi Driver (1975)

Con trỏ trỏ đến cấu trúc


Như bất kì các kiểu dữ liệu nào khác, các cấu trúc có thể được trỏ đến bởi con trỏ. Quy tắc hoàn toàn giống như đối với bất kì kiểu dữ liệu cơ bản nào:

struct movies_t {

char title [50];

int year;

};
movies_t amovie;

movies_t * pmovie;

Ở đây amovie là một đối tượng có kiểu movies_tpmovie là một con trỏ trỏ tới đối tượng movies_t. OK, bây giờ chúng ta sẽ đến với một ví dụ khác, nó sẽ giới thiệu một toán tử mới: 


// pointers to structures

#include

#include
struct movies_t {

char title [50];

int year;

};

int main ()



{

char buffer[50];


movies_t amovie;

movies_t * pmovie;

pmovie = & amovie;
cout << "Enter title: ";

cin.getline (pmovie->title,50);

cout << "Enter year: ";

cin.getline (buffer,50);

pmovie->year = atoi (buffer);
cout << "\nYou have entered:\n";

cout << pmovie->title;

cout << " (" << pmovie->year << ")\n";
return 0;

}



Enter title: Matrix
Enter year: 1999
 
You have entered:
Matrix (1999)

Đoạn mã trên giới thiệu một điều quan trọng: toán tử ->. Đây là một toán tử tham chiếu chỉ dùng để trỏ tới các cấu trúc và các lớp (class). Nó cho phép chúng ta không phải dùng ngoặc mỗi khi tham chiếu đến một phần tử của cấu trúc. Trong ví dụ này chúng ta sử dụng:

movies->title

nó có thể được dịch thành:

(*movies).title

cả hai biểu thức movies->title(*movies).title đều hợp lệ và chúng đều dùng để tham chiếu đến phần tử title của cấu trúc được trỏ bởi movies. Bạn cần phân biệt rõ ràng với:

*movies.title

nó tương đương với

*(movies.title)

lệnh này dùng để tính toán giá trị được trỏ bởi phần tử title của cấu trúc movies, trong trường hợp này (title không phải là một con trỏ) nó chẳng có ý nghĩa gì nhiều. Bản dưới đây tổng kết tất cả các kết hợp có thể được giữa con trỏ và cấu trúc:


Biểu thức

Mô tả

Tương đương với

movies.title

Phần tử title của cấu trúc movies

 

movies->title

Phần tử title của cấu trúc được trỏ bởi movies

(*movies).title

*movies.title

Giá trị được trỏ bởi phần tử title của cấu trúc movies

*(movies.title)

Các cấu trúc lồng nhau


Các cấu trúc có thể được đặt lồng nhau vì vậy một phần tử hợp lệ của một cấu trúc có thể là một cấu trúc khác.

struct movies_t {

char title [50];

int year;

}
struct friends_t {

char name [50];

char email [50];

movies_t favourite_movie;

} charlie, maria;
friends_t * pfriends = &charlie;

Vì vậy, sau phần khai báo trên chúng ta có thể sử dụng các biểu thức sau:

charlie.name
maria.favourite_movie.title
charlie.favourite_movie.year
pfriends->favourite_movie.year

(trong đó hai biểu thức cuối cùng là tương đương).

Các khái niệm cơ bản về cấu trúc được đề cập đến trong phần này là hoàn toàn giống với ngôn ngữ C, tuy nhiên trong C++, cấu trúc đã được mở rộng thêm các chức năng của một lớp với tính chất đặc trưng là tất cả các phần tử của nó đều là công cộng (public). Bạn sẽ có thêm các thông tin chi tiết trong phần  4.1, Lớp.

Bài 12:Các Kiểu Dữ Liệu Do Người Dùng Định Nghĩa

Trong bài trước chúng ta đã xem xét một loại dữ liệu được định nghĩa bởi người dùng (người lập trình): cấu trúc. Nhưng có còn nhiều kiểu dữ liệu tự định nghĩa khác:

Tự định nghĩa các kiểu dữ liệu (typedef).


C++ cho phép chúng ta định nghĩa các kiểu dữ liệu của riêng mình dựa trên các kiểu dữ liệu đã có. Để có thể làm việc đó chúng ta sẽ sử dụng từ khoá typedef, dạng thức như sau:

typedef   existing_type   new_type_name ;

trong đó existing_type là một kiểu dữ liệu cơ bản hay bất kì một kiểu dữ liệu đã định nghĩa và new_type_name là tên của kiểu dữ liệu mới. Ví dụ

typedef char C;
typedef unsigned int WORD;
typedef char * string_t;
typedef char field [50];

Trong trường hợp này chúng ta đã định nghĩa bốn kiểu dữ liệu mới: C, WORD, string_tfield kiểu char, unsigned int, char* kiểu char[50], chúng ta hoàn toàn có thể sử dụng chúng như là các kiểu dữ liệu hợp lệ:

C achar, anotherchar, *ptchar1;
WORD myword;
string_t ptchar2;
field name;

typedef có thể hữu dụng khi bạn muốn định nghĩa một kiểu dữ liệu được dùng lặp đi lặp lại trong chương trình hoặc kiểu dữ liệu bạn muốn dùng có tên quá dài và bạn muốn nó có tên ngắn hơn.


Union


Union cho phép một phần bộ nhớ có thể được truy xuất dưới dạng nhiều kiểu dữ liệu khác nhau mặc dù tất cả chúng đều nằm cùng một vị trí trong bộ nhớ. Phần khai báo và sử dụng nó tương tự với cấu trúc nhưng chức năng thì khác hoàn toàn:

union model_name {

type1 element1;

type2 element2;

type3 element3;

.

.

} object_name;

Tất cả các phần tử của union đều chiếm cùng một chỗ trong bộ nhớ. Kích thước của nó là kích thước của phần tử lớn nhất. Ví dụ:

union mytypes_t {

char c;


int i;

float f;


} mytypes;

định nghĩa ba phần tử

mytypes.c
mytypes.i
mytypes.f

mỗi phần tử có một kiểu dữ liệu khác nhau. Nhưng vì tất cả chúng đều nằm cùng một chỗ trong bộ nhớ nên bất kì sự thay đổi nào đối với một phần tử sẽ ảnh hưởng tới tất cả các thành phần còn lại.

Một trong những công dụng của union là dùng để kết hợp một kiểu dữ liêu cơ bản với một mảng hay các cấu trúc gồm các phần tử nhỏ hơn. Ví dụ:

union mix_t{

long l;

struct {


short hi;

short lo;

} s;

char c[4];



} mix;

định nghĩa ba phần tử cho phép chúng ta truy xuất đến cùng một nhóm 4 byte: mix.l, mix.smix.c mà chúng ta có thể sử dụng tuỳ theo việc chúng ta muốn truy xuất đến nhóm 4 byte này như thế nào. Tôi dùng nhiều kiểu dữ liệu khác nhau, mảng và cấu trúc trong union để bạn có thể thấy các cách khác nhau mà chúng ta có thể truy xuất dữ liệu.




Các unions vô danh


Trong C++ chúng ta có thể sử dụng các unions vô danh. Nếu chúng ta đặt một union trong một cấu trúc mà không đề tên (phần đi sau cặp ngoặc nhọn { })  union sẽ trở thành vô danh và chúng ta có thể truy xuất trực tiếp đến các phần tử của nó mà không cần đến tên của union (có cần cũng không được). Ví dụ, hãy xem xét sự khác biệt giữa hai phần khai báo sau đây:

union

union vô danh

struct {

char title[50];

char author[50];

union {


float dollars;

int yens;

} price;

} book;


struct {

char title[50];

char author[50];

union {


float dollars;

int yens;

};

} book;


Sự khác biệt duy nhất giữa hai đoạn mã này là trong đoạn mã đầu tiên chúng ta đặt tên cho union (price) còn trong cái thứ hai thì không. Khi truy nhập vào các phần tử dollarsyens, trong trường hợp thứ nhất chúng ta viết:

book.price.dollars


book.price.yens

còn trong trường hợp thứ hai:

book.dollars
book.yens

Một lần nữa tôi nhắc lại rằng vì nó là một union, hai trường dollarsyens đều chiếm cùng một chỗ trong bộ nhớ nên chúng không thể giữ hai giá trị khác nhau.


Kiểu liệt kê (enum)


Kiểu dữ liệu liệt kê dùng để tạo ra các kiểu dữ liệu chứa một cái gì đó hơi đặc biệt một chút, không phải kiểu số hay kiểu kí tự hoặc các hằng truefalse. Dạng thức của nó như sau:

enum model_name {

value1,

value2,

value3,

.

.

} object_name;

Ví dụ, chúng ta có thể tạo ra một kiểu dữ liệu mới có tên color để lưu trữ các màu với phần khai báo như sau:

enum colors_t {black, blue, green, cyan, red, purple, yellow, white};

Chú ý rằng chúng ta không sử dụng bất kì một kiểu dữ liệu cơ bản nào trong phần khai báo. Chúng ta đã tạo ra một kiểu dữ liệu mới mà không dựa trên bất kì kiểu dữ liệu nào có sẵn: kiểu color_t, những giá trị có thể của kiểu color_t được viết trong cặp ngoặc nhọn {}. Ví dụ, sau khi khai báo kiểu liệt kê, biểu thức sau sẽ là hợp lệ:

colors_t mycolor;
 
mycolor = blue;
if (mycolor == green) mycolor = red;

Trên thực tế kiểu dữ liệu liệt kê được dịch là một số nguyên và các giá trị của nó là các hằng số nguyên được chỉ định. Nếu điều này không đựoc chỉ định, giá trị nguyên tương đương với phần tử đầu tiên là 0 và các giá trị tiếp theo cứ thế tăng lên 1, Vì vậy, trong kiểu dữ liệu colors_t mà chúng ta định nghĩa ở trên, white tương đương với 0, blue tương đương với 1, green tương đương với 2 và cứ tiếp tục như thế. 

Nếu chúng ta chỉ định một giá trị nguyên cho một giá trị nào đó của kiểu dữ liệu liệt kê (trong ví dụ này là phần tử đầu tiên) các giá trị tiếp theo sẽ là các giá trị nguyên tiếp theo, ví dụ:

enum months_t { january=1, february, march, april,

may, june, july, august,

september, october, november, december} y2k;



trong trường hợp này, biến y2k có kiểu dữ liệu liệt kê months_t có thể chứa một trong 12 giá trị từ january đến december và tương đương với các giá trị nguyên từ 1 đến 12, không phải 0 đến 11 vì chúng ta đã đặt january bằng 1

Nguồn internet
Каталог: gallery
gallery -> Album hưƠng xuâN. Thơ phổ nhạC. Phòng thu audio. Nhạc Sĩ Đình Đạm
gallery -> Phụ cấp độc hại, nguy hiểm
gallery -> BỘ TÀi chính cộng hoà XÃ HỘi chủ nghĩa việt nam độc lập Tự do Hạnh phúc
gallery -> Nobel văn chương năm 1987 joseph brodsky
gallery -> TÊN ĐỀ TÀi luận văn thạc sĩ khnn chuyên ngành chăn nuôi từ NĂM 1996 2012
gallery -> BÁo cáo công khai đIỀu kiệN ĐẢm bảo chất lưỢng đÀo tạo tiến sĩ Tên chuyên ngành, mã số, quyết định giao chuyên ngành đào tạo
gallery -> CHƯƠng I kế toán vốn bằng tiềN
gallery -> KẾ toán vốn bằng tiền I. YÊU cầU
gallery -> Phụ lục II nguyên tắC, NỘi dung và KẾt cấu tài khoản kế toáN

tải về 448.29 Kb.

Chia sẻ với bạn bè của bạn:
1   ...   6   7   8   9   10   11   12   13   14




Cơ sở dữ liệu được bảo vệ bởi bản quyền ©hocday.com 2024
được sử dụng cho việc quản lý

    Quê hương