1. Trang chủ
  2. » Công Nghệ Thông Tin

Bài giảng Ngôn ngữ lập trình C: Mảng một chiều, chuỗi - TS. Ngô Hữu Dũng

70 9 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Ngôn ngữ lập trình C: Mảng một chiều, chuỗi
Trường học Trường Đại Học Công Nghiệp Thành Phố Hồ Chí Minh
Thể loại Bài giảng
Thành phố Thành phố Hồ Chí Minh
Định dạng
Số trang 70
Dung lượng 1,49 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Bài giảng Ngôn ngữ lập trình C: Mảng một chiều, chuỗi cung cấp cho người học các kiến thức: Dữ liệu kiểu mảng, khai báo biến mảng, số phần tử của mảng, truy xuất đến một phần tử, truyền mảng cho hàm,... Mời các bạn cùng tham khảo nội dung chi tiết.

Trang 1

Ngôn ngữ lập trình C

Mảng một chiều, chuỗi

TRƯỜNG ĐẠI HỌC CÔNG NGHIỆP THÀNH PHỐ HỒ CHÍ MINH

Trang 2

Đặt vấn đề

 Chương trình cần lưu trữ 3 số nguyên?

=> Khai báo 3 biến int a1, a2, a3;

 Chương trình cần lưu trữ 100 số nguyên?

=> Khai báo 100 biến kiểu số nguyên!

 Người dùng muốn nhập n số nguyên?

=> Không thực hiện được!

 Kiểu dữ liệu mới cho phép lưu trữ một dãy các số nguyên và dễ dàng truy xuất

Trang 3

Dữ liệu kiểu mảng

 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ố

Trang 4

Khai báo biến mảng (tường minh)

 Bộ nhớ sử dụng = <tổng số phần tử>* sizeof (<kiểu cơ sở>)

 Bộ nhớ sử dụng phải ít hơn 64KB (65535 Bytes)

 Một dãy liên tục có chỉ số từ 0 đến <tổng số phần tử>-1

<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> ] ;

Trang 5

0 1 2

Khai báo biến mảng (tường minh)

Trang 6

Khai báo biến mảng (kô tường minh)

<tên kiểu mảng> <tên biến mảng>;

typedef int Mang1Chieu [ 10 ] ;

typedef int Mang2Chieu [ 3 ][ 4 ] ;

Mang1Chieu m1, m2, m3;

Trang 8

Khởi tạo giá trị cho mảng lúc khai báo

 Khởi tạo giá trị cho mọi phần tử của mảng

 Khởi tạo giá trị cho một số phần tử đầu mảng

Trang 9

Khởi tạo giá trị cho mảng lúc khai báo

Trang 10

 Hợp lệ: a[0], a[1], a[2], a[3]

 Không hợp lệ: a[-1], a[4], a[5], …

=> Cho kết thường không như mong muốn!

<tên biến mảng> [ <gt cs1> ][ <gt cs2> ] … [ <gt csn> ]

int a[4];

0 1 2 3

Trang 11

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

<biến mảng đích> = <biến mảng nguồn>; //sai

<biến mảng đích>[<chỉ số thứ i>] = <giá trị>;

Trang 12

Một số lỗi thường gặp

 Khai báo không chỉ rõ số lượng phần tử

 int a [] ; => int a[100];

 Số lượng phần tử liên quan đến biến hoặc hằng

 int n1 = 10; int a[ n1 ]; => int a[10];

 const int n2 = 10; int a[ n2 ]; => int a[10];

 Khởi tạo cách biệt với khai báo

Trang 13

 Có thể bỏ số lượng phần tử hoặc sử dụng con trỏ.

 Mảng có thể thay đổi nội dung sau khi thực hiện hàm

void SapXepTang( int a[100] );

void SapXepTang( int a[] );

void SapXepTang( int *a );

Trang 14

void SapXepTang(int *a, int n );

void NhapMang(int a[], int &n);

void XuatMang(int a[], int n);

Trang 15

Một số bài toán cơ bản

Trang 17

Thủ tục HoanVi & Hàm LaSNT

1 void HoanVi (int &x, int &y){

2 int tam = x; x = y; y = tam;

Trang 21

Hàm Xuất Mảng

1 void XuatMang (int a[], int n)

2 {

3 printf(“Noi dung cua mang la: ”);

4 for (int i = 0 ; i < n ; i++ )

6 printf(“\n”);

7 }

Trang 22

Tìm kiếm một phần tử trong mảng

 Tìm xem phần tử x có nằm trong mảng a kích thước n hay

không? Nếu có thì nó nằm ở vị trí đầu tiên nào.

 Xét từng phần của mảng a Nếu phần tử đang xét bằng x thì trả

về vị trí đó Nếu kô tìm được thì trả về -1

Trang 25

Kiểm tra tính chất của mảng

 Cho trước mảng a , số lượng phần tử n Mảng a có phải là

mảng toàn các số nguyên tố hay không?

Trang 29

Tách các phần tử thỏa điều kiện

Trang 31

 Cách 1: viết 1 hàm tách các số nguyên tố từ mảng a sang

mảng b và 1 hàm tách các số không phải nguyên tố từ mảng

a sang mảng c.

 Cách 2: Duyệt từ phần tử của mảng a, nếu đó là số nguyên tố thì đưa vào mảng b , ngược lại đưa vào mảng c

Trang 32

Hàm Tách 2 Mảng

1 void TachSNT2 (int a[], int na,

2 int b[], int &nb, int c[], int &nc)

Trang 33

Gộp 2 mảng thành một mảng

 Cho trước mảng a , số lượng phần tử na và mảng b số lượng phần tử nb Gộp 2 mảng trên theo tứ tự đó thành mảng c , số lượng phần tử nc

Trang 34

Hàm Gộp Mảng

1 void GopMang (int a[], int na, int b[], int nb,

Trang 35

 Giả sử giá trị max hiện tại là giá trị phần tử đầu tiên a[0]

 Lần lượt kiểm tra các phần tử còn lại để cập nhật max

Trang 36

Hàm tìm Max

1 int TimMax (int a[], int n)

2 {

3 int max = a[0];

4 for (int i = 1; i < n; i++)

8 }

Trang 39

Thêm một phần tử vào mảng

 Thêm phần tử x vào mảng a kích thước n tại vị trí vt

 “Đẩy” các phần tử bắt đầu tại vị trí vt sang phải 1 vị trí

 Đưa x vào vị trí vt trong mảng.

 Tăng n lên 1 đơn vị

Trang 41

Xóa một phần tử trong mảng

 Xóa một phần tử trong mảng a kích thước n tại vị trí vt

 “Kéo” các phần tử bên phải vị trí vt sang trái 1 vị trí

 Giảm n xuống 1 đơn vị

Trang 44

a. Vị trí cuối cùng của phần tử x trong mảng

b. Vị trí số nguyên tố đầu tiên trong mảng nếu có

c. Tìm số nhỏ nhất trong mảng

d. Tìm số dương nhỏ nhất trong mảng

Trang 45

Bài tập thực hành

a. Tách các số nguyên tố có trong mảng a đưa vào mảng b.

b. Tách mảng a thành 2 mảng b (chứa các số nguyên dương) và

c (chứa các số còn lại)

c. Sắp xếp mảng giảm dần

d. Sắp xếp mảng sao cho các số dương đứng đầu mảng giảm

dần, kế đến là các số âm tăng dần, cuối cùng là các số 0.

Trang 46

Bài tập thực hành

a. Sửa các số nguyên tố có trong mảng thành số 0

b. Chèn số 0 đằng sau các số nguyên tố trong mảng

c. Xóa tất cả số nguyên tố có trong mảng

Trang 47

Ngôn ngữ lập trình C

Chuỗi ký tự

Trang 48

Khái niệm Chuỗi

 Mảng kiểu ký tự

char word [] = { 'H' , 'e' , 'l' , 'l' , 'o' , '!' };

 Chuỗi ký tự

char word [] = { 'H' , 'e' , 'l' , 'l' , 'o' , '!' , '\0' };

char word [] = "Hello!" ;

 Chuỗi ký tự bao gồm một ký tự đặc biệt nằm cuối chuỗi

 Báo hiệu kết thúc chuỗi

 Được hiểu là ký tự NULL, có thể viết là '\0'

 Một chuỗi, ví dụ "Hello!" , đã bao hàm ký tự kết thúc, tức char[7]

 Kiểu liệt kê, ví dụ { 'H' , 'e' , 'l' , 'l' , 'o' , '!' , '\0' }, tức char[7]

Trang 49

 <Số ký tự> có thể lớn hơn chiều dài của <Chuỗi>

 <Chuỗi> bao gồm các ký tự và ký tự NULL (\0)

 Nếu không khai báo <Số ký tự> (để trống)

 Cần khởi tạo chuỗi ban đầu cho biến

 Kích cỡ của biến chính là chiều dài của chuỗi (gồm ký tự NULL)

 <Chuỗi> khởi tạo hợp lệ?

 nằm giữa dấu hai nháy “”

 liệt kê {} các ký tự bao gồm ký tự NULL, ‘\0’, ở cuối cùng

Trang 50

Ví dụ khai báo

1 char hello[] = "Hello!" ; // char[7]

2 char hi[] = { 'H' , 'i' , '!' , '\0' }; // char[4]

8 char country[] = { 'V' , 'N' }; // Array, not string!

9 char gender[2] = "male" ; // Error!? Overflow

10 char classroom = "V10.4" ; // Error!? Char vs string

11 char university[] = 'IUH' ; // Error!? Char vs string

Trang 51

Khởi tạo giá trị

 Một khởi tạo giá trị: char hello[] = "Hello!" ;

char hello[] = { 'H' , 'e' , 'l' , 'l' , 'o' , '!' , '\0' };

char hello[7] = { 'H' , 'e' , 'l' , 'l' , 'o' , '!' , '\0' };

char hello[7] = "Hello!" ;

 Một khởi tạo giá trị: char empty[] = "" ;

char empty[] = { '\0' };

char empty[1] = { '\0' };

char empty[1] = "" ;

Trang 52

Khởi tạo giá trị (2)

 Một khởi tạo giá trị:

char hi[7] = "Hi!" ;

char hi[7] = { 'H' , 'i' , '!' , '\0' };

 Khởi tạo một chuỗi rất dài, dùng dấu \ để xuống dòng

char longstring[] = "Toi la sinh vien Cong nghe Thong

\

tin\nTruong Dai hoc Cong Nghiep TP HCM.\n\

Than chao cac ban!" ;

char longstring[] = "Toi la sinh vien Cong nghe Thong

"

"tin\nTruong Dai hoc Cong Nghiep TP HCM.\n"

"Than chao cac ban!" ;

'H' 'i' '!' '\0'

Trang 53

Phép gán

 Các phép gán trực tiếp cho chuỗi bị hạn chế

Bởi trình biên dịch xử lý với chuỗi như mảng

 Một khai báo

char name[10];

name = "Quang" ; // Error!

 const char[6] không gán được cho char[10]

name = hello; // Error!

 char[7] không gán được cho char[10]

 Làm thế nào để thay đổi giá trị của chuỗi?

 Dùng các hàm xử lý chuỗi như scanf, gets

 Thay đổi từng phần tử

Các hàm trong thư viện string.h

 Tự viết hàm xử lý chuỗi ký tự

Trang 54

 Nhập "My name is C", name = "My name is C"

 scanf tự động thêm ký tự NULL vào sau chuỗi nhận được từ bàn phím

Dùng hàm gets trong thư viện stdio.h

gets(name);

 Hàm gets tự động chấp nhận chuỗi có khoảng trắng

Trang 55

Phần tử của chuỗi

 Phép khởi tạo char hello[] = "Hello!" ;

 hello[0] = 'H', hello[1] = 'e', hello[2] = 'l',… hello[6] = '\0'

Phép gán sau đó hello = "Hi!" ; sẽ bị báo lỗi!

Xuất chuỗi: printf( "%s" , hello);

printf( "%s" , "e" ); // "e"= { ' e ', ' \0 ' }

Xuất ký tự: printf( "%c" , hello[1]);

printf( "%c" , ' e ' );

hello[0] hello[1] hello[2] hello[3] hello[4] hello[5] hello[6] 'H' 'e' 'l' 'l' 'o' '!' '\0'

Trang 56

Thư viện string.h

size_t strlen(const char * str)

Trả về chiều dài của chuỗi ký tự str

 strlen(“hello”) = 5, strlen(hello) = 6

 size_t: Unsigned integral type

const char: Bởi hàm không thay đổi giá trị của str

char * strcpy(char * destination, const char * source)

Chép nội dung chuỗi source sang chuỗi destination bao gồm ký tự

NULL

Chuỗi destination phải đủ chứa chuỗi source (bao gồm ký tự NULL)

 Bản thân hàm trả về destination

strcpy(hello, “Hi!”) trả về chuỗi “Hi!” và hello = “Hi!”

 char * destination: Hàm thay đổi giá trị của destination

 const char * source: Hàm không thay đổi giá trị của source

Trang 57

Thư viện string.h (2)

int strcmp( const char * str1, const char * str2 )

So sánh chuỗi str1 với chuỗi str2, so sánh từng ký tự từ đầu đến

khi phát hiện điểm khác nhau hoặc đến cuối chuỗi (‘\0’)

 Giá trị trả về >0: str1 > str2

 Giá trị trả về =0: str1 = str2

 Giá trị trả về <0: str1 < str2

char * strcat( char * destination, const char * source )

Nối chuỗi source vào cuối chuỗi destination

destination phải đủ chứa chuỗi kết quả (bao gồm ký tự NULL)

char name[10]; strcpy(name, hello); strcat(name, hi); // name =

“Hello!Hi!”

Trang 58

Thư viện string.h (6)

char * strtok( char * str, const char * delimiters): Chia chuỗi

void * memset( void * ptr, int value, size_t num): Điền giá trị

value vào num bytes ô nhớ đầu tiên của biến ptr

 memset(hello,'2',2); // hello = “22llo!”

void * memcpy( void * destination, const void * source, size_t

num ): Chép num ô nhớ đầu tiên của biến source vào biến

destination

 memcpy(hello,hi,3);// hello = “Hi!lo!”

Trang 59

Chuyển đổi giữa chuỗi và số

Thư viện <stdlib.h> chứa các hàm chuyển đổi giữa chuỗi và số

 int atoi (const char * str)

Chuyển chuỗi str sang số nguyên và trả về giá trị số nguyên

 atoi("34.5 53") = 34

 double atof (const char* str)

 Chuyển đổi một chuỗi sang kiểu số thực và trả về số thực

 atof("34.5 53") = 34.5

 long int atol ( const char * str )

 Chuyển đổi chuỗi sang kiểu long int (4 bytes)

 long long int atoll ( const char * str )

 Chuyển đổi chuỗi sang kiểu long long int (8 bytes)

Trang 60

Chiều dài của chuỗi

 Chiều dài của chuỗi được xác định dựa vào ký tự NULL, kết thúc chuỗi

 Viết hàm tính chiều dài của chuỗi

 Hàm có kiểu nguyên, trả về chiều dài của chuỗi (output)

 Đối số của hàm là một chuỗi (input)

 Mã giả:

 Khai báo một biến đếm và khởi tạo giá trị 0

 Duyệt và đếm các phần tử của chuỗi

 Dừng đếm khi gặp ký tự ‘\0’

 Trả về chiều dài của chuỗi dựa vào giá trị của biến đếm

 Tương tự hàm strlen của thư viện string.h

Trang 61

Ví dụ tham khảo hàm tính chiều dài của chuỗi

1. int stringLength( const char str[])

Trang 62

Chép chuỗi

 Viết hàm chép nội dung của một chuỗi nguồn vào một chuỗi đích

 Chuỗi đích sẽ mang giá trị của chuỗi nguồn (output)

 Đối số của hàm là hai chuỗi, nguồn và đích (input)

 Mã giả

 Khai báo một biến chạy và khởi gán giá trị ban đầu

 Duyệt từng phần tử của chuỗi nguồn

 Gán giá trị của từng phần tử ở chuỗi nguồn sang chuỗi đích

 Dừng sao chép khi gặp ký tự ‘\0’

 Gán ký tự ‘\0’ vào cuối chuỗi đích

 Tương tự lệnh strcpy của thư viện string.h

 Hàm có kiểu trả về là void

 Bạn có thể trả về chuỗi đích cho hàm nếu biết dùng con trỏ, pointer (sẽ học sau)

Trang 63

Ví dụ tham khảo hàm chép chuỗi

1 void stringCopy( char str1[], const char str2[])

Trang 64

Nối chuỗi

 Viết hàm nối một chuỗi nguồn vào cuối một chuỗi đích

 Chuỗi đích sẽ mang giá trị là kết quả của việc nối hai chuỗi

 Đối số của hàm gồm hai chuỗi

 Mã giả

 Khai báo hai biến chạy và khởi gán giá trị ban đầu

 Biến chạy cho chuỗi nguồn, bắt đầu từ đầu chuỗi nguồn

 Biến chạy cho chuỗi đích, bắt đầu từ cuối chuỗi đích

 Duyệt từng phần tử của chuỗi nguồn

 Gán giá trị của các phần tử của chuỗi nguồn vào chuỗi đích

 Dừng sao chép khi gặp ký tự NULL của chuỗi nguồn

 Gán ký tự NULL vào chuỗi đích

 Hàm tương tự như hàm strcpy trong thư viện string.h

Trang 65

Ví dụ tham khảo hàm nối chuỗi

1 void stringAppend( char dest[], const char src[])

Trang 66

 Khai báo và khởi tạo cho một biến chạy

 Duyệt các phần tử cho đến khi

 Gặp phần tử khác nhau

 Hoặc kết thúc một trong hai chuỗi

 So sánh phần tử cuối cùng và trả về giá trị so sánh tương ứng

Trang 67

Ví dụ tham khảo về hàm so sánh chuỗi

1. int stringCompare(const char str1[], const char

str2[])

2. {

3. int i = 0;

4. while(str1[i]==str2[i]&&str1[i]!= '\0' &&str2[i]!= '\0 ' )

Trang 68

Tìm kiếm

 Viết hàm tìm kiếm vị trí của một chuỗi nguồn trong chuỗi đích

 Hàm trả về số nguyên là vị trí đầu tiên tìm thấy

 Hàm trả về số âm nếu không tìm thấy

 Đối số của hàm là hai chuỗi

Trang 69

Ví dụ tham khảo về tìm kiếm chuỗi

Trang 70

 Khái niệm chuỗi

 Khai báo, khởi tạo

 Phần tử của chuỗi

 Thư viện string.h

 Thư viện stdlib.h

 Một vài bài toán về

chuỗi

 Bài tập về nhà

 Nhập vào họ và tên, đếm số ký tự alphabet

 Ví dụ: Nhập “Tran Van An ”, xuất ra có 9 ký tự

 Nhập vào một số, xuất ra chữ viết của số đó

 Ví dụ: Nhập 456, xuất ra: Bon tram nam muoi sau

Ngày đăng: 11/05/2021, 03:34

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm