Con trỏ chuỗi trong C++

Cùng tìm hiểu về con trỏ chuỗi trong C++. Bạn sẽ biết cách sử dụng con trỏ để xử lý chuỗi trong C++ sau bài học này.

Con trỏ chuỗi trong C++ là gì

Trong bài Con trỏ trong C++ là gì chúng ta đã biết, con trỏ trong C++ là một biến được dùng để lưu trữ địa chỉ của dữ liệu trong bộ nhớ máy tính.

Trong bài Con trỏ mảng trong C++ chúng ta cũng đã biết cách sử dụng con trỏ để thao tác với mảng rồi.

Chuỗi ký tự trong C++ thực ra cũng là một loại mảng, và do đó, chúng ta cũng có thể sử dụng con trỏ để lưu trữ địa chỉ của chuỗi và qua đó thao tác với chúng. Chúng ta gọi con trỏ sử dụng trong chuỗi là con trỏ chuỗi trong C++.

Con trỏ chuỗi trong C++

Bằng cách sử dụng con trỏ chuỗi trong C++, chúng ta có thể khai báo và xử lý chuỗi trực tiếp, cũng như xử lý gián tiếp chuỗi trong hàm, qua đó nâng cao việc sử dụng hiệu quả bộ nhớ và giảm thời gian thực thi chương trình.

Do đó, con trỏ chuỗi trong C++ là phần kiến thức không thể thiếu mà một lập trình viên về C++ cần phải nắm vững.

Khai báo con trỏ chuỗi trong C++

Cách khai báo con trỏ chuỗi trong C++ cũng tương tự như cách khai báo các loại con trỏ khác. Chúng ta viết kiểu của con trỏ, tiếp theo là dấu hoa thị * và tên của con trỏ với cú pháp sau đây:

char *p;

Trong đó char là kiểu dữ liệu của con trỏ chuỗi, và p là tên con trỏ.

Sau khi khai báo con trỏ chuỗi, chúng ta có thể gán địa chỉ của một chuỗi cho nó. Tương tự như với con trỏ mảng thì khi gán địa chỉ chuỗi cho con trỏ trong C++, chúng ta không dùng toán tử & khi gán địa chỉ của chuỗi cho con trỏ.

Ví dụ:

char

a[] =

"Hello"

, *p1;

p1 = a;



char

b[

100

], *p2;

p2 = b;


Con trỏ và địa chỉ trong chuỗi

Con trỏ chuỗi biểu thị địa chỉ của điểm bắt đầu chuỗi

Con trỏ chuỗi biểu thị địa chỉ của điểm bắt đầu vùng lưu trữ chuỗi trong bộ nhớ. Địa chỉ này cũng chính là địa chỉ của ký tự đầu tiên (có index bằng 0) của chuỗi trong bộ nhớ.

Lưu ý khác với ngôn ngữ C sẽ lưu địa chỉ của điểm bắt đầu chuỗi dưới dạng một dãy số thì trong C++, địa chỉ của điểm bắt đầu chuỗi được biểu diễn bởi các ký tự từ vị trí con trỏ chỉ đến tới cuối chuỗi.

Ví dụ, chúng a có thể xuất ra các ký tự từ vị trí con trỏ chỉ đến tới cuối chuỗi như sau:


using

namespace

std

;

int

main

()

{

char

str[] =

"Hello"

, *p;

p = str;


cout

<< p <<

endl

;

cout

<< p +

1

<<

endl

;

cout

<< p +

2

<<

endl

;


return

0

;

}


Kết quả:

Hello


ello


llo


Có thể thấy rõ địa chỉ của con trỏ chuỗi đã được biểu diễn bởi các ký tự từ vị trí con trỏ chỉ đến tới cuối chuỗi như trên.
Lưu ý phép cộng một số đơn vị vào con trỏ như trên được gọi là phép dịch chuyển con trỏ, và chúng ta sẽ làm rõ xử lý này dưới đây.

Chỉ định địa chỉ trong chuỗi thông qua dịch chuyển con trỏ

Chúng ta dịch chuyển con trỏ bằng cách cộng trừ nó cho một số đơn vị. Và bằng cách dịch chuyển con trỏ, chúng ta có thể chỉ định tới một địa chỉ trong chuỗi mà chúng ta cần làm việc với ký tự tại địa chỉ đó.

Ví dụ, do con trỏ p biểu thị địa chỉ trỏ tới ký tự đầu tiên (index bằng 0), nên chúng ta có thể chỉ định địa chỉ của ký tự thứ 2 (có index bằng 1) trong chuỗi bằng cách cộng thêm 1 đơn vị vào con trỏ, hoặc ký tự thứ 4 (có index bằng 3) trong chuỗi bằng cách cộng thêm 3 đơn vị vào con trỏ như sau:


using

namespace

std

;

int

main

()

{


char

a[]=

"Hello"

, *p;

p = a;


cout

<<

"array[0] address: "

, p;

cout

<<

"array[1] address: "

, p +

1

;

cout

<<

"array[3] address: "

, p +

3

;


return

0

;

}


Kết quả, bằng cách dịch chuyển con trỏ 1 đơn vị hoặc một số đơn vị, chúng ta có thể chỉ định các địa chỉ của các ký tự trong chuỗi như sau:

array[0] address: Hello


array[1] address: ello


array[3] address: lo


Bằng cách dịch chuyển con trỏ, chúng ta có thể chỉ định vị trí cần truy cập trong chuỗi, và qua đó có thể tiến hành truy xuất ký tự tại vị trí đó bằng cách dưới đây.

Truy xuất các ký tự trong chuỗi bằng con trỏ

Trong bài Con trỏ trong C++ là gì chúng ta đã biết để truy xuất giá trị tại vị trí con trỏ chỉ đến, chúng ta viết dấu hoa thị * vào đằng trước tên con trỏ.

Cách truy xuất các ký tự trong chuỗi bằng con trỏ cũng tương tự như vậy.

Giả sử chúng ta có chuỗi array và cho con trỏ chuỗi p lưu địa chỉ của nó như sau:

char

a[

100

], *p;

p = a;


Thông thường để truy cập vào từng ký tự trong chuỗi, chúng ta chỉ định index của ký tự đó trong chuỗi, ví dụ như a[0] hoặc a[1] chẳng hạn.

Tuy nhiên bằng cách kết hợp tên con trỏ với dấu hoa thị *, chúng ta cũng có thể truy cập và lấy giá trị của các ký tự trong chuỗi array với cú pháp sau đây:

*(p + index);

Trong đó index là index của ký tự cần lấy giá trị trong chuỗi và p là con trỏ chuỗi.

Ỏ đây, (p + index) có ý nghĩa tăng con trỏ một số index đơn vị, nhằm chỉ định địa chỉ của ký tự cần truy cập trên bộ nhớ. Và việc thêm hoa thị *(p + index) nhằm lấy giá trị ký tự tại vị trí này.

Và trong trường hợp index bằng 0, chúng ta có thể hiểu rằng cách viết *p biểu thị giá trị của ký tự đầu tiên trong chuỗi.

Cách truy cập vào ký tự trong chuỗi bằng index và bằng con trỏ có thể so sánh như bảng dưới đây:

indexTruy xuất bằng chuỗiTruy xuất bằng con trỏ0a[0]*p1a[1]*(p + 1)2a[2]*(p + 2)3a[3]*(p + 3)………na[n]*(p + n)

Ví dụ cụ thể:


using

namespace

std

;

int

main

()

{


char

a[] =

"Hello"

, *p;

p = a;



cout

<< a[

2

] <<

endl

;

cout

<< *(p +

2

)<<

endl

;


cout

<< a[

4

]<<

endl

;

cout

<< *(p +

4

)<<

endl

;

return

0

;

}


Kết quả, chuỗi và con trỏ đều đưa ra kết quả truy xuất giá trị ký tự giống nhau như sau:

l


l


o


o


Nhập xuất chuỗi bằng con trỏ trong C++

Bằng cách sử dụng con trỏ chuỗi, chúng ta có thể chỉ định vị trí các ký tự trong chuỗi, cũng như là truy cập và lấy giá trị của các ký tự đó.

Ứng dụng điều này, chúng ta cũng có thể nhập xuất chuỗi bằng con trỏ trong C++ như sau.

Nhập chuỗi bằng con trỏ trong C++

Trong bài Nhập chuỗi trong C++ chúng ta đã biết cách nhập trực tiếp giá trị từ bàn phím vào chuỗi như sau:

char

str[

100

];

cin

>> str;

Để nhập chuỗi bằng con trỏ trong C++ chúng ta chỉ cần sử dụng con trỏ thay cho chuỗi như sau là xong:

char

str[

100

], *p;

p = str;


cin

>> p;

Xuất chuỗi bằng con trỏ trong C++

Để xuất trực tiếp một chuỗi, chúng ta viết như sau:

char

str[

100

];

cout

<< str;

Để xuất chuỗi bằng con trỏ trong C++ thì sẽ phức tạp hơn chút. Chúng ta sẽ cần dịch chuyển vị trí con trỏ lần lượt từ đầu chuỗi đến cuối chuỗi và in lần lươt các ký tự tại vị trí đó.

Để làm được điều đó, chúng ta cần một vòng lặp và lặp từ đầu đến cuối chuỗi, cho tới khi gặp ký tự kết thúc chuỗi \0 thì thôi.

Chúng ta viết:

char

str[

100

], *p;

p = str;


while

(*p !=

'\0'

){

cout

<< *p;

++p;


}


Chương trình mẫu nhập xuất chuỗi bằng con trỏ trong C++

Dưới đây là chương trình mẫu nhập xuất chuỗi bằng con trỏ trong C++:


using

namespace

std

;


int

main

()


{

char

a[

256

], *p;

p = a;




cout

<<

">>Nhap chuoi: "

;

cin

>> p;




cout

<<

"Xuat chuoi: "

;

while

(*p !=

'\0'

){

cout

<< *p;

++p;


}



return

(

0

);

}


Kết quả:

>>Nhap chuoi: abcd


Xuat chuoi: abcd


Khai báo chuỗi bằng con trỏ trong C++

Trong ngôn ngữ C, chúng ta có thể khai báo chuỗi bằng con trỏ như sau:

char

*array_str =

"Hello"

;

Tuy nhiên, rất tiếc là chúng ta không thể sử dụng con trỏ để khai báo chuỗi trong C++ với cách viết như vậy, vì lỗi sẽ bị trả về như sau:

char

*array_str =

"Hello"

;


>>>main.cpp:

6

:

22

: warning: ISO C++ forbids converting a

string

constant to ‘

char

*’ [-Wwrite-strings]

>>>

6

|

char

*array_str =

"Hello"

;

Do vậy, nếu các bạn đã học C trước khi chuyển qua học C++ thì hãy quên đi chuyện khai báo chuỗi bằng con trỏ trong C++ đi nhé.

Tổng kết

Trên đây Kiyoshi đã hướng dẫn các bạn về con trỏ chuỗi trong C++ rồi. Để nắm rõ nội dung bài học hơn, bạn hãy thực hành viết lại các ví dụ của ngày hôm nay nhé.

Và hãy cùng tìm hiểu những kiến thức sâu hơn về C++ trong các bài học tiếp theo.