Lập trình cơ bản:
Ngơn ngữ lập trình C
Đỗ Thị Mai Hường
Bộ môn Hệ thống thông tin
Khoa Công nghệ thông tin
Mảng, con trỏ và xâu ký
tự
Tài liệu tham khảo
• Kỹ thuật lập trình C: cơ sở và nâng cao, Phạm
Văn Ất, Nhà xuất bản KHKT – Chương 6
• The C programming language 2nd Edition,
Brian Kernighan and Dennis Ritchie, Prentice
Hall Software Series – Chương 4
• The C programming language 2nd Edition,
Brian Kernighan and Dennis Ritchie, Prentice
3
Hall Software Series – Chương
5
Chương 7 - Phần 1
Nội dung
•
Mảng một chiều
•
Mảng hai chiều
•
Con trỏ và phép tốn trên con trỏ
– Khai báo con trỏ
– Phép gán con trỏ
– Truy xuất giá trị qua con trỏ
•
Con trỏ và mảng
•
Cấp phát vùng nhớ cho con trỏ
•
Xâu ký tự
– Khái niệm
– Khởi tạo
– Các thao tác trên xâu ký tự
4
Chương 7 - Phần 1
PHẦN 1. MẢNG MỘT CHIỀU VÀ
NHIỀU CHIỀU
5
Mảng một chiều
• Khái niệm
• Khai báo
• Truy xuất dữ liệu
6
Dữ liệu kiểu mảng
• Khái niệm
– Là một kiểu dữ liệu có cấu trúc do người lập
trình định nghĩa.
– Biểu diễn một dãy các biến có cùng kiểu. Ví dụ:
dãy các số nguyên, dãy các ký tự…
– Kích thước được xác định ngay khi khai báo
và không bao giờ thay đổi.
– NNLT C luôn chỉ định một khối nhớ liên tục
cho một biến kiểu mảng.
7
Khai báo biến mảng (tường
minh)
• Tường minh
<kiểu cơ sở> <tên biến mảng>[<số phần tử>];
<kiểu cơ sở> <tên biến mảng>[<N1>][<N2>]…[<Nn>];
– <N1>, …, <Nn> : số lượng phần tử của mỗi chiều.
• Lưu ý
– Phải xác định <số phần tử> cụ thể (hằng) khi khai
báo.
– Mảng nhiều chiều: <tổng số phần tử> =
N1*N2*…*Nn
8
– Bộ nhớ sử dụng = <tổng số phần tử>*sizeof(
Khai báo biến mảng (tường
minh)
• Ví dụ
int Mang1Chieu[10];
0
1
2
3
4
5
6
7
8
9
3
4
5
6
7
8
9
Mang1Chieu
int Mang2Chieu[3][4];
0
Mang2Chieu 0
1
2
9
1
2
10 11
Khai báo biến mảng (khơng
tường minh)
• Cú pháp
– Khơng tường minh (thông qua khai báo kiểu)
typedef <kiểu cơ sở> <tên kiểu mảng>[<số phần tử>];
typedef <kiểu cơ sở> <tên kiểu mảng>[<N1>]…[<Nn>];
<tên kiểu mảng> <tên biến mảng>;
typedef int Mang1Chieu[10];
typedef int Mang2Chieu[3][4];
• Ví dụ
Mang1Chieu m1, m2, m3;
Mang2Chieu m4, m5;
10
Chương 7 - Phần 1
Số phần tử của mảng
• Phải xác định cụ thể số phần tử ngay lúc
khai báo, không được sử dụng biến hoặc
int n1 = 10; int a[n1];
const int n2 = 20; int b[n2];
hằng thường
#define n1 10
#define n2 20
int a[n1];
int b[n1][n2];
// int a[10];
// int b[10][20];
• 11Nên sử dụng chỉ thị tiền xử lý #define để
Khởi tạo giá trị cho mảng lúc
khai báo
• Gồm các cách sau
– Khởi tạo giá trị cho mọi phần tử của mảng
int a[4] = {2912, 1706, 1506, 1904};
a
0
1
2
3
2912
1706
1506
1904
int a[4] = {2912, 1706};
2 phần
3 tử đầu mảng
– Khởi tạo giá 0trị cho1 một số
a
12
2912
1706
0
0
Khởi tạo giá trị cho mảng lúc
khai báo
• Gồm các cách sau
– Khởi tạo giá trị 0 cho mọi phần tử của mảng
int a[4] = {0};
a
0
1
2
3
0
0
0
0
– Tự động xác định số lượng phần tử
int a[] = {2912, 1706, 1506, 1904};
a
13
0
1
2
3
2912
1706
1506
1904
Truy xuất đến một phần tử
• Thơng qua chỉ số
<tên biến mảng>[<gt cs1>][<gt cs2>]…[<gt csn>]
• Ví dụ
– Cho mảng như sau
0
1
2
3
int a[4];
– Các truy xuất
• Hợp lệ: a[0], a[1], a[2], a[3]
• Khơng hợp lệ: a[-1], a[4], a[5], …
14
=> Cho kết thường không như mong muốn!
Gán dữ liệu kiểu mảng
• Khơng được sử dụng phép gán thông
thường mà phải gán trực tiếp giữa các phần
tử tương ứng
#define MAX 3
typedef int MangSo[MAX];
MangSo a = {1, 2, 3}, b;
• Ví dụ
b = a;
// Sai
for (int i = 0; i < 3; i++) b[i] = a[i];
15
Chương 7 - Phần 1
Ví dụ
#include
•1.Nhập
mảng <stdio.h>
có n phần tử kiểu ngun, in ra các phần
2. #define MAX 1000
3.tử void
main()
của mảng
4. {
int ary[MAX];
5.
int i,n;
6.
printf(“Nhap n = ”);
7.
scanf(“%d”,&n);
8.
for(i=0; i
{
9.
printf(“\n Enter value: %d : ”, i+1);
10.
scanf(“%d”,&ary[i]);
11.
}
12.
for(i=1; i<10; i++) printf(“a[%d]=%d\n“,i,
13.
ary[i])
14. }
16
Ví dụ
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
#include <stdio.h>
#define MAX 1000
void main()
{
int ary1[MAX], ary2[MAX], sum[MAX];
int i,n;
printf(“Nhap n = ”);scanf(“%d”,&n);
for(i=0; i
{
printf(“\n Enter value: %d : ”, i+1);
scanf(“%d”,&ary1[i]);
}
for(i=0; i
{
printf(“\n Enter value: %d : ”, i+1);
scanf(“%d”,&ary2[i]);
}
for(i=1; i<10; i++)sum[i]=ary1[i]+ary2[i];
for(i=1; i<10; i++) printf(“a[%d]=%d\n“,i, sum[i])
}
• Nhập 2 mảng có n phần tử kiểu nguyên, tính và in ra
mảng tổng
17
Mảng hai chiều
• Khái niệm
• Khai báo
• Truy xuất dữ liệu
18
Ma Trận
0
1
… n-1
0
0
m-1
19
An
…
…
Am,n
0
n-1
… n-1
Ma Trận
0
… n-1
0
0
… n-1
0
…
…
n-1
n-1
dòng = cột
dòng > cột
dòng < cột
0
0
0
… n-1
… n-1
0
… n-1
0
…
…
…
n-1
n-1
n-1
dòng + cột = n-1
20
0
n-1
0
An
… n-1
…
An
0
dòng + cột > n-1
dòng + cột < n-1
Khai báo biến mảng 2 chiều
• Cú pháp
– Tường minh
<kiểu cơ sở> <tên biến>[<N1>][<N2>];
typedef
cơ minh
sở>
kiểu>[<N1>][<N2>];
– Không
tường
(thông
qua kiểu)
<tên kiểu> <tên biến>;
<tên kiểu> <tên biến 1>, <tên biến 2>;
21
Khai báo biến mảng 2 chiều
• Ví dụ
– Tường minh
int a[10][20], b[10][20];
int c[5][10];
int d[10][20];
– Không tường minh (thông qua kiểu)
typedef int MaTran10x20[10][20];
typedef int MaTran5x10[5][10];
MaTran10x20 a, b;
MaTran11x11 c;
MaTran10x20 d;
22
Truy xuất đến một phần tử
• Thơng qua chỉ số
<tên biến mảng>[<giá trị cs1>][<giá trị cs2>]
0
• Ví dụ
1
0
1
int a[3][4];
– Cho mảng 2 chiều như sau
2
– Các truy xuất
• Hợp lệ: a[0][0], a[0][1], …, a[2][2], a[2][3]
23
• Khơng hợp lệ: a[-1][0], a[2][4], a[3][3]
2
3
Gán dữ liệu kiểu mảng
• Khơng được sử dụng phép gán thông thường
mà phải gán trực tiếp giữa các phần tử
int a[5][10], b[5][10];
• Ví
dụ
b = a;
// Sai
int i, j;
for (i = 0; i < 5; i++)
for (j = 0; j < 10; j++)
b[i][j] = a[i][j];
24
Ví dụ
•
Nhập mảng có n dịng, m cột các phần tử kiểu nguyên, in các phần tử
1. #include <stdio.h>
của mảng ra màn hình
2. #define MAX 1000
3. void main()
4. {
5.
int a[MAX][MAX];
6.
int i,n,m;
7.
//Nhap mang
8.
printf(“Nhap n = ”);scanf(“%d”,&n);
9.
printf(“Nhap m = ”);scanf(“%d”,&m);
10.
for (i=0; i
11.
for (j=0; j
12.
{
13.
printf(“Nhap a[%d][%d]: ”, i, j);
14.
scanf(“%d”, &a[i][j]);
15.
}
25