Lp trình căn bn
Chương VI
KIU MNG
Hc xong chương này, sinh viên s nm được các vn đề sau:
Khái nim v kiu d liu mng cũng như ng dng ca nó.
Cách khai báo biến kiu mng và các phép toán trên các phn t ca mng.
I. GII THIU KIU D LIU “KIU MNG”
TRONG C
Mng là mt tp hp các phn t c định có cùng mt kiu, gi là kiu phn t.
Kiu phn t có th là có các kiu bt k: ký t, s, chui ký t…; cũng có khi ta s
dng kiu mng để làm kiu phn t cho mt mng (trong trường hp này ta gi là
mng ca mng hay mng nhiu chiu).
Ta có th chia mng làm 2 loi: mng 1 chiu và mng nhiu chiu.
Mng là kiu d liu được s dng rt thường xuyên. Chng hn người ta cn
qun lý mt danh sách h và tên ca khong 100 sinh viên trong mt lp. Nhn thy
rng mi h và tên để lưu tr ta cn 1 biến kiu chui, như vy 100 h và tên thì cn
khai báo 100 biến kiu chui. Nếu khai báo như thế này thì đon khai báo cũng như
các thao tác trên các h tên s rt dài dòng và rc ri. Vì thế, kiu d liu mng giúp
ích ta trong trường hp này; ch cn khai báo 1 biến, biến này có th coi như là tương
đương vi 100 biến chui ký t; đó là 1 mng mà các phn t ca nó là chui ký t.
Hay như để lưu tr các t khóa ca ngôn ng lp trình C, ta cũng dùng đến mt mng
để lưu tr chúng.
II. MNG 1 CHIU
Nếu xét dưới góc độ toán hc, mng 1 chiu ging như mt vector. Mi phn t ca mng
mt chiu có giá tr không phi là mt mng khác.
II.1. Khai báo
II.1.1. Khai báo mng vi s phn t xác định (khai báo tường minh)
Cú pháp: <Kiu> <Tên mng ><[s phn t]>
Ý nghĩa:
- Tên mng: đây là mt cái tên đặt đúng theo quy tc đặt tên ca danh biu. Tên này
cũng mang ý nghĩa là tên biến mng.
- S phn t: là mt hng s nguyên, cho biết s lượng phn t ti đa trong mng là
bao nhiêu (hay nói khác đi kích thước ca mng là gì).
- Kiu: mi phn t ca mng có d liu thuc kiu gì.
- đây, ta khai báo mt biến mng gm có s phn t phn t, phn t th nht là
tên mng [0], phn t cui cùng là tên mng[s phn t -1]
Trang 72
Lp trình căn bn
Ví d:
int a[10]; /* Khai báo biến mng tên a, phn t th nht là a[0], phn t
cui cùng là a[9].*/
Ta có th coi mng a là mt dãy liên tiếp các phn t trong b nh như sau:
V trí 0 1 2 3 4 5 6 7 8 9
Tên phn t a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]
Hình 1: Hình nh mng a trong b nh
II.1.2. Khai báo mng vi s phn t không xác định (khai báo không tường
minh)
Cú pháp: <Kiu> <Tên mng> <[]>
Khi khai báo, không cho biết rõ s phn t ca mng, kiu khai báo này thường được
áp dng trong các trường hp: va khai báo va gán giá tr, khai báo mng là tham s hình
thc ca hàm.
a. Va khai báo va gán giá tr
Cú pháp:
<Kiu> <Tên mng> []= {Các giá tr cách nhau bi du phy}
Nếu va khai báo va gán giá tr thì mc nhiên C s hiu s phn t ca mng là s
giá tr mà chúng ta gán cho mng trong cp du {}. Chúng ta có th s dng hàm sizeof()
để ly s phn t ca mng như sau:
S phn t=sizeof(tên mng)/ sizeof(kiu)
b. Khai báo mng là tham s hình thc ca hàm, trong trường hp này ta không cn
ch định s phn t ca mng là bao nhiêu.
II.2 Truy xut tng phn t ca mng
Mi phn t ca mng được truy xut thông qua Tên biến mng theo sau là ch s
nm trong cp du ngoc vuông [ ]. Chng hn a[0] là phn t đầu tiên ca mng a được khai
báo trên. Ch s ca phn t mng là mt biu thc mà giá tr là kiu s nguyên.
Vi cách truy xut theo kiu này, Tên biến mng[Ch s] có th coi như là mt biến
có kiu d liu là kiu được ch ra trong khai báo biến mng.
Ví d 1:
int a[10];
Trong khai báo này, vic truy xut các phn t được ch ra trong hình 1. Chng hn
phn t th 2 (có v trí 1) là a[1]…
Ví d 2: Va khai báo va gán tr cho 1 mng 1 chiu các s nguyên. In mng s
nguyên này lên màn hình.
Gi s ta đã biết s phn t ca mng là n; vic hin th 1 giá tr s nguyên lên màn
hình ta cn s dng hàm printf() vi định dng %d, tng quát hóa lên nếu mun hin th lên
màn hình giá tr ca n s nguyên, ta cn gi hàm printf() đúng n ln. Như vy trong trường
hp này ta s dng 1 vòng lp để in ra giá tr các phn t.
Ta có đon chương trình sau:
#include <stdio.h>
#include <conio.h>
int main()
{
int n,i,j,tam;
int dayso[]={66,65,69,68,67,70};
clrscr();
Trang 73
Lp trình căn bn
n=sizeof(dayso)/sizeof(int); /*Ly s phn t*/
printf("\n Noi dung cua mang ");
for (i=0;i<n;i++)
printf("%d ",dayso[i]);
return 0;
}
Ví d 3: Đổi mt s nguyên dương thp phân thành s nh phân. Vic chuyn đổi này
được thc hin bng cách ly s đó chia liên tiếp cho 2 cho ti khi bng 0 và ly các s dư
theo chiu ngược li để to thành s nh phân. Ta s dùng mng mt chiu để lưu li các s dư
đó. Chương trình c th như sau:
#include<conio.h>
#include<stdio.h>
int main()
{
unsigned int N;
unsigned int Du;
unsigned int NhiPhan[20],K=0,i;
printf("Nhap vao so nguyen N= ");scanf("%d",&N);
do
{
Du=N % 2;
NhiPhan[K]=Du; /* Lưu s dư vào mng v trí K*/
K++; /* Tăng K lên để ln kế lưu vào v trí kế*/
N = N/2;
} while(N>0);
printf("Dang nhi phan la: ");
for(i=K-1;i>=0;i--)
printf("%d",NhiPhan[i]);
getch();
return 0;
}
Ví d 4: Nhp vào mt dãy n s và sp xếp các s theo th t tăng. Đây là mt bài
toán có ng dng rng rãi trong nhiu lĩnh vc. Có rt nhiu gii thut sp xếp. Mt trong s
đó được mô t như sau:
Đầu tiên đưa phn t th nht so sánh vi các phn t còn li, nếu nó ln hơn mt
phn t đang so sánh thì đổi ch hai phn t cho nhau. Sau đó tiếp tc so sánh phn t th hai
vi các phn t t th ba tr đi ... c tiếp tc như vy cho đến phn t th n-1.
Chương trình s được chia thành các hàm Nhap (Nhp các s), SapXep (Sp xếp) và
InMang (In các s); các tham s hình thc ca các hàm này là 1 mng không ch định rõ s
phn t ti đa, nhưng ta cn có thêm s phn t thc tế được s dng ca mng là bao nhiêu,
đây là mt giá tr nguyên.
#include<conio.h>
#include<stdio.h>
void Nhap(int a[],int N)
{
int i;
for(i=0; i< N; i++)
{
printf("Phan tu thu %d: ",i);scanf("%d",&a[i]);
}
}
Trang 74
Lp trình căn bn
void InMang(int a[], int N)
{
int i;
for (i=0; i<N;i++)
printf("%d ",a[i]);
printf("\n");
}
void SapXep(int a[], int N)
{
int t,i;
for(i=0;i<N-1;i++)
for(int j=i+1;j<N;j++)
if (a[i]>a[j])
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
int main()
{
int b[20], N;
printf("So phan tu thuc te cua mang N= ");
scanf("%d",&N);
Nhap(b,N);
printf("Mang vua nhap: ");
InMang(b,N);
SapXep(b,N); /* Gi hàm sp xếp*/
printf("Mang sau khi sap xep: ");
InMang(b,N);
getch();
return 0;
}
Kết qu chy chương trình có th là:
III. MNG NHIU CHIU
Mng nhiu chiu là mng có t 2 chiu tr lên. Điu đó có nghĩa là mi phn
t ca mng là mt mng khác.
Người ta thường s dng mng nhiu chiu để lưu các ma trn, các ta độ 2
chiu, 3 chiu…
Phn dưới đây là các vn đề liên quan đến mng 2 chiu; các mng 3, 4,… chiu thì
tương t (ch cn tng quát hóa lên).
Trang 75
Lp trình căn bn
III.1 Khai báo
III.1.1. Khai báo mng 2 chiu tường minh
Cú pháp:
<Kiu> <Tên mng><[S phn t chiu 1]><[S phn t chiu 2]>
Ví d: Người ta cn lưu tr thông tin ca mt ma trn gm các s thc. Lúc này
ta có th khai báo mt mng 2 chiu như sau:
float m[8][9]; /* Khai báo mng 2 chiu có 8*9 phn t là s thc*/
Trong trường hp này, ta đã khai báo cho mt ma trn có ti đa là 8 dòng, mi
dòng có ti đa là 9 ct. Hình nh ca ma trn này được cho trong hình 2:
Dòng\Ct 0 1 2 3 4 5 6 7 8
0 m[0][0] m[0][1] m[0][2] m[0][3] m[0][4] m[0][5] m[0][6] m[0][7] m[0][8]
1 m[1][0] m[1][1] m[1][2] m[1][3] m[1][4] m[1][5] m[1][6] m[1][7] m[1][8]
2 m[2][0] m[2][1] m[2][2] m[2][3] m[2][4] m[2][5] m[2][6] m[2][7] m[2][8]
3 m[3][0] m[3][1] m[3][2] m[3][3] m[3][4] m[3][5] m[3][6] m[3][7] m[3][8]
4 m[4][0] m[4][1] m[4][2] m[4][3] m[4][4] m[4][5] m[4][6] m[4][7] m[4][8]
5 m[5][0] m[5][1] m[5][2] m[5][3] m[5][4] m[5][5] m[5][6] m[5][7] m[5][8]
6 m[6][0] m[6][1] m[6][2] m[6][3] m[6][4] m[6][5] m[6][6] m[6][7] m[6][8]
7 m[7][0] m[7][1] m[7][2] m[7][3] m[7][4] m[7][5] m[7][6] m[7][7] m[7][8]
Hình 2: Ma trn được mô t là 1 mng 2 chiu
III.1.2. Khai báo mng 2 chiu không tường minh
Để khai báo mng 2 chiu không tường minh, ta vn phi ch ra s phn t ca
chiu th hai (chiu cui cùng).
Cú pháp: <Kiu> <Tên mng> <[]><[S phn t chiu 2]>
Cách khai báo này cũng được áp dng trong trường hp va khai báo, va gán
tr hay đặt mng 2 chiu là tham s hình thc ca hàm.
III.2 Truy xut tng phn t ca mng 2 chiu
Ta có th truy xut mt phn t ca mng hai chiu bng cách viết ra tên mng
theo sau là hai ch s đặt trong hai cp du ngoc vuông. Chng hn ta viết m[2][3].
Vi cách truy xut theo cách này, Tên mng[Ch s 1][Ch s 2] có th coi là 1
biến có kiu được ch ra trong khai báo biến mng.
Ví d 1: Viết chương trình cho phép nhp 2 ma trn a, b có m dòng n ct, thc
hin phép toán cng hai ma trn a,b và in ma trn kết qu lên màn hình.
Trong ví d này, ta s s dng hàm để làm ngn gn hơn chương trình ca ta.
Ta s viết các hàm: nhp 1 ma trn t bàn phím, hin th ma trn lên màn hình, cng 2
ma trn.
#include<conio.h>
#include<stdio.h>
void Nhap(int a[][10],int M,int N)
{
int i,j;
for(i=0;i<M;i++)
Trang 76