ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl...

48
Ts. Bùi Ngọc Thăng Bộ môn KHMT, Trường Đại học CN

Transcript of ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl...

Page 1: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Ts. Bùi Ngọc ThăngBộ môn KHMT, Trường Đại học CN

Page 2: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Nội dung

Khái niệm con trỏ & Khai báo Thao tác: Các toán tử “&”, “*”, “=”, “+” Nhắc lại về truyền tham số địa chỉ Nhắc lại về truyền tham số địa chỉ Con trỏ và mảng Cấp phát vùng nhớ động

Page 3: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Kiến trúc máy tính Bộ nhớ máy tính

Bộ nhớ RAM chứa rất nhiều ô nhớ, mỗi ô nhớ có kíchthước 1 byte.

RAM dùng để chứa một phần hệ điều hành, các lệnh RAM dùng để chứa một phần hệ điều hành, các lệnhchương trình, các dữ liệu…

Mỗi ô nhớ có địa chỉ duy nhất và địa chỉ này được đánhsố từ 0 trở đi.

Ví dụ RAM 512MB được đánh địa chỉ từ 0 đến 229 – 1 RAM 2GB được đánh địa chỉ từ 0 đến 231 – 1

Page 4: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Cấu trúc một CT C/C++ trong bộ nhớ Toàn bộ tập tin chương trình sẽ được nạp vào bộ

nhớ tại vùng nhớ còn trống, gồm 4 phần:

STACKSTACKLastLast--In FirstIn First--OutOut

STACKSTACKLastLast--In FirstIn First--OutOut

LLưưu u đốđối ti tượượng cục bộng cục bộKhi thực hiện hàmKhi thực hiện hàm

Vùng cấp phát tĩnhVùng cấp phát tĩnh(kích th(kích thướước cố c cố địđịnh)nh)

Vùng cấp phát Vùng cấp phát độđộngng(RAM trống và bộ nhớ ảo)(RAM trống và bộ nhớ ảo)

Gồm các lệnh và hằngGồm các lệnh và hằng(kích th(kích thướước cố c cố địđịnh)nh)

Vùng nhớ trốngVùng nhớ trống

HEAPHEAPĐối tĐối tượượng toàn cụcng toàn cục

& tĩnh& tĩnhĐối tĐối tượượng toàn cụcng toàn cục

& tĩnh& tĩnhMã chMã chươương trìnhng trình

Page 5: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Nhắc lại về biến Chúng ta đã biết các biến đều có kích thước, kiểu

dữ liệu xác định (biến tĩnh) chính là các ô nhớ mà chúng ta có thể truy xuất dưới các tên.

Các biến này được lưu trữ tại những chỗ cụ thể Các biến này được lưu trữ tại những chỗ cụ thể trong bộ nhớ, tồn tại trong suốt thời gian thực thi chương trình

Hạn chế của biến tĩnh: Cấp phát ô nhớ dư: Gây lãnh phí Cấp phát ô nhớ thiếu: Lỗi chương trình

Page 6: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Con trỏNgôn ngữ C cung cấp một kiểu biến gọi là con trỏ với những đặc điểm sau:

Chỉ phát sinh trong quá trình thực hiện chương trình Khi chạy chương trình, kích thước của biến, vùng nhớ và

địa chỉ vùng nhớ được cấp phát cho biến có thể thay đổiKhi chạy chương trình, kích thước của biến, vùng nhớ và địa chỉ vùng nhớ được cấp phát cho biến có thể thay đổi

Sau khi thực hiện xong có thể giải phóng để tiết kiệm chỗ trong bộ nhớ

Kích thước của biến con trỏ không phụ thuộc kiểu dữ liệu, nó luôn có kích thước cố định là 4 byte (tùy thuộc HĐH)

Page 7: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Con trỏ – Một số lý do nên sử dụng

Con trỏ là kiểu dữ liệu lưu trữ địa chỉ của các vùng dữ liệu trong bộ nhớ máy tính

Kiểu con trỏ cho phép: Truyền tham số kiểu địa chỉ Truyền tham số kiểu địa chỉ Biểu diễn các kiểu, cấu trúc dữ liệu động Lưu trữ dữ liệu trong vùng nhớ heap

Ví dụ con trỏ đã được sử dụng trong hàm scanf(…)

Page 8: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Con trỏ – Khai báo trong C Con trỏ đơn giản chỉ là địa chỉ của một vị trí bộ nhớ và

cung cấp cách gián tiếp để truy xuất dữ liệu trong bộ nhớ

Tên con trỏTên con trỏ

typetype **pointer_name;pointer_name;

• Kiểu dữ liệu được trỏ tới• Không phải là kiểu của con trỏ

Ý nghĩa: Khai báo một biến có tên là Khai báo một biến có tên là pointer_namepointer_name dùng để chứa địa chỉ dùng để chứa địa chỉ của các biến có kiểu là của các biến có kiểu là typetype

Page 9: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Con trỏ – Khai báo trong C Giá trị của một biến con trỏ là địa chỉ mà nó trỏ đến Nếu chưa muốn khai báo kiểu dữ liệu mà con trỏ chỉ

đến, ta có thể khai báo như sau:

void *<tên_con_trỏ>;

Page 10: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Ví dụint *number;char *character;float *greatnumber;

• Đây là ba khai báo của con trỏ• Mỗi biến trỏ tới một kiểu dữ liệu khác nhau

• Chúng đều chiếm một lượng bộ nhớ như nhau (kích thước của một biến con trỏ tùy thuộc vào hệ điều hành)

• Dữ liệu mà chúng trỏ tới không chiếm lượng bộ nhớ như nhau, một kiểu int, một kiểu char và cái còn lại kiểu float

Page 11: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

int *pi;

long int *p;

float *pf;

Con trỏ – Khai báo trong C

char c, d, *pc; /* c và d kiểu charpc là con trỏ đến char */

double *pd, e, f; /* pd là con trỏ đến doublee and f are double */

char *start, *end;

Page 12: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Con trỏ- Toán tử lấy địa chỉ (&) Khai báo một biến thì nó phải được lưu trữ trong

một vị trí cụ thể trong bộ nhớ Chúng ta không quyết định nơi nào biến đó được

đặt Vậy: Hệ điều hànhHệ điều hành Vậy:

Ai đặt vị trí của biến? Chúng ta có thể biết biến đó được lưu trữ ở đâu ?

Hệ điều hànhHệ điều hành

Điều này có thể được thực hiện bằng cách đặt trước tên biến một dấu và (&), có nghĩa là "địa chỉ của".

Page 13: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Con trỏ - Toán tử lấy địa chỉ “&”

“&”: toán tử lấy địa chỉ của 1 biến Địa chỉ của tất cả các biến trong chương trình đều đã

được chỉ định từ khi khai báo

0x91A2

0x1132

char g = 'z';

int main(){

char c = 'a';char *p;p = &c;p = &g;return 0;

}

p c'a'

0x1132

p g

'z'0x91A2

Page 14: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Con trỏ - Toán tử “*” Có thể truy xuất trực tiếp đến giá trị được lưu trữ trong

biến được trỏ bởi con trỏ bằng cách đặt trước tên biến con trỏ một dấu sao (*) - ở đây được dịch là "giá trị được trỏ bởi"

*<tên_con_trỏ>;

• Vì vậy, nếu chúng ta viết: int beth = *ted;

• C thể đọc nó là: "beth bằng giá trị được trỏ bởi ted”

*<tên_con_trỏ>;

Page 15: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Con trỏ - Toán tử “*”

#include <stdio.h>char g = 'z';int main() a

0x1132

p c'a'

0x1132int main(){

char c = 'a';char *p;p = &c;printf("%c\n", *p);p = &g;printf("%c\n", *p);return 0;

}

az

xuất giá trị do p đang quản lý

0x91A2

0x1132

p g

'z'0x91A2

Page 16: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Phân biệt toán tử & và * Toán tử lấy địa chỉ (&)

Nó được dùng như là một tiền tố của biến và có thể được dịch là "địa chỉ của“&variable1 có thể được đọc là "địa chỉ của variable1“

Toán tử (*)Nó chỉ ra rằng cái cần được tính toán là nội dung được trỏ bởi biểu thức được coi như là một địa chỉ. Được dịch là "giá trị được trỏ bởi"..

*mypointer được đọc là "giá trị được trỏ bởi mypointer"

Page 17: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Con trỏ Con trỏ -- Truyền tham số địa chỉTruyền tham số địa chỉ

#include <stdio.h>void change(int *v);

int main(){

int var = 5;int var = 5;change(&var);printf("main: var = %i\n", var);return 0;

}

void change(int *v){

(*v) *= 100;printf("change: *v = %i\n", (*v));

}

Page 18: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Con trỏ NULLCon trỏ NULL Giá trị đặc biệt để chỉ rằng con trỏ không quản lý vùng

nào. Giá trị này thường được dùng để chỉ một con trỏ không hợp lệ.

#include <stdio.h>int main(){

int i = 13;short *p = NULL;if (p == NULL)

printf(“Con trỏ không hợp lệ!\n");else

printf(“Giá trị : %hi\n", *p);return 0;

}

Page 19: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

0x15A4

0x15A0

Con trỏ - Toán tử gán “=” Có sự khác biệt rất quan trọng khi thực hiện các

phép gán:int i = 10, j = 14;int *p = &i;int *q = &j;

p i10

0x15A0q j

14

14

0x15A0

0x15A4*p = *q;

int i = 10, j = 14;int *p = &i;int *q = &j;

p = q;

và:0x15A4

14

p i10

0x15A0q j

0x15A40x15A4

14

0x15A4

Page 20: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Luyện tập – Điền vào ô trống

int main(void){

int i = 10, j = 14, k;int *p = &i;int *q = &j;

i0x2100

j0x2104

*p += 1;p = &k;*p = *q;p = q;*p = *q;

return 0;}

k0x1208

p0x120B

q0x1210

Page 21: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Con trỏ và Mảng Biến kiểu mảng là địa chỉ tĩnh của một vùng nhớ,

được xác định khi khai báo, không thay đổi trong suốt chu kỳ sống.

Biến con trỏ là địa chỉ động của một vùng nhớ, được xác định qua phép gán địa chỉ khi chương trình thực xác định qua phép gán địa chỉ khi chương trình thực thi. #include <stdio.h>

int main(){

int a[10] = {1, 3, 4, 2, 0};int *p;p = a; //a = p: saiprintf(“0x%04X %i 0x%04X %i\n“, );

a, a[0], p, *p);return 0;

}

Page 22: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

3344

Con trỏ - Toán tử “+” với số nguyên

#include <stdio.h>int main(){

short a[10] = {1, 3, 5, 2, 0};short *p = a; printf(“0x%04X %i 0x%04X %i\n“, );

a, a[0], p, *p);

11

55

22

aa0x15A0

0x15A00x15A00x15A20x15A2

a, a[0], p, *p);p ++;printf(“0x%04X %i 0x%04X %i\n“, );

a, a[0], p, *p);(*p) ++;printf(“0x%04X %i 0x%04X %i\n“, );

a, a[0], p, *p);return 0;

}

22

00

……

pp0x16B2

Page 23: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Tăng (giảm) 1 ngôi trên biến con trỏ

Giả sử chúng ta có 3 con trỏ sau: char *mychar;short *myshort;long *mylong;

Nguyên nhân:Khi cộng thêm 1 vào một con trỏ thì nó sẽ trỏ tới phần tử tiếp theo có cùng kiểu mà nó đã được định nghĩa, vì vậy kích thước tính bằng byte long *mylong;

Chúng lần lượt trỏ tới ô nhớ 1000, 2000 và 3000. Nếu chúng ta viết

mychar++;myshort++;mylong++;

10011001

20012001

30013001

10011001

20022002

30043004

định nghĩa, vì vậy kích thước tính bằng byte của kiểu dữ liệu nó trỏ tới sẽ được cộng thêm vào biến con trỏ

Page 24: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Tăng (giảm) 1 ngôi trên biến con trỏ

Viết cách khác:Viết cách khác:mychar = mychar + 1;mychar = mychar + 1;myshort = myshort + 1;myshort = myshort + 1;mylong = mylong + 1;mylong = mylong + 1;

Page 25: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Con trỏ - Luyện tập

#include <stdio.h>int main(){

int a[10] = {2, 3, 5, 1, 4, 7, 0};int *p = a; printf(“%i %i\n“, a[0], *p);

2 23 11 91 3

printf(“%i %i\n“, a[0], *p);p ++;printf(“%i %i\n“, *p, p[2]);p ++; a[2] = 9;printf(“%i %i\n“, p[1], *p);p -= 2;printf(“%i %i\n”, p[3], p[1]);return 0;

}

Page 26: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Con trỏ - Cấp phát vùng nhớ động (1) Bộ nhớ tĩnh (stack)

Vùng nhớ được sử dụng để lưu trữ các biến toàn cục và lời gọi hàm

Tất cả những phần bộ nhớ chúng ta có thể sử Tất cả những phần bộ nhớ chúng ta có thể sử dụng là các biến các mảng và các đối tượng khác mà chúng ta đã khai báo. Kích cỡ của chúng là cố định và không thể thay đổi trong thời gian chương trình chạy

Page 27: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Con trỏ - Cấp phát vùng nhớ động (2) Bộ nhớ động (heap)

Bộ nhớ mà kích cỡ của nó chỉ có thể được xác định khi chương trình chạy

Có thể chỉ định vùng bộ nhớ động cho 1 con trỏ quản lý bằng các lệnh hàm malloc, calloc hoặc toán tử new của C++

Vùng nhớ do lập trình viên chỉ định phải được giải phóng bằng lệnh free (malloc, calloc) hoặc toán tử delete (new) trong C++

#include <stdio.h>#include <#include <malloc.hmalloc.h> > int main(){

int *p = (*int)malloc(10);p[0] = 1;p[3] = -7;free(p);return 0;

}

Page 28: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Một số lưu ý Một số lưu ý

Con trỏ là khái niệm quan trọng và khó nhất trong C/C++. Mức độ thành thạo C/C++ được đánh giá qua mức độ sử dụng con trỏ.mức độ sử dụng con trỏ.

Nắm rõ quy tắc sau, ví dụ int a, *pa = &a; *pa và a đều chỉ nội dung của biến a. pa và &a đều chỉ địa chỉ của biến a.

Không nên sử dụng con trỏ khi chưa được khởi tạo. Kết quả sẽ không lường trước được.

Page 29: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Tài liệu tham khảo [PVA] Chương 6 [K&R] Chapter 5

Page 30: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq
Page 31: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Chuỗi ký tự – Strings Một số qui tắc Nhập / xuất Con trỏ và chuỗi ký tự Một số hàm thư viện Một số hàm thư viện

Page 32: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Chuỗi ký tự Chuỗi ký tự -- Một số qui tắcMột số qui tắc

Chuỗi ký tự là mảng một chiều có mỗi thành phần là một số nguyên được kết thúc bởi số 0 (số không).

Ký tự kết thúc (0) ở cuối chuỗi ký tự thường được gọi là ký tự null (không giống con trỏ NULL). Có thể gọi là ký tự null (không giống con trỏ NULL). Có thể ghi là 0 hoặc ‘\0’ (không phải chữ o).

Được khai báo và truyền tham số như mảng một chiều.

char s[100];unsigned char s1[1000];

Page 33: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

char first_name[5] = { 'J', 'o', 'h', 'n', '\0' };

char last_name[6] = "Minor";

char other[] = "Tony Blurt";

char characters[7] = "No null";

Chuỗi ký tự - Ví dụ

char characters[7] = "No null";

first_name

last_name

other

characters

'J' 'o' 'h' 'n' 0

'M' 'i' 'n' 'o' 'r' 0

'T' 'o' ‘n’

'y' 32 'B' 'l' 'u' 'r' 't' 0

'N' 'o' 32 'n' 'u' 'l' 'l' 0

Page 34: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Chuỗi ký tự Chuỗi ký tự -- Nhập / xuấtNhập / xuất Có thể nhập / xuất chuỗi ký tự s bằng cách nhập

từng ký tự của s Hoặc sử dụng các hàm scanf và printf với ký

tự định dạng “%s”

char other[] = "Tony Blurt";

Nhập chuỗi có khoảng trắng dùng hàm gets

char name[100];printf("Nhap mot chuoi ky tu %s: ");gets(name);

char other[] = "Tony Blurt";printf("%s\n", other);

Page 35: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Lưu ý: kết thúc chuỗi#include <stdio.h>

int main(){

char other[] = "Tony Blurt";

printf("%s\n", other);

"Blurt" sẽ không được in ra

'T' 'o' ‘n’

'y' 32 'B' 'l' 'u' 'r' 't' 0

printf("%s\n", other);

other[4] = '\0';

printf("%s\n", other);

return 0;}

Tony BlurtTony

other

Page 36: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Chuỗi ký tự – Một số hàm thư viện

#include<string.h> Lấy độ dài chuỗi

l = strlen(s); Đổi toàn bộ các ký tự của chuỗi thành IN Đổi toàn bộ các ký tự của chuỗi thành IN

HOAstrupr(s);

Đổi toàn bộ các ký tự của chuỗi thành in thườngstrlwr(s);

Page 37: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Chuỗi ký tự – Một số hàm thư viện

So sánh chuỗi: so sánh theo thứ tự từ điển

Phân biệt IN HOA – in thường:

int strcmp(const char *s1, const char *s2);int strcmp(const char *s1, const char *s2);

Không phân biệt IN HOA – in thường:int stricmp(const char *s1, const char *s2);

Page 38: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

#include <stdio.h>

int main(){

char s1[] = "Minor";char s2[] = "Tony";int cmp = strcmp(s1, s2);

Chuỗi ký tự – ví dụ strcmp

Minor < Tony

int cmp = strcmp(s1, s2);if (cmp < 0)

printf("%s < %s", s1, s2);else

if (cmp == 0)printf("%s = %s", s1, s2);

elseprintf("%s > %s", s1, s2);

return 0;}

Page 39: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Chuỗi ký tự – Một số hàm thư viện

Gán nội dung chuỗi:o Chép toàn bộ chuỗi source sang chuỗi dest:int strcpy(char *dest, const char *src);

o Chép tối đa n ký tự từ source sang dest:int strncpy(char *dest,

const char *src, int n);

Tạo chuỗi mới từ chuỗi đã có:char *strdup(const char *src);

Page 40: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

#include <stdio.h>

int main(){

char s[] = "Tony Blurt";char s2[100], *s3;

Chuỗi ký tự – ví dụ strcpy

Tony Blurt

To123Blurt

Blurt

strcpy(s2, s);printf("%s\n", s2);strncpy(s2 + 2, "12345", 3);printf("%s\n", s2);s3 = strdup(s + 5);printf("%s\n", s3);free(s3);return 0;

}

Page 41: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Chuỗi ký tự – Một số hàm thư viện

Nối chuỗi: char *strcat(char *dest,

const char *src);

Tách chuỗi được phân biệt bởi ký tự trong chuỗi Tách chuỗi được phân biệt bởi ký tự trong chuỗi sep:

char *strtok(char *s, const char *sep);

Trả về địa chỉ của đoạn đầu tiên. Muốn tách đoạn kế tiếp tham số thứ nhất sẽ là NULL

Page 42: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

#include <stdio.h>

#define SEPARATOR "., "

int main(){

char s[]= "Thu strtok: 9,123.45";char *p;

Chuỗi ký tự – ví dụ strtok

Thu

strtok:

9

123

45char *p;

p = strtok(s, SEPARATOR);while (p != NULL){

printf("%s\n", p);p = strtok(NULL, SEPARATOR);

}return 0;

}

45

Page 43: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Chuỗi ký tự – Một số hàm thư viện

Tìm một ký tự trên chuỗi: char *strchr(const char *s, int c);

Tìm một đoạn ký tự trên chuỗi: char *strstr(const char *s1,

const char *s2);

Page 44: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

#include <stdio.h>

int main(){

char s[]= "Thu tim kiem chuoi";char *p;

Chuỗi ký tự – ví dụ tìm kiếm

char *p;

p = strchr(s, 'm');printf("%s\n", p);p = strstr(s, "em");printf("%s\n", p);return 0;

}

m kiem chuoi

em chuoi

Page 45: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

#include <stdio.h>

void StrIns(char *s, char *sub){

int len = strlen(sub);memmove(s + len, s, strlen(s)+1);strncpy(s, sub, len);

Chuỗi ký tự – chèn một đoạn ký tự

strncpy(s, sub, len);}int main(){

char s[]= "Thu chen";

StrIns(s, "123"); printf("%s\n", s);StrIns(s + 8, "45"); printf("%s\n", p);return 0;

}

123 Thu chen

123 Thu 45chen

Page 46: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

#include <stdio.h>

void StrDel(char *s, int n){

memmove(s, s + n, strlen(s+n)+1);}int main()

Chuỗi ký tự – xóa một đoạn ký tự

xoa 12345int main(){

char s[]= "Thu xoa 12345";

StrDel(s, 4); printf("%s\n", s);StrDel(s + 4, 3); printf("%s\n", p);return 0;

}

xoa 12345

xoa 45

Page 47: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Tổng kếtTổng kết

Khai báo Nhập / xuất Con trỏ và chuỗi ký tự Con trỏ và chuỗi ký tự Một số hàm thư viện Chèn / loại bỏ một đoạn con

Page 48: ä î < £ B Ø á K E 0 - VNUuet.vnu.edu.vn/~tqlong/2016thcs4/slide8_pointer_string.pdf · lqw sl orqj lqw s iordw si } v ¹ t< z ] } } v p fkdu f g sf f yj g nl Åx fkdu sf oj frq

Tài liệu tham khảo

[K&R] Chapter 7