Bài giảng C căn bản - Chương 1: Kỹ thuật xử lý Mảng và Con trỏ

Mảng (array) là một dãy các phần tử có cùng kiểu dữ liệu được đặt liên tiếp trong bộ nhớ.

Mỗi phần tử được xác định bởi một chỉ số biểu thị vị trí của phần tử trong mảng.

Số lượng phần tử trong mảng được gọi là kích thước của mảng.

Kích thước của mảng là cố định và phải được xác định trước.

 

ppt40 trang | Chuyên mục: C/C++ | Chia sẻ: tuando | Lượt xem: 416 | Lượt tải: 0download
Tóm tắt nội dung Bài giảng C căn bản - Chương 1: Kỹ thuật xử lý Mảng và Con trỏ, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
g 
	 long TongUocSo(int n) 
{	 
	long S;	 int i; 
	S = 0; 
	for (i = 1; i <n; i++) 
	 if(n%i ==0) 
	S = S + i; 
	return S; 
	} 
7 
1.1. Khái niệm Mảng 
	long TichUocSo(int n) 
	{	long P;	 int i; 
	P = 1; 
	for (i = 1; i <n; i++) 
	 if(n%i ==0) 
	P = P * i; 
	return P; 
	} 
	 int SoHoanChinh(int n) 
	{ 
	return ( TongUocSo(n )== TichUocSo(n )); 
	} 
8 
1.1. Khái niệm Mảng 
	Đếm các số a[1], a[2], , a[n] thõa điều kiện 
	 count = 0; 
	 Lặp i = 1, 2, 3, , n 
	 Nếu a[i ] thõa điều kiện thì 
	Count = count + 1; 
	 Cuối lặp . 
Ví dụ : Đếm số phần tử dương , số phần tử âm , số phần tử bằng 0 trong mảng số nguyên a có n phần tử . 
9 
1.1. Khái niệm Mảng 
void	 Demso(int a[], int n, int & demduong , int&demam , int & demkhong ) 
	{	int i; 
	demduong =0;	demam = 0;	demkhong = 0; 
	for (i = 0; i < n; i++) 
	 { 
	if ( a[i ]>0)	( demduong )++; 
	if ( a[i ]<0)	( demam )++; 
	 if(a[i ]==0)	( demkhong )++; 
	} 
	} 
10 
1.1. Khái niệm Mảng 
Tìm phần tử đầu tiên trong mảng a thõa điều kiện 
	j = -1, i = 1; 
	 Lặp ( trong khi (i<=n) và (j = -1)) 
	 Nếu a[i] thõa điều kiện thì 
	 	j = i; 
	 	Cuối nếu. 
	 	i = i+1; 
	 Cuối lặp. 
Ví dụ : Tìm phần tử âm đầu tiên trong mảng a mà có tận cùng bằng 6. 
11 
1.1. Khái niệm Mảng 
int	AmTanCung6(int a[], int n) 
	 { 
	 	i = 0; 
	 j = -1; 
	 while (i < n && j ==-1) 
	 { 
	 if(a[i]<0 && -a[i] %10 ==6) 
	 j = i; 
	 i++; 
	 } 
	 re turn j; 
	} 
12 
1.1. Khái niệm Mảng 
	 Tìm tất cả các phần tử mảng a thõa điều kiện 
	m = 0; 
	 Lặp i = 1, 2, 3, , n 
	 Nếu ( a[i ] thõa điều kiện thì ) 
	 b[m] = a[i]; 
	 	m = m + 1; 
	 	Cuối nếu. 
	 Cuối lặp. 
Ví dụ: Tìm tất cả các phần tử chỉ xuất hiện một lần trong mảng số nguyên a, n phần tử. 
13 
1.1. Khái niệm Mảng 
int Dem(int a[], int n, int x) 
	 { 
	 	 int i, kq = 0; 
	for(i = 0; i < n ; i++) 
	if(a[i] == x) 
	kq = kq + 1; 
	return kq; 
	 } 
14 
1.1. Khái niệm Mảng 
void XuatHien01Lan(int a[], int n, int b[], int&m ) 
	{ 
	m = 0; 
	 for(i = 0; i < n; i++) 
	if(Dem(a, n, a[i]) == 1) 
	{ 
	b[m] = a[i] 
	m = m + 1; 
	} 
	} 
15 
1.1. Khái niệm Mảng 
Tìm phần tử lớn nhất, nhỏ nhất 
	Bước 1: Chọn một phần tử xo và gán min := xo 
	Bước 2: Lặp (cho đến khi chọn hết các phần tử của S) 
	Chọn phần tử kế tiếp x, nếu min > x thì gán min := x; 
	Ví dụ: Hãy tìm phần tử âm lớn nhất có tận cùng là 6 trong mảng a 
16 
1.1. Khái niệm Mảng 
void	MaxAmTanCung6 ( int a[], int n) 
	{	int i, j; 
	int max; 
	 j = AmTanCung6(a, n); 
	if (j ==-1) return 0; 
	 else 
	{ 
	max = a[j]; 
	for (i = j+1; i < n; i++) 
	 if(a[i ]<0&&(-a[i]%10==6)) 
	if (max < a[i ]) 
	max = a[i ];	 
	} 
	return max; 
	} 
17 
1.1. Khái niệm Mảng 
Sắp xếp mảng thõa một điều kiện ( giữ nguyên vị trí các phần tử khác ) 
	 Lặp i = 1, 2, , n -1 
	 Lặp j = i +1, i + 2, , n 
	 Nếu ( a[i ], a[j ] thõa điều kiện ) thì 
	 Nếu a[i ] > a[j ] thì 
	 x = a[i]; 
	 	a[i] = a[j]; 
	 	a[j]= x; 
	 	Cuối nếu. 
	 	Cuối lặp j. 
	 Cuối lặp i. 
18 
1.2. Mảng hai chiều 
Khai báo mảng 2 chiều kiểu int gồm 10 dòng , 10 cột : int A[10][10]; 
Khai báo mảng 2 chiều kiểu float gồm 10 dòng , 10 cột : float b[10][10]; 
	 int A[3][4] = { {2,3,9,4} , {5,6,7,6} , {2,9,4,7} }; 
	A[0][0] = 2; A[0][1] = 3; 
	A[1][1] = 6; A[1][3] = 6; 
Khi nhập liệu cho mảng hai chiều , nếu là mảng các số nguyên thì ta nhập liệu theo cách thông thường . Nhưng nếu là mảng các số thực thì ta phải thông qua biến trung gian . 
19 
1.2. Mảng hai chiều 
Duyệt các phần tử của mảng . 
	// Duyệt từng dòng từ trên xuống dưới . 
	 for(i = 0; i< so_dong ; i++) 
	 for(j = 0; j < so_cot ; j++) 
	{ 
	// Xử lý a[i][j ]; 
	} 
	// Duyệt từng cột từ trái qua phải 
	 for(j = 0; j < so_cot ; j++) 
	 for(i = 0; i< so_dong ; i++) 
	{ 
	// Xử lý a[i][j ]; 
	} 
20 
1.2. Mảng hai chiều 
Duyệt các phần tử nằm trên cùng một dòng hay trên cùng một cột . 
	// Duyệt các phần tử trên dòng thứ k (0 <=k < so_dong ) 
	for (i = 0; i < so_cot ; i++) 
	{ 
	// Xử lý phần tử a[k][i ]; 
	} 
	// Duyệt các phần tử trên cột thứ k (0 <=k < so_cot ) 
	for (i = 0; i < so_dong ; i++) 
	{ 
	// Xử lý phần tử a[i][k ]; 
	} 
21 
1.2. Mảng hai chiều 
Duyệt các phần tử trên đường chéo của ma trận vuông 
	// Duyệt các phần tử trên đường chéo chính . 
	for (i = 0; i < n; i++) 
	 {	 
	 // Xử lý phần tử a[i][i]; 
	 } 
	// Duyệt các phần tử trên đường chéo phụ . 
	for (i = 0; i < n; i++) 
	{ 
	// Xử lý phần tử a[n-1-i][i]; 
	} 
22 
1.3. Con trỏ 
Ta xét dòng khai báo sau : 
int *p; 
Dòng này cho bi ết bi ến p đư ợc khai báo là m ột con trỏ ki ểu int , đ ịa chỉ c ủa ki ểu dữ li ệu số nguyên . D ấu * không ph ải là m ột ph ần c ủa bi ến p, int * có nghĩa là con trỏ ki ểu int. 
Cú pháp khai báo như sau  : *  ; 
23 
Địa chỉ & ô nhớ 
Bộ nhớ 
Địa chỉ ô nhớ 
0xA00h 
ĐỊA CHỈ Ô NHỚ DÙNG ĐỂ QUẢN LÝ Ô NHỚ TRONG BỘ NHỚ. 
0xA01h 
0xAFFh 
. 
. 
24 
POINTER 
int x; 
int *p; 
p 
0xA04h 
x = 5; 
p = 0xA04h; 
p = &x; 
Dùng biến con trỏ (pointer) để lưu giữ các giá trị địa chỉ . 
x 
5 
p = &x; 
Khai báo : * ; 
Ví dụ :	 int * p; 
25 
POINTER 
*p = *p + 2; 
*p = 
x = 
x = 6 
*p = 8 
int x; 
int *p; 
p 
0xA04h 
x = 5; 
p = &x; 
Nếu gán con trỏ p = &x thì : 
6 
5 
6 
*p  x 
*p và biến x cùng sử dụng chung một ô nhớ 
8 
8 
26 
Ví dụ 1 
int main() 
{ 
	 int i; 
	 int j; 
	 int *p; 
	p = &i; 
	*p = 5; 
	j = i; 
	 printf (“%d %d %d ”, i, j, *p); 
	return 0; 
} 
i 
j 
p 
5 5 5 
int i; 
int j; 
int *p; 
p = &i; 
*p = 5; 
5 
5 
j = i; 
printf (“%d %d %d ”, i, j, *p); 
return 0; 
5 
27 
Ví dụ 2 
int main() 
{	 
	 int i; 
	 int *p; 
	 printf(“%d %d \n”, p, &i); 
	p = &i; 
	 printf(“%d % d\n”,p,&i ); 
	return 0; 
} 
i 
0xA06h 
p 
852 2566 
2566 2566 
int i; 
int *p; 
printf(“%d %d \n”, p, &i); 
printf(“%d % d\n”,p,&i ); 
p = &i; 
p = &i; 
return 0; 
28 
Ví dụ 3 
void swap(int *a, int *b) 
{	 
	 int tmp ; 
	 tmp = *a; 
	*a = *b; 
	*b = tmp ; 
} 
int main() 
{	 
	 int a, b; 
	a = 5; 
	b = 10; 
	 swap(&a , &b); 
	 printf(“%d,%d”,a , b); 
	return 0; 
} 
int a, b; 
0xA06h 
0xA08h 
a 
b 
a = 5; 
5 
5 
b = 10; 
10 
10 
swap(&a , &b); 
void swap(int *a, int *b) 
int tmp ; 
tmp 
tmp = *a; 
5 
5 
*a = *b; 
*b = tmp ; 
5 
10 
10 
10 5 
printf(“%d,%d”,a , b); 
0xAA0h 
return 0; 
5 
29 
Ví dụ 4 
void 	 tinh ( int * a, int * b) 
{ 
	(*a) ++; 
	*a = *a + *b; 
	(*b) ++; 
	*b = *b + *a; 
} 
int main() 
{ 
	 int * pa , * pb ; 
	 int x = 10; 
	pa = &x; 
	 pb = &x; 
	 tinh(pa , &x); 
	 printf(“%d%d%d ”, x, *pa, * pb ); 
	 tinh(pa , pb ); 
	x++; 
	 printf(“%d%d%d ”, x, *pa, * pb ); 
	return 0; 
} 
int * pa , * pb ; 
pa 
pb 
int x = 10; 
x 
pa = &x; 
pb = &x; 
tinh(pa , &x); 
void 	 tinh ( int * a, int * b) 
(*a) ++; 
11 
10 
*a = *a + *b; 
22 
(*b) ++; 
23 
*b = *b + *a; 
46 
printf(“%d%d%d ”, x, *pa, * pb ); 
46 46 46 
tinh(pa , pb ); 
void 	 tinh ( int * a, int * b) 
(*a) ++; 
47 
*a = *a + *b; 
94 
(*b) ++; 
95 
*b = *b + *a; 
190 
x++; 
191 
printf(“%d%d%d ”, x, *pa, * pb ); 
191 191 191 
return 0; 
30 
POINTER 
Pointer là một biến mà trỏ đến một ô nhớ . 
int x = 5; 
int *p; 
5 
Pointer lưu trữ địa chỉ bộ nhớ của một ô nhớ . 
p = &x; 
p 
0xA04h 
p = 0xA04h 
*p = 5 
p = &x; 
p = &x; 
31 
array & pointer 
Lưu ý: 
5 
4 
3 
6 
8 
12 
16 
24 
10 
9 
a[0] 
a[1] 
a[2] 
a[6] 
a[3] 
a[7] 
a[4] 
a[8] 
a[5] 
a[9] 
a 
int a[10] ={5, 4, 3, 6, 8, 12, 16, 24, 10, 9}; 
int *pa; 
pa 
pa = a; 
pa + 8; 
pa = pa + 8; 
& a[i ]  (a + i) 
pa + i  & a[i ]	 
pa[i ]  *(pa + i) 
32 
Ví dụ 5 
int main() 
{	 int a[10] ={5, 4, 3, 6, 8, 12, 16, 24, 10, 9}; 
	 int * pa ; 
	 int x; 
	 pa = &a[0]; 
	 x = *pa; 
	 printf(“%d ”, x); 
	pa++;	 
	x = *pa; 
	 printf(“%d ”, x); 
	pa = pa + 5;	 
	x = *pa;	 
	 printf(“%d ”, x);	 
	return 0 ; } 
x 
pa 
int a[10] ={5, 4, 3, 6, 8, 12, 16, 24, 10, 9}; 
int * pa ; 
int x; 
pa = &a[0]; 
x = *pa; 
5 
printf(“%d ”, x); 
5 
pa++; 
x = *pa; 
4 
printf(“%d ”, x); 
4 
pa = pa + 5; 
x = *pa; 
16 
printf(“%d ”, x); 
16 
return 0 ; 
5 
4 
3 
6 
8 
12 
16 
24 
10 
9 
a[0] 
a[1] 
a[2] 
a[6] 
a[3] 
a[7] 
a[4] 
a[8] 
a[5] 
a[9] 
a 
33 
array & pointer 
M ảng không ph ải là m ột bi ến ( ta không thể th ực hi ện a = pa và a++ ) 
5 
4 
3 
6 
8 
12 
16 
24 
10 
9 
a[0] 
a[1] 
a[2] 
a[6] 
a[3] 
a[7] 
a[4] 
a[8] 
a[5] 
a[9] 
a 
pa 
pa = a 
pa = a 
pa++ 
pa++ 
Pointer là m ột bi ến (ta có thể th ực hi ện : pa = a và pa ++) 
34 
MỘT SỐ LƯU Ý 
Ph ải kh ởi t ạo đ ịa chỉ ô nhớ cho con trỏ (pointer) trư ớc khi sử d ụng . 
int * p; 
*p = *p + 2; 
p 
int * p; 
int x = 5; 
p = x; 
p 
Không đư ợc gán m ột giá trị cho con trỏ. 
5 
x 
35 
MỘT SỐ LƯU Ý 
Sử d ụng p++ t ức là con trỏ p tham chi ếu đ ến ô nhớ ti ếp theo . 
int * p; 
 p = &x; 
p 
int * p, *q, *r; 
int x; 
r = p + q; 
p 
Không đư ợc th ực hi ện các phép toán (+, *, /) trên hai con trỏ. 
int x = 2; 
 p ++; 
p = &x;	q = &x; 
Lưu ý: Phép toán trừ hai con trỏ (p – q) v ẫn th ực hi ện đư ợc . 
	K ết quả c ủa : p – q = ? ( Bài t ập ) 
36 
TỔNG KẾT 
Phân bi ệt gi ữa đ ịa chỉ và ô nhớ . 
Cách qu ản lý ô nhớ c ủa con trỏ. 
Toán tử đ ịa chỉ (&) và n ội dung (*). 
Phân bi ệt sự khác nhau gi ữa m ảng và con trỏ. 
Lưu ý m ột số l ỗi khi sử d ụng con trỏ. 
37 
BÀI TẬP 
int * Func () 
{ 
	 int x; 
	 int * p; 
	x = 2; 
	p = &x; 
	return p; 
} 
int main() 
{ 
	 int * q; 
	 q = Func (); 
	 printf(“%d ”, *q); 
	return 0; 
} 
Tìm l ỗi sai c ủa chương trình trên và s ửa l ại cho đúng . 
38 
BÀI TẬP 
int * p; 
int x; 
p = &x; 
Con trỏ p sẽ lưu giữ giá trị đ ịa chỉ c ủa bi ến x. 
Đ ịa chỉ c ủa bi ến con trỏ p là gì ? 
Làm cách nào để qu ản lý đư ợc đ ịa chỉ c ủa bi ến con trỏ p ? 
39 
Q&A 
40 

File đính kèm:

  • pptbai_giang_c_can_ban_chuong_1_ky_thuat_xu_ly_mang_va_con_tro.ppt