Trong ngôn ngữ lập trình C, kiểu dữ liệu signed và unsigned đóng một vai trò quan trọng trong việc lưu trữ và xử lý dữ liệu. Chúng xác định cách dữ liệu được biểu diễn và xử lý, và hiểu rõ sự khác biệt giữa chúng là điều quan trọng để viết mã nguồn chính xác và hiệu quả. Trong bài viết này, chúng ta sẽ tìm hiểu về kiểu dữ liệu signed và unsigned, các sự khác biệt giữa chúng và cách sử dụng thích hợp.
Kiểu Dữ Liệu Signed
Kiểu dữ liệu signed được sử dụng để biểu diễn các số nguyên có thể là dương, âm hoặc không (0). Điểm quan trọng là kiểu dữ liệu signed sử dụng một bit để biểu diễn dấu của số. Điều này có nghĩa là một biến kiểu dữ liệu signed có thể nhận các giá trị âm, dương và 0.
Dưới đây là một số kiểu dữ liệu signed phổ biến trong ngôn ngữ C:
signed char: Kiểu dữ liệu này thường có kích thước 1 byte và có phạm vi từ -128 đến 127.
signed int: Kiểu dữ liệu này thường có kích thước 4 byte trên máy tính 32-bit và có phạm vi từ -2,147,483,648 đến 2,147,483,647.
signed short: Kiểu dữ liệu này thường có kích thước 2 byte và có phạm vi từ -32,768 đến 32,767.
signed long: Kiểu dữ liệu này thường có kích thước 4 byte trên máy tính 32-bit và 8 byte trên máy tính 64-bit, có phạm vi tương ứng.
signed long long: Kiểu dữ liệu này thường có kích thước 8 byte và có phạm vi rất lớn.
Khi bạn khai báo một biến kiểu dữ liệu signed và gán giá trị cho nó, biến này có thể chứa các giá trị âm và dương theo mặc định. Ví dụ:
signed int so_nguyen = -100; // Biến so_nguyen có thể chứa giá trị âm |
Kiểu Dữ Liệu Unsigned
Kiểu dữ liệu unsigned được sử dụng để biểu diễn các số nguyên không âm (tức là số dương hoặc 0). Một điểm quan trọng là kiểu dữ liệu unsigned không sử dụng bit để biểu diễn dấu, nên tất cả các giá trị của nó đều không âm.
Dưới đây là một số kiểu dữ liệu unsigned phổ biến trong ngôn ngữ C:
unsigned char: Kiểu dữ liệu này thường có kích thước 1 byte và có phạm vi từ 0 đến 255.
unsigned int: Kiểu dữ liệu này thường có kích thước 4 byte trên máy tính 32-bit và có phạm vi từ 0 đến 4,294,967,295.
unsigned short: Kiểu dữ liệu này thường có kích thước 2 byte và có phạm vi từ 0 đến 65,535.
unsigned long: Kiểu dữ liệu này thường có kích thước 4 byte trên máy tính 32-bit và 8 byte trên máy tính 64-bit, có phạm vi tương ứng.
unsigned long long: Kiểu dữ liệu này thường có kích thước 8 byte và có phạm vi rất lớn.
Khi bạn khai báo một biến kiểu dữ liệu unsigned và gán giá trị cho nó, biến này chỉ có thể chứa các giá trị không âm. Ví dụ:
unsigned int so_nguyen_khong_am = 100; // Biến so_nguyen_khong_am chỉ chứa giá trị không âm |
Sự Khác Biệt Giữa Kiểu Dữ Liệu Signed và Unsigned
Sự khác biệt chính giữa kiểu dữ liệu signed và unsigned là cách chúng biểu diễn và xử lý dấu của các số. Dưới đây là một số sự khác biệt quan trọng:
Phạm Vi Giá Trị: Kiểu dữ liệu signed có phạm vi giá trị chia đôi so với kiểu dữ liệu unsigned cùng kích thước. Ví dụ, một biến
signed char
có phạm vi từ -128 đến 127, trong khi một biếnunsigned char
có phạm vi từ 0 đến 255.Dấu Trong Toán Tử So Sánh: Trong các toán tử so sánh như
<
,>
,<=
, và>=
, kiểu dữ liệu signed và unsigned có sự khác biệt trong cách dấu được xử lý. Ví dụ:
signed int a = -1; |
Trong ví dụ trên, biến a
có giá trị âm nhưng vẫn được so sánh với biến b
có giá trị không âm.
- Phép Trừ: Khi bạn thực hiện phép trừ giữa các biến kiểu dữ liệu signed và unsigned, hãy cẩn thận với kết quả. Kết quả có thể không như mong đợi do sự khác biệt trong phạm vi giá trị. Ví dụ:
signed int a = 10; |
Trong trường hợp này, biến c
có giá trị không như bạn có thể nghĩ.
Vì sao cần phân biệt kiểu dữ liệu signed và unsigned trong C
Với mỗi kiểu dữ liệu trong C sẽ có một phạm vi giá trị riêng bắt đầu từ một số âm đến một số dương nào đó. Ví dụ như kiểu char có phạm vi giá trị bắt đầu từ -127 đến 128 chẳng hạn. Với những dữ liệu có sự phân biệt dấu như thế, chúng ta sẽ dùng kiểu signed để lưu giữ chúng.
Ngược lại thì với các dữ liệu có phạm vi giá trị không chứa số âm thì chúng ta sẽ dùng tới kiểu dữ liệu không dấu- kiểu dữ liệu unsigned để lưu giữ.
Về mặc định thì khi khai báo hoặc khởi tạo biến trong C, chương trình sẽ tự động định nghĩa biến thuộc kiểu kiểu dữ liệu có dấu - kiểu dữ liệu signed . Tuy nhiên cũng có những trường hợp chúng ta biết trước sẽ không sử dụng tới số âm trong chương trình, do đó nếu chúng ta khai báo kiểu dữ liệu theo cách thông thường, thì sẽ dẫn đến một phần dung lượng trong biến sẽ được khai báo mà không được sử dụng, dẫn đến sự lãng phí bộ nhớ chương trình.
Bởi vậy, để tiết kiệm và sử dụng hiệu quả dung lượng bộ nhớ chỉ định cho biến, chúng ta có thể báo cho chương trình biết trước dữ liệu mà chúng ta lưu trong biến có dấu hay không, bằng cách sử dụng tới hai từ khoá là signed và unsigned trong C. Trong đó signed nghĩa là dữ liệu có dấu, và unsigned nghĩa là dữ liệu không có dấu trong C.
Lưu ý là khi chỉ định Kiểu dữ liệu signed và unsigned trong C, chúng ta cần phải chú ý tới 2 điểm sau đây:
Không thể sử dụng signed và unsigned trong C cho các kiểu dữ liệu số thực dấu phẩy động như là float hay double.
Việc chỉ định signed và unsigned sẽ không làm thay đổi kích thước (size) của dữ liệu, mà chỉ thay đổi phạm vi dữ liệu có thể gán trong nó mà thôi.
Cụ thể thì chúng ta có bảng so sánh các kiểu dữ liệu trong C trong trường hợp mặc định (signed) và unsigned như sau:
Bảng So sánh Kiểu dữ liệu mặc định (signed) và unsigned trong C
Loại | Kiểu dữ liệu | Kích thước | Phạm vi giá trị mặc đinh (signed) | Phạm vi giá trị (unsigned) |
---|---|---|---|---|
Loại ký tự | char | 1 byte | -127 ~ 128 | 0 ~ 255 |
Số nguyên | short int int long int | 2 byte 4 byte 4 byte | -32768 ~ 32767 -2147483648 ~ 2147483647 -2147483648 ~ 2147483647 | 0 ~ 65535 0 ~ 4294967295 0 ~ 4294967295 |
Cách khai báo kiểu dữ liệu signed và unsigned trong C
Để khởi tạo và khai báo kiểu dữ liệu có dấu signed trong C, theo cách chính xác thì chúng ta cần phải thêm từ khoá signed vào trước tên biến khi khai báo hoặc khởi tạo nó. Ví dụ:
signed char char1 = 'a'; |
Tuy nhiên thì do chúng ta có thể lược bỏ từ khoá này và sử dụng kiểu dữ liệu theo cách mặc định, giống như Kiyoshi đã hướng dẫn ở phần trên.
char char1 = 'a'; |
Khác với kiểu dữ liệu có dấu thì để sử dụng kiểu dữ liệu không dấu unsigned trong C thì chúng ta bắt buộc phải thêm từ khoá unsigned vào đằng trước khi khởi tạo và khai báo biến. Ví dụ:
unsigned char char1 = 'a'; |
Sử Dụng Thích Hợp của Kiểu Dữ Liệu Signed và Unsigned
Khi lập trình trong ngôn ngữ C, việc lựa chọn giữa kiểu dữ liệu signed và unsigned phụ thuộc vào nhiệm vụ cụ thể và loại dữ liệu bạn đang xử lý. Dưới đây là một số hướng dẫn về cách sử dụng thích hợp:
Sử Dụng Kiểu Dữ Liệu Signed Cho Số Nguyên Chứa Dấu: Khi bạn cần lưu trữ số nguyên có thể là âm hoặc dương, sử dụng kiểu dữ liệu signed như
signed int
,signed char
, vàsigned long
.Sử Dụng Kiểu Dữ Liệu Unsigned Cho Số Nguyên Không Âm: Khi bạn chỉ cần lưu trữ các số nguyên không âm (ví dụ: chỉ số mảng, độ dài chuỗi), sử dụng kiểu dữ liệu unsigned như
unsigned int
,unsigned char
, vàunsigned long
.Cân Nhắc Khi Trộn Lẫn Signed và Unsigned Trong Phép Tính: Khi bạn kết hợp các biến kiểu dữ liệu signed và unsigned trong phép tính, hãy cẩn thận để tránh kết quả không như mong đợi. Thường nên ép kiểu các biến để đảm bảo tính nhất quán.
Lựa Chọn Phù Hợp Cho Phạm Vi Giá Trị: Chọn kiểu dữ liệu sao cho phạm vi giá trị của biến phù hợp với nhiệm vụ của nó. Điều này giúp tiết kiệm bộ nhớ và đảm bảo tính chính xác của tính toán.
Sử Dụng
size_t
Cho Kích Thước Dữ Liệu và chỉ Số Mảng: Kiểu dữ liệusize_t
được định nghĩa là unsigned và thường được sử dụng cho kích thước dữ liệu và chỉ số mảng để đảm bảo tính nhất quán với các hàm thư viện C.
size_t kich_thuoc_mang = sizeof(int) * 10; // Sử dụng size_t cho kích thước |
Chú ý khi dùng Kiểu Dữ Liệu Signed và Unsigned
Với các kiểu dữ liệu dùng để biểu diễn số thực dấu phẩy động trong C như là kiểu float hay double chẳng hạn, chúng ta lưu ý rằng không thể sử dụng signed và unsigned với chúng được. Ví dụ các cách viết sau đây sẽ đều dẫn đến lỗi compile chương trình:
signed float num1 = 1.234; |
Kết Luận
Kiểu dữ liệu signed và unsigned là một phần quan trọng của ngôn ngữ lập trình C và ảnh hưởng đến cách chúng ta lưu trữ và xử lý dữ liệu. Sự khác biệt chính giữa chúng là cách xử lý dấu của các số và phạm vi giá trị của biến. Việc hiểu rõ sự khác biệt này và lựa chọn kiểu dữ liệu phù hợp cho nhiệm vụ cụ thể là quan trọng để viết mã nguồn chính xác và hiệu quả.
URL Link
HOME › lập trình c cơ bản dành cho người mới học lập trình>>07. biến trong c