Cap Phat Dong Va Cau Truc

You might also like

Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 26

www.uit.edu.

vn

NHẬP MÔN LẬP TRÌNH

BỘ NHỚ ĐỘNG
KIỂU DỮ LIỆU CÓ CẤU TRÚC
NỘI DUNG

9 CẤP PHÁT VÀ GIẢI PHÓNG BỘ NHỚ ĐỘNG

Trường Đại Học CNTT


NỘI DUNG BÀI BỘ NHỚ ĐỘNG
 Khái niệm biến “động”
 Các hàm cấp phát bộ nhớ
 Hàm malloc
 Hàm calloc
 Hàm realloc
 Hàm giải phóng bộ nhớ
 Hàm free

Trường Đại Học CNTT


BIẾN ĐỘNG
 Biến động là biến được “tạo” ra khi chạy
chương trình. Thông qua con trỏ, vùng nhớ
biến được cấp phát và quản lý.
 Các hàm thao tác vùng nhớ trên C được
định nghĩa trong thư viện stdlib.h hoặc
alloc.h
 Các hàm cấp phát và giải phóng bộ nhớ
 Hàm malloc
 Hàm calloc
 Hàm realloc
Trường Đại Học CNTT
 Hàm free
HÀM MALLOC / HÀM FREE
 Chức năng của hàm malloc là gọi cấp phát
một vùng nhớ có kích thước size:
void *malloc(size_t size);
 Ví dụ:
int *p;
p=(int *) malloc(100);
p=(int *) malloc(80*sizeof(int));
 Hàm free được dùng để giải phóng một
vùng nhớ đã được cấp phát thông qua con
trỏ prt:
void free(void Trường
*ptr); Đại Học CNTT
VÍ DỤ
#include <string.h>
#include <stdio.h>
#include <alloc.h>
void main(void)
{
char *str;
/* allocate memory for string */
str = (char *) malloc(10);
/* copy "Hello" to string */
strcpy(str, "Hello");
/* display string */
printf("String is %s\n", str);
/* free memory */
free(str);
}
Trường Đại Học CNTT
HÀM CALLOC VÀ REALLOC
 Bên cạnh hàm malloc, một vùng nhớ còn
có thể được cấp phát bằng hàm calloc và
cấp phát lại bằng hàm realloc.
 Hàm calloc cấp phát một vùng nhớ có kích
thước nitems* size bytes.
void *calloc(size_t nitems, size_t
size);
 Hàm realloc điều chỉnh lại vùng nhớ đã
được cấp phát block, với kích thước mới là
size bytes.
void *realloc(void* block, size_t
Trường Đại Học CNTT
size);
BỘ NHỚ ĐỘNG VÀ MẢNG 1 CHIỀU
 Cấp phát vùng nhớ n phần tử cho biến con trỏ
int *a :
a = (int *)malloc(n*sizeof(int));
a =(int *)calloc(n, sizeof(int));
 Kiểm tra cấp phát thành công và thực hiện các
thao tác tiếp (như đối với mảng):
if(a!=NULL)
{
// dùng như mảng cho a[0], a[1], …
…………
free(a);
} Trường Đại Học CNTT
Nhập xuất mảng 1 chiều động
void main()
{ int *a,n,i;
printf(“Nhap n=”); scanf(“%d”,&n);
a= (int*) malloc(n*sizeof(int));
for(i=0;i<n;i++)
{ printf(“nhap a[%d]=”,i);
scanf(“%d”,a+i);
}
printf(“Mang sau khi nhap:”);
for(i=0;i<n;i++)
printf(“%d”,a[i]); // hoặc *(a+i)

free(a);
}
Trường Đại Học CNTT
Hàm nhập xuất mảng 1 chiều động
void Nhap1c(int a[],int n) //hoặc *a
{
for(i=0;i<n;i++)
{ printf(“nhap a[%d]=”,i);
scanf(“%d”,a+i);
}
}
void Xuat1c(int a[],int n) //hoặc *a
{
for(i=0;i<n;i++)
printf(“%d”,a[i]); // hoặc *(a+i)

}
void main()
{
int *a,n,i;
printf(“Nhap n=”); scanf(“%d”,&n);
a= (int*) malloc(n*sizeof(int));
Nhap1c(a,n);
printf(“Mang 1 chieu sau khi nhap”);
Xuat1c(a,n);
}

Trường Đại Học CNTT


BỘ NHỚ ĐỘNG VÀ MẢNG 2 CHIỀU
a = (int **)malloc(m*sizeof(int*));
if(a!=NULL)
{ kt=0;
for(i=0; i<m; i++)
a[i]=NULL;
for(i=0; i<m; i++)
{
if(kt==1) break;
a[i]=(int *)malloc(n*sizeof(int));
if(a[i]==NULL) kt=1;
}
if(kt==0)
{
/* dùng như mảng 2 chiều a[i][j] */
………
for(i=0; i<m; i++)
if(a[i]!=NULL) free(a[i];
free(a);
}
}
Trường Đại Học CNTT
NỘI DUNG

10 KIỂU DỮ LIỆU CÓ CẤU TRÚC

Trường Đại Học CNTT


NỘI DUNG BÀI KIỂU CẤU TRÚC

 Khái niệm
 Khai báo kiểu cấu trúc struct
 Mảng và con trỏ cấu trúc
 Truy xuất các thành phần của cấu
trúc
 Kiểu cấu trúc và hàm
 Ví dụ minh họa
Trường Đại Học CNTT
KHÁI NIỆM
 Kiểu cấu trúc (hay bản ghi đối với một số
NNLT khác) là dạng dữ liệu thường được
định nghĩa để mô tả dữ liệu có nhiều thành
phần thuộc nhiều kiểu dữ liệu khác nhau.
 Kiểu dữ liệu của từng thành phần có thể là
các kiểu dữ liệu cơ bản (ký tự, số nguyên, số
thực), con trỏ, mảng, và thậm chí là một kiểu
cấu trúc.
 Kiểu cấu trúc trên C được định nghĩa thông
qua từ khoá struct

Trường Đại Học CNTT


KHAI BÁO STRUCT
 Cú pháp tổng quát:
struct [<tên cấu trúc>]
{
[<KDL> <tên biến [, tên biến, …]>];
[<KDL> <tên biến [, tên biến, …]>];

} [<danh sách các biến cấu trúc>];
 <tên cấu trúc> và <danh sách các
biến cấu trúc> là tùy chọn nhưng ít nhất
phải có một trong 2 được khai báo.
 Các biến cùng kiểu KDL có thể khai báo cách
nhau bởi dấu phẩy. Các KDL khác nhau khai
báo riêng cách nhau bởi
Trường dấu
Đại Học CNTTchấm phẩy
KHAI BÁO STRUCT
 Trong C, ta có thể đặt <tên kiểu> cho một <định
nghĩa kiểu> thông qua từ khoá typedef:
typedef <định nghĩa kiểu>
<tên kiểu>;
 Ví dụ:
typedef struct tagHocSinh
{
char sHoTen[50];
int nToan, nVan;
float fDTB;
} HOCSINH, *PTR_HOCSINH;
 Khi đó ta có thể khai báo một biến hs như sau:
HOCSINH hs;

Trường Đại Học CNTT


MẢNG VÀ CON TRỎ CẤU TRÚC
 Các thao tác trên mảng, con trỏ và vùng nhớ
động cho các biến cấu trúc hoàn toàn tương tự
như đối với các biến có kiểu dữ liệu thông
thường.
 Ví dụ:
HOCSINH hs, manghs[20];
PTR_HOCSINH phs1, phs2;
manghs[5] = hs;
phs1 = &hs;
phs2 = (PTR_HOCSINH)calloc(10,
sizeof(HOCSINH));
Trường Đại Học CNTT
TRUY XUẤT THÀNH PHẦN CẤU TRÚC

 Để truy xuất đến một thành phần của biến cấu trúc tĩnh
ta dùng toán tử chấm “.” và dùng toán tử “->” đối với
biến con trỏ.
 Ví dụ:
HOCSINH hs;
hs.sHoTen=“Phúc Khang An”;
hs.nToan=10;
hs.nVan = 7;
hs.fDTB=(hs.nToan+hs.nVan)/2.0;
 Không nên dùng toán tử & đối với thành phần cấu trúc.
Trường Đại Học CNTT
TRUY XUẤT THÀNH PHẦN CẤU TRÚC

 Với các biến:


HOCSINH hs;
PTR_HOCSINH phs = &hs;
 Ta có thể truy xuất đến thành phần sHoTen
của cấu trúc bằng các cách tương đương như:
gets(hs.sHoTen);
gets(phs->sHoTen);
gets((*phs).sHoTen);

Trường Đại Học CNTT


TRUY XUẤT THÀNH PHẦN CẤU TRÚC
 Áp dụng cho biến mảng cấu trúc:
HOCSINH dshs[100];
PTR_HOCSINH pdshs = dshs;
 Ta có thể truy xuất đến thành phần sHoTen của cấu
trúc bằng các cách tương đương như:
gets(dshs[i].sHoTen);
gets(pdshs[i].sHoTen);
gets(*(dshs+i).sHoTen);
gets(*(pdshs+i).sHoTen);
gets(pdshs->sHoTen); pdshs++;
gets((*pdshs).sHoTen); pdshs++;
Trường Đại Học CNTT
KIỂU CẤU TRÚC VÀ HÀM

 Các thao tác trên hàm cho biến cấu trúc hoàn toàn
tương tự cho biến thông thường. Chẳng hạn truyền
tham biến và tham trị như sau:
 Prototype:
void NhapHS(PTR_HOCSINH phs);
void XuatHS(HOCSINH hs);
 Khi đó ta có thể gọi dùng hàm:
HOCSINH hs;
NhapHS(&hs);
XuatHS(hs);
Trường Đại Học CNTT
VÍ DỤ MINH HỌA

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>

typedef struct tagHOCSINH


{
char sHoTen[50];
float fVan, fToan;
float fDTB;
}HOCSINH, *PTR_HOCSINH;

void NhapHS(PTR_HOCSINH phs, int stt);


void XuatHS(HOCSINH hs, int stt);
Trường Đại Học CNTT
VÍ DỤ MINH HỌA
void main()
{ int i, nSoHS;
PTR_HOCSINH pDSHS;
clrscr();
printf("So luong hoc sinh: ");
scanf("%d", &nSoHS);
pDSHS = (PTR_HOCSINH)calloc(nSoHS,
sizeof(HOCSINH));
if(pDSHS==NULL) return;
for(i=0; i<nSoHS; i++)
NhapHS(&pDSHS[i], i);
for(i=0; i<nSoHS; i++)
XuatHS(pDSHS[i], i);
if(pDSHS) free(pDSHS);
getch();} Trường Đại Học CNTT
VÍ DỤ MINH HỌA
void NhapHS(PTR_HOCSINH phs, int stt)
{
char hoten[50];
float van, toan;
flushall();
printf("\nHoc sinh thu %d:", stt+1);
printf("\nHo Ten: ");
gets(hoten);
printf("Diem van: ");
scanf("%f", &van);
printf("Diem toan: ");
scanf("%f", &toan);
strcpy(phs->sHoTen, hoten);
phs->fVan = van;
phs->fToan = toan;
phs->fDTB = (float)(van+toan)/2;
}
Trường Đại Học CNTT
VÍ DỤ MINH HỌA

void XuatHS(HOCSINH hs, int stt)


{
printf("\n\nHoc sinh thu %d: %s",
stt+1, hs.sHoTen);
printf("\nVan %.1f, Toan %.1f. DTB
%.1f",
hs.fVan, hs.fToan, hs.fDTB);
}

Trường Đại Học CNTT


www.uit.edu.vn

You might also like