Professional Documents
Culture Documents
Chuong 7 NN C
Chuong 7 NN C
Nội dung
7.1 Định nghĩa kiểu cấu trúc.
7.2 Khai báo, khởi tạo và truy xuất biến kiểu cấu trúc.
7.3 Truyền biến cấu trúc cho hàm
7.4 Mảng cấu trúc và con trỏ cấu trúc.
1
CHƯƠNG 7. KIỂU DỮ LIỆU CẤU TRÚC
Để lưu trữ và xử lý thông tin trong máy tính ta có các biến và các mảng.
Mỗi biến chứa được một giá trị.
Mảng là tập hợp nhiều biến có cùng một kiểu giá trị và được biểu thị bằng một
tên.
Vấn đề: Lưu mảng dữ liệu mà mỗi một phần tử gồm nhiều thành phần có kiểu
khác nhau. Ví dụ như một danh sách các sinh viên với các thông tin:
- Mã số sinh viên;
- Họ tên;
- Ngày tháng năm sinh;
- Giới tính;
- Địa chỉ thường trú 2
CHƯƠNG 7. KIỂU DỮ LIỆU CẤU TRÚC
7.1 Định nghĩa kiểu cấu trúc.
Ngôn ngữ lập trình C cho phép người lập trình tự định nghĩa ra kiểu dữ liệu mới (kiểu
cấu trúc) theo nhu cầu sử dụng từ những kiểu dữ liệu đã có hoặc đã định nghĩa trước đó.
Kiểu cấu trúc (Structure) là kiểu dữ liệu bao gồm nhiều thành phần có kiểu dữ liệu
khác nhau, mỗi thành phần được gọi là một trường (field).
Cú pháp 1: Cú pháp 2:
struct <Tên cấu trúc> typedef struct
{ {
<Kiểu dữ liệu> <Tên trường 1> ; <Kiểu dữ liệu > <Tên trường 1> ;
<Kiểu dữ liệu > <Tên trường 2> ; <Kiểu dữ liệu > <Tên trường 2> ;
…….. ……..
<Kiểu dữ liệu > <Tên trường n> ; <Kiểu dữ liệu > <Tên trường n> ;
}; } <Tên cấu trúc>; 3
7.1 Định nghĩa kiểu cấu trúc.
Cú pháp 1: Cú pháp 2:
struct <Tên cấu trúc> typedef struct
{ {
<Kiểu dữ liệu> <Tên trường 1> ; <Kiểu dữ liệu > <Tên trường 1> ;
<Kiểu dữ liệu > <Tên trường 2> ; <Kiểu dữ liệu > <Tên trường 2> ;
…….. ……..
<Kiểu dữ liệu > <Tên trường n> ; <Kiểu dữ liệu > <Tên trường n> ;
}; } <Tên cấu trúc>;
Trong đó:
- <Tên cấu trúc>: là một tên được đặt theo quy tắc đặt tên của C; tên này mang ý nghĩa
sẽ là tên kiểu cấu trúc;
- <Kiểu dữ liệu> < Tên trường i> (i=1..n): mỗi trường trong cấu trúc có kiểu dữ liệu và
tên của trường phải là một tên được đặt theo quy tắc đặt tên của C. 4
CHƯƠNG 7. KIỂU DỮ LIỆU CẤU TRÚC
7.1 Định nghĩa kiểu cấu trúc.
Ví dụ 1: Để quản lý ngày, tháng, năm của một ngày trong năm ta có thể khai báo kiểu
cấu trúc gồm 3 thông tin: ngày, tháng, năm.
5
CHƯƠNG 7. KIỂU DỮ LIỆU CẤU TRÚC
7.1 Định nghĩa kiểu cấu trúc.
Ví dụ 2: Mỗi sinh viên cần được quản lý bởi các thông tin: Mã số sinh viên, họ tên, ngày
tháng năm sinh, giới tính, địa chỉ thường trú.
Kết thúc của phần khai báo kiểu cấu trúc là dấu chấm phẩy (;).
Các kiểu cấu trúc được phép khai báo lồng nhau, nghĩa là kiểu cấu trúc có thể lại là
một trường của kiểu cấu trúc.
Một biến có kiểu cấu trúc sẽ được cấp phát bộ nhớ sao cho các thành phần của nó
được sắp liên tục theo thứ tự xuất hiện trong khai báo. 7
7.2 Khai báo, khởi tạo và truy xuất biến kiểu cấu trúc .
7.2.1 Khai báo biến kiểu cấu trúc .
Cú pháp:
Đối với cấu trúc được định nghĩa theo cách 1:
struct <Tên cấu trúc> <Biến 1> [, <Biến 2>…];
Ví dụ: struct KieuNgayThang NgaySinh;
struct KieuSinhVien SV;
Đối với các cấu trúc được định nghĩa theo cách 2:
<Tên cấu trúc> <Biến 1> [, <Biến 2>…];
Ví dụ: KieuNgayThang NgaySinh;
KieuSinhVien SV; 8
7.2 Khai báo, khởi tạo và truy xuất biến kiểu cấu trúc .
7.2.2 Truy xuất đến từng trường của biến cấu trúc
Cú pháp:
<Biến cấu trúc>.<Tên trường>;
Ví dụ1: Viết chương trình cho phép đọc dữ liệu từ bàn phím cho biến SinhVien và in
biến đó lên màn hình:
#include<conio.h> typedef struct
#include<stdio.h> {
#include<string.h> char MSSV[10];
typedef struct char HoTen[40];
{ KieuNgayThang NgaySinh;
unsigned char Ngay; int Phai;
unsigned char Thang; char DiaChi[40];
unsigned int Nam; } KieuSinhVien;
9
} KieuNgayThang;
Ví dụ1: Viết chương trình cho phép đọc dữ liệu từ bàn phím cho biến SinhVien và in
biến đó lên màn hình:
void InSV(KieuSinhVien s)
{ printf(“MSSV: | Ho va ten | Ngay Sinh | Dia chi\n”);
printf(“%s | %s | %d-%d-%d | %s\n”,s.MSSV,s.HoTen,
s.NgaySinh.Ngay,s.NgaySinh.Thang,s.NgaySinh.Nam,s.DiaChi);
}
int main() fflush(stdin);
{ printf(“Dia chi: “);gets(SV.DiaChi);
KieuSinhVien SV, s; printf("In cac thong so cua bien cau truc SV\n");
printf(“Nhap MSSV: “);gets(SV.MSSV); InSV(SV);
printf(“Nhap Ho va ten: “);gets(SV.HoTen); s=SV;
printf(“Sinh ngay: “); printf("In cac thong so cua bien cau truc s\n");
scanf(“%d”,&SV.NgaySinh.Ngay); InSV(s);
printf(“Thang: “);scanf(“%d”,&SV.NgaySinh.Thang); getch();
printf(“Nam: “);scanf(“%d”,&SV.NgaySinh.Nam); return 0;
printf(“Gioi tinh (0: Nu), (1: Nam): “); }
scanf(“%d”,&SV.Phai); 10
7.2 Khai báo, khởi tạo và truy xuất biến kiểu cấu trúc .
7.2.2 Truy xuất đến từng trường của biến cấu trúc
Lưu ý:
Với các biến kiểu cấu trúc ta không thể thực hiện được các thao tác sau đây:
Không sử dụng các hàm xuất nhập trên biến cấu trúc; Hàm xuất nhập dung
cho các trường của
Ví dụ: biến cấu trúc thì được
gets(SV) gets(SV.MSSV)
printf(“chuỗi định dạng”, SV) printf(“%s”, SV.Hoten)
scanf(“chuỗi định dạng”, SV) scanf(“%d”, SV.NgaySinh.Nam)
Không sử dụng các phép so sánh, các phép toán số học và logic.
Ví dụ: SV ==s; hay SV=s+5; 11
7.2.2 Truy xuất đến từng trường của biến cấu trúc
Lưu ý:
Các biến cấu trúc cùng kiểu có thể gán cho nhau. ( Thao tác gán thực hiện trên toàn
bộ các trường của biến cấu trúc không phải trên một trường riêng rẽ nào)
Ví dụ câu lệnh gán: s=SV;
Nhập dữ liệu
(trong hàm main)
Việc khởi tạo cấu trúc có thể được thực hiện trong lúc khai báo biến cấu trúc.
Các trường của cấu trúc được khởi tạo được đạt giữa 2 dấu { và }, chúng được
phân cách nhau bởi dấu phẩy (,).
Ví dụ khởi tạo biến cấu trúc NgaySinh:
struct KieuNgayThang NgaySinh ={29, 8, 1986};
Ví dụ khởi tạo một mảng biến cấu trúc:
struct KieuNgayThang a[3]= {{29,8,1986},{30,9,1987},{15,10,1988}};
13
CHƯƠNG 7. KIỂU DỮ LIỆU CẤU TRÚC
7.3 Truyền biến cấu trúc cho hàm.
Giống như các tham số có kiểu dữ liệu cơ bản khác, ta có thể truyền tham số
có kiểu cấu trúc cho hàm
<kiểu dữ liệu trả về> <tên hàm>(<kiểu cấu trúc> <tên biến>,…)
Ví dụ:
Void InSV(KieuSinhVien s);
Lời gọi hàm:
InSV(s);
InSV(SV);
14
CHƯƠNG 7. KIỂU DỮ LIỆU CẤU TRÚC
7.4 Mảng cấu trúc và con trỏ cấu trúc.
7.4.1 Mảng cấu trúc.
Khai báo mảng dữ liệu kiểu cấu trúc
Đối với cấu trúc struct <Tên kiểu cấu trúc> <tên mảng>[số phần tử ];
được định nghĩa
theo cách 1
Ví dụ :struct KieuSinhVien a[10];
Hoặc:
Ví dụ: Câu lệnh nhập họ tên cho phần tử thứ có chỉ số 5 của mảng a
16
CHƯƠNG 7. KIỂU DỮ LIỆU CẤU TRÚC
7.4 Mảng cấu trúc và con trỏ cấu trúc.
7.4.2 Con trỏ cấu trúc.
Khai báo con trỏ kiểu cấu trúc
Ví dụ : struct KieuSinhVien *p ;
Hoặc:
Ví dụ : KieuSinhVien *p ; 17
CHƯƠNG 7. KIỂU DỮ LIỆU CẤU TRÚC
7.4.2 Con trỏ cấu trúc.
Sử dụng các con trỏ kiểu cấu trúc.
Khi khai báo biến con trỏ cấu trúc, biến con trỏ chưa có địa chỉ cụ thể.
Muốn thao tác trên con trỏ cấu trúc hợp lệ, tương tự như các con trỏ khác, ta phải:
- Cấp phát một vùng nhớ cho nó (sử dụng hàm malloc() hay calloc);
- Hoặc, cho nó quản lý địa chỉ của một biến cấu trúc nào đó.
Ví dụ: Sau khi khởi tạo giá trị của cấu trúc:
struct KieuNgayThang NgaySinh ={29, 8, 1986};
struct KieuNgayThang *p;
Khi đó biến con trỏ p chứa
p = & NgaySinh;
địa chỉ của NgaySinh 18
7.4.2 Con trỏ cấu trúc.
Truy cập các thành phần của cấu trúc đang được quản lý bởi con trỏ
Để truy cập đến từng trường của 1 cấu trúc thông qua con trỏ của nó, ta sử
dụng toán tử dấu mũi tên -> (dấu - và dấu >).
Sử dụng đến phép toán * để truy cập vùng dữ liệu đang được quản lý bởi con
trỏ cấu trúc để lấy thông tin cần thiết.
Ví dụ: int main()
{
#include<conio.h> NgayThang Ng={29,8,1986};
#include<stdio.h> NgayThang *p; p=&Ng;
typedef struct printf("Truy cap binh thuong %d-%d-%d\n", Ng.Ngay,Ng.Thang,Ng.Nam);
{ printf("Truy cap qua con tro %d-%d-%d\n", p->Ngay,p->Thang,p->Nam);
unsigned char Ngay; printf("Truy cap qua vung nho con tro %d-%d-%d\n",
unsigned char Thang; (*p).Ngay,(*p).Thang,(*p).Nam);
unsigned int Nam; getch(); return 0;
} NgayThang; } 19
CHƯƠNG 7. KIỂU DỮ LIỆU CẤU TRÚC
7.4 Mảng cấu trúc và con trỏ cấu trúc.
Bài tập ví dụ: Viết chương trình xử lý danh sách sinh viên (tối đa 20 Sinh viên),
cho phép thực hiện các công việc sau:
1. Cho phép nhập danh sách sinh viên
2. Cho phép in danh sách sinh viên
3. Cho phép sửa danh sách sinh viên.
(viết dưới dạng các hàm con với tham số truyền là cấu trúc)
20
CHƯƠNG 7. KIỂU DỮ LIỆU CẤU TRÚC
Truyền biến cấu //cac ham xu ly
#include <stdio.h> trúc cho hàm int nhap(struct Sinhvien *p) ;
#include <conio.h> int nhapds(struct Sinhvien *a, int n) ;
#include<string.h> int in(struct Sinhvien x) ;
struct Ngaythang Truyền mảng int inds(const struct Sinhvien a[], int n) ;
{ cấu trúc cho int sua(struct Sinhvien *r)
int ng ; hàm int suads(struct Sinhvien *a, int n) ;
int th ; //Khai báo mảng
int nam ; Truyền con struct Sinhvien a[20];
}; trỏ cấu trúc
int main()
cho hàm
struct Sinhvien {
{ nhapds(a,20);
char hoten[25] ; inds(a,20);
struct Ngaythang ns; suads(a,20);
int gt; getch();
float diem ; return 0;
}; } 21
int nhap(struct Sinhvien *p) int main()
{ fflush(stdin); {
printf("Nhap ho va ten: ");gets(p->hoten); Cách sử nhapds(a,20);
printf("Nhap ngay sinh (ngay thang nam): "); dụng inds(a,20);
scanf("%d%d%d", &p->ns.ng ,&p->ns.th,&p->ns.nam); con trỏ suads(a,20);
printf("Gioi tinh 0: nu, 1: nam: "); truy cập getch();
đến các
scanf("%d",& p->gt); return 0;
trường
printf("Diem: "); }
của biến
scanf("%f",& p->diem); cấu trúc
return 0;
}
int nhapds(struct Sinhvien *a, int n)
{
int i; So sánh thông số
truyền trong 2 lời
for (i=0; i<n; i++) nhap(&a[i]) ;
gọi hàm
return 0;
}
22
int in(struct Sinhvien x) int main()
{ {
printf("Ho ten :%s\nNgay sinh %d/%d/%d\n",x.hoten,x.ns.ng, nhapds(a,20);
x.ns.th, x.ns.nam) ; inds(a,20);
printf("Gioi tinh :%s\nDiem :%f\n",(x.gt==1) ?"Nam" :"Nu",x.diem) ; suads(a,20);
return 0; getch();
} return 0;
int inds(const struct Sinhvien a[], int n) }
{
int i;
for (i=0; i<n; i++)
in(a[i]) ;
return 0;
}
23
int suads(struct Sinhvien *a, int n) int main()
{ {
int chon; nhapds(a,20);
do inds(a,20);
{ suads(a,20);
printf("\nNhap phan tu duoc su tu 0 den %d, gia tri khac thoat:",n-1); getch();
scanf("%d",&chon); return 0;
if(chon>=0 &&chon<n) sua(&a[chon]) ; }
}while(chon>=0 && chon<n);
return 0;
}
24
int sua(struct Sinhvien *r)
{
int chon;
do {
printf("1: Sua ho ten\n2: Sua ngay sinh\n3:Sua gioi tinh\n4:Sua diem\n5:In\n0: Ket thuc\n");
scanf("%d",&chon);
switch (chon)
{
case 1: fflush(stdin);
printf("Nhap ho ten:"); gets(r->hoten);
break;
case 2: printf("Nhap ngay thang nam sinh:");
scanf("%d%d%d",&r->ns.ng,&r->ns.th,&r->ns.nam);
break;
case 3: printf("Nhap gioi tinh 0:Nu 1:Nam:");scanf("%d",&r->gt) ;
break;
case 4: printf("Nhap diem:");scanf("%f",&r->diem);
break;
case 5: printf("Sinh vien:");in(*(r));break;
case 0: break;
default:
printf("Nhap gia tri khong dung\n");break;
}
25
} while (chon) ;return 0;}
Tóm Tắt Nội Dung Chương 7
Bài 2:
Khai báo kiểu dữ liệu biểu diễn thông tin một tam giác, sau đó viết chương trình thực hiện
các chức năng sau:
a.Nhập tam giác
b.Xuất tam giác theo định dạng ((x1, y1); (x2, y2); (x3, y3))
c.Kiểm tra 3 đỉnh có lập thành 3 đỉnh của một tam giác không?
d.Tính chu vi tam giác
e.Tính diện tích tam giác
f. Tính tọa độ trọng tâm tam giác
g.Phân loại tam giác
28