Trang Chủ

Giới thiệu về kiểu dữ liệu char trong C++

Đến thời điểm này, các kiểu dữ liệu cơ bản mà chúng ta đã tìm hiểu để sử dụng cho việc giữ các số (số nguyên và dấu phẩy động) hoặc giá trị đúng / sai (booleans). Nhưng nếu chúng ta muốn lưu trữ chữ thì sao? Kiểu dữ liệu char được thiết kế cho mục đích như vậy.

Những bài tập giúp nâng cao kỹ năng xử lý tình huống trong C++”]

Kiểu dữ liệu char là một kiểu tích phân, có nghĩa là giá trị cơ bản được lưu trữ dưới dạng một số nguyên và nó được đảm bảo có kích thước 1 byte. Tuy nhiên, tương tự như cách giá trị boolean được hiểu là true hay false, giá trị char được hiểu là ký tự ASCII.

ASCII là viết tắt của Code tiêu chuẩn của Mỹ để trao đổi thông tin và nó định nghĩa một cách cụ thể để biểu thị các ký tự tiếng Anh (cộng với một vài ký hiệu khác) là các số từ 0 đến 127 (được gọi là code ASCII). Ví dụ, code ASCII 97 được hiểu là ký tự ‘a.

Ký tự char luôn được đặt giữa các dấu nhấy đơn.

Ở đây, một bảng đầy đủ các ký tự ASCII:

Code Symbol Code Symbol Code Symbol Code Symbol
0 NUL (null) 32 (space) 64 @ 96 `
1 SOH (start of header) 33 ! 65 A 97 a
2 STX (start of text) 34 66 B 98 b
3 ETX (end of text) 35 # 67 C 99 c
4 EOT (end of transmission) 36 $ 68 D 100 d
5 ENQ (enquiry) 37 % 69 E 101 e
6 ACK (acknowledge) 38 & 70 F 102 f
7 BEL (bell) 39 71 G 103 g
8 BS (backspace) 40 ( 72 H 104 h
9 HT (horizontal tab) 41 ) 73 I 105 i
10 LF (line feed/new line) 42 * 74 J 106 j
11 VT (vertical tab) 43 + 75 K 107 k
12 FF (form feed / new page) 44 , 76 L 108 l
13 CR (carriage return) 45 77 M 109 m
14 SO (shift out) 46 . 78 N 110 n
15 SI (shift in) 47 / 79 O 111 o
16 DLE (data link escape) 48 0 80 P 112 p
17 DC1 (data control 1) 49 1 81 Q 113 q
18 DC2 (data control 2) 50 2 82 R 114 r
19 DC3 (data control 3) 51 3 83 S 115 s
20 DC4 (data control 4) 52 4 84 T 116 t
21 NAK (negative acknowledge) 53 5 85 U 117 u
22 SYN (synchronous idle) 54 6 86 V 118 v
23 ETB (end of transmission block) 55 7 87 W 119 w
24 CAN (cancel) 56 8 88 X 120 x
25 EM (end of medium) 57 9 89 Y 121 y
26 SUB (substitute) 58 : 90 Z 122 z
27 ESC (escape) 59 ; 91 [ 123 {
28 FS (file separator) 60 < 92 124 |
29 GS (group separator) 61 = 93 ] 125 }
30 RS (record separator) 62 > 94 ^ 126 ~
31 US (unit separator) 63 ? 95 _ 127 DEL (delete)

Code 0-31 được gọi là ký tự không thể in được và chúng chủ yếu được sử dụng để thực hiện định dạng và điều khiển máy in. Hầu hết trong số này đã lỗi thời.

Code 32-127 được gọi là các ký tự có thể in được và chúng đại diện cho các chữ cái, ký tự số và dấu chấm câu mà hầu hết các máy tính sử dụng để hiển thị văn bản tiếng Anh cơ bản.

Nội dung chính

Khởi tạo ký tự

Bạn có thể khởi tạo các biến char bằng cách sử dụng các ký tự:

 

Bạn cũng có

thể khởi tạo ký tự bằng số nguyên, nhưng điều này nên tránh nếu có thể

Cẩn thận không trộn lẫn số ký tự với số nguyên. Hai khởi tạo sau không giống nhau:

Số dưới dạng ký tự sẽ được sử dụng khi chúng ta muốn biểu diễn số dưới dạng văn bản, thay vì số để áp dụng các phép toán.

in ký tự

Khi sử dụng std :: cout để in char, std :: cout xuất ra biến char dưới dạng ký tự ASCII:

Điều này tạo ra kết quả:

Chúng ta cũng có thể xuất chữ char trực tiếp:

Điều này tạo ra kết quả:

Số nguyên chiều rộng cố định int8_t thường được xử lý giống như một char đã ký trong C ++, do đó, nó thường sẽ in dưới dạng char thay vì số nguyên.

In ký tự dưới dạng số nguyên thông qua static_cast

Nếu chúng ta muốn xuất một char dưới dạng một số thay vì một ký tự, chúng ta phải nói với std :: cout để in char như thể nó là một số nguyên. Một cách để làm điều này là gán char cho một số nguyên và in số nguyên:

 

Tuy nhiên, điều này là khó khăn. Một cách tốt hơn là sử dụng một kiểu cast. Một cast sẽ tạo ra một giá trị cho một kiểu nào đó từ một giá trị của kiểu khác. Để chuyển đổi giữa các kiểu dữ liệu cơ bản (ví dụ: từ char thành int hoặc ngược lại), chúng ta sử dụng static_cast.

Cú pháp cho cast như sau:

static_cast lấy giá trị từ một biểu thức làm đầu vào và chuyển đổi nó thành bất kỳ loại cơ bản nào new_type đại diện (ví dụ: int, bool, char, double).

Ở đây, sử dụng static_cast để tạo giá trị nguyên từ giá trị char của chúng ta:

Kết quả này trong:

Điều quan trọng cần lưu ý là tham số tới static_cast đánh giá là một biểu thức. Khi chúng ta truyền vào một biến, biến đó được ước tính để tạo ra giá trị của nó, sau đó được chuyển đổi sang kiểu mới. Biến không bị ảnh hưởng bằng cách chuyển giá trị của nó sang kiểu mới. Trong trường hợp trên, biến ch vẫn là char và vẫn giữ nguyên giá trị.

Cũng lưu ý rằng việc static_cast không thực hiện bất kỳ kiểm tra phạm vi(độ lớn), vì vậy nếu bạn truyền một số nguyên lớn vào một char, bạn sẽ tràn kiểu char của mình.

Chúng ta sẽ nói nhiều hơn về các static_cast và các kiểu khác nhau trong một bài học trong tương lai.

Nhập ký tự

Chương trình sau đây yêu cầu người dùng nhập một ký tự, sau đó in ra cả ký tự và code ASCII của nó:

Đây là đầu ra từ một lần chạy:

Lưu ý rằng std :: cin sẽ cho phép bạn nhập nhiều ký tự. Tuy nhiên, biến ch chỉ có thể chứa 1 ký tự. Do đó, chỉ có ký tự đầu vào đầu tiên được trích xuất thành biến ch. Phần còn lại của đầu vào người dùng được để lại trong bộ đệm đầu vào mà std :: cin sử dụng và có thể được trích xuất bằng các lệnh gọi tiếp theo đến std :: cin.

Bạn có thể thấy hành vi này trong ví dụ sau:

 

Kích thước Char, phạm vi và dấu hiệu mặc định

Char được định nghĩa bởi C ++ để luôn có kích thước 1 byte. Theo mặc định, một char có thể được có ký hiệu hoặc không dấu (mặc dù nó thường được có ký hiệu). Nếu bạn sử dụng ký tự để giữ các ký tự ASCII, bạn không cần chỉ định một ký hiệu (vì cả hai ký tự có ký hiệu và không dấu có thể giữ các giá trị trong khoảng từ 0 đến 127).

Nếu bạn sử dụng char để giữ các số nguyên nhỏ (điều bạn không nên làm trừ khi bạn tối ưu hóa rõ ràng cho không gian), bạn phải luôn chỉ định xem nó có ký hiệu hay không dấu. Một char có ký hiệu có thể giữ một số trong khoảng từ -128 đến 127. Một char không dấu có thể giữ một số trong khoảng từ 0 đến 255.

Trình tự thoát khỏi một dòng nào đó

Có một số nhân vật trong C ++ có ý nghĩa đặc biệt. Những nhân vật này được gọi là trình tự thoát. Một chuỗi thoát bắt đầu bằng một ký tự ‘ (dấu gạch chéo ngược) và sau đó là một chữ cái hoặc số sau đây.

Bạn đã thấy trình tự thoát phổ biến nhất: ‘ n, có thể được sử dụng để nhúng một dòng mới trong một chuỗi văn bản:

Kết quả này:

Một chuỗi thoát thường được sử dụng khác là ‘ t, trong đó nhúng một tab ngang:

Đầu ra nào:

Ba chuỗi thoát đáng chú ý khác là:

In in một trích dẫn
‘In một trích dẫn kép
\ in dấu gạch chéo ngược

Ở đây, một bảng của tất cả các chuỗi để giúp chúng ta thoát trong 1 line:

Name Symbol Ý nghĩa
Alert a Tạo ra một cảnh báo, chẳng hạn như tiếng bíp
Backspace b Di chuyển con trỏ trở lại một khoảng trắng
Formfeed f Di chuyển con trỏ đến trang logic tiếp theo
Newline n Di chuyển con trỏ đến dòng tiếp theo
Carriage return r Di chuyển con trỏ đến đầu dòng
Horizontal tab t In một tab ngang
Vertical tab v In một tab dọc
Single quote In một trích dẫn
Double quote In một trích dẫn kép
Backslash \ In dấu gạch chéo ngược.
Question mark ? In một dấu hỏi.
Octal number (number) Dịch sang char từ số bát phân
Hex number x(number) Dịch sang char từ số hex

Dưới đây là một số ví dụ:

 

Bản in

Dòng mới ( n) với std :: endl

Điều khác biệt giữa việc đặt ký hiệu trong dấu ngoặc đơn hay dấu ngoặc kép

Các ký tự độc lập luôn được đặt trong các trích dẫn đơn (ví dụ: ’a’,’+’, ‘5’). Một char chỉ có thể đại diện cho một ký hiệu (ví dụ: chữ a, ký hiệu cộng, số 5). Ví dụ sau đây là sai:

Văn bản đặt giữa hai dấu ngoặc kép (ví dụ: “Hello, world!”) được gọi là một chuỗi. Chuỗi là một tập hợp các ký tự liên tiếp (và do đó, một chuỗi có thể chứa nhiều ký hiệu).

Hiện tại, bạn có thể sử dụng chuỗi ký tự trong code của mình:

Tuy nhiên, các chuỗi không phải là kiểu dữ liệu cơ bản trong C ++ và nó phức tạp hơn một chút, vì vậy chúng ta sẽ bảo lưu thảo luận về các kiểu dữ liệu đó cho đến khi chúng tôi đề cập đến các kiểu dữ liệu ghép.

Luôn đặt các ký tự độc lập trong các dấu ngoặc đơn. Điều này giúp trình biên dịch tối ưu hóa hiệu quả hơn.

Còn các loại char khác, wchar_t, char16_t và char32_t thì sao?

Nên tránh sử dụng wchar_t trong hầu hết các trường hợp (trừ khi giao tiếp với API Windows). Kích thước của nó được xác định, và không đáng tin cậy. Nó phần lớn đã bị phản đối khi dùng.

Giống như ASCII ánh xạ các số nguyên 0-127 sang các ký tự tiếng US, các tiêu chuẩn code hóa ký tự khác tồn tại để ánh xạ các số nguyên (có kích thước khác nhau) sang các ký tự trong các ngôn ngữ khác. Ánh xạ nổi tiếng nhất bên ngoài ASCII là tiêu chuẩn Unicode, ánh xạ hơn 110.000 số nguyên sang các ký tự trong nhiều ngôn ngữ khác nhau. Vì Unicode chứa rất nhiều điểm code, một điểm code Unicode duy nhất cần 32 bit để thể hiện một ký tự (được gọi là UTF-32). Tuy nhiên, các ký tự Unicode cũng có thể được mã hóa bằng nhiều ký tự 16 bit hoặc 8 bit (được gọi là UTF-16 và UTF-8 tương ứng).

char16_t và char32_t đã được thêm vào C ++ 11 để cung cấp hỗ trợ rõ ràng cho các ký tự Unicode 16 bit và 32 bit. char8_t đã được thêm vào trong C ++ 20.

Bạn có nhu cầu sử dụng char8_t, char16_t hoặc char32_t trừ khi bạn có kế hoạch làm một chương trình có liên quan tới Unicode. Unicode và ngôn ngữ bản địa nói chung nằm ngoài phạm vi của các hướng dẫn này, vì vậy chúng ta sẽ tìm hiểu trong phần tiếp theo.

Trong khi đó, bạn chỉ nên sử dụng các ký tự ASCII khi làm việc với các ký tự (và chuỗi). Sử dụng các ký tự từ các bộ ký tự khác có thể khiến các ký tự của bạn hiển thị không chính xác.

Chia sẻ bài viết ngay