Kiểu dữ liệu là gì ?
Kiểu dữ liệu (data type) là một sự quy định về cấu trúc, miền trị của dữ liệu và tập các phép toán tác động lên miền trị đó.
Một ngôn ngữ lập trình chỉ chấp nhận và xử lý những dữ liệu tuân theo sự quy định về kiểu của ngôn ngữ lập trình đó. Trong một ngôn ngữ lập trình, một dữ liệu bao giờ cũng thuộc về một kiểu dữ liệu nhất định.
Trong C# dữ liệu được phân loại thành mấy kiểu ?
Dữ liệu được phân loại thành 3 kiểu:
- Kiểu tham trị (Value type)
- Kiểu tham chiếu (Reference type)
- Kiểu con trỏ (Pointer type)
Nội dung chi tiết:
Ví dụ: khi khai báo int, char, float,… thì tương ứng các biến có kiểu dữ liệu này sẽ lưu trữ giá trị số nguyên, ký tự, và số thực…
Bảng sau sẽ mô tả một số kiểu tham trị (Kiểu dữ liệu được xây dựng sẵn):
Kiểu C# | Số byte | Kiểu .NET | Mô tả |
byte | 1 | Byte | Số nguyên dương không dấu từ 0-255 |
char | 2 | Char | Ký tự Unicode |
bool | 1 | Boolean | Giá trị logic true/ false |
sbyte | 1 | Sbyte | Số nguyên có dấu (từ -128 đến 127) |
short | 2 | Int16 | Số nguyên có dấu giá trị từ -32768 đến 32767 |
ushort | 2 | UInt16 | Số nguyên không dấu 0 – 65.535 |
int | 4 | Int32 | Số nguyên có dấu, giá trị từ –2.147.483.648 đến 2.147.483.647 |
uint | 4 | UInt32 | Số nguyên không dấu 0 – 4.294.967.295 |
float | 4 | Single | Kiểu dấu chấm động, giá trị xấp xỉ từ -3.402823e38 đến 3.402823e38 |
double | 8 | Double | Kiểu dấu chấm động có độ chính xác gấp đôi, giá trị từ -1.79769313486232e308 đến 1.79769313486232e308. |
decimal | 8 | Decimal | Từ -79228162514264337593543950335 đến 79228162514264337593543950335 , được dùng trong tính toán tài chính, kiểu này đòi hỏi phải có hậu tố “m” hay “M” theo sau giá trị. |
long | 8 | Int64 | Kiểu số nguyên có dấu có giá trị trong khoảng: -9.223.370.036.854.775.808 đến 9.223.372.036.854.775.807 |
ulong | 8 | UInt64 | Số nguyên không dấu từ 0 đến 18,446,744,073,709,551,615 |
■ Ngoài ra còn có 2 kiểu tham trị đặc biệt là kiểu struct, enum chúng ta sẽ cùng tìm hiểu trong một bài riêng.
Code minh họa:
namespace MinhHoangBlog
{
class KieuThamTriCSharp
{
static void Main(string[] args)
{
/*
* Khai báo biến và khởi tạo giá trị
*/
// Kiểu số nguyên
int valInt = 8;
byte valByte = 6;
short valShort = 2017;
// Kiểu số thực
float valFloat = 10.9f; // Giá trị của biến kiểu float phải có hậu tố f hoặc F.
double valDouble = 10.9; // Giá trị của biến kiểu double không cần hậu tố.
decimal valDecimal = 10.9m; // Giá trị của biến kiểu decimal phải có hậu tố m hoặc M.
// Kiểu ký tự và kiểu chuỗi
char valChar = ‘M’; // Giá trị của biến kiểu ký tự nằm trong cặp dấu ” (nháy đơn).
string valString = "MinhHoangBlog"; // Giá trị của biến kiểu chuỗi nằm trong cặp dấu "" (nháy kép).
/*
* Dùng từ khóa << typeof >> để biết Type của kiểu dữ liệu
*/
Type typeUint = typeof(uint);
Console.WriteLine(typeUint.Name); // Output: UInt32
Type typeFloat = typeof(float);
Console.WriteLine(typeFloat.Name); // Output: Single
/*
* Dùng từ khóa << sizeof >> để biết Size của kiểu dữ liệu
*/
Console.WriteLine("Kieu char co: {0} bytes", sizeof(char)); // Output: 2
Console.WriteLine("Kieu long co: {0} bytes", sizeof(long)); // Output: 8
Console.WriteLine("Kieu double co: {0} bytes", sizeof(double)); // Output: 8
Console.ReadLine();
/*
* Dùng hằng << MinValue, MaxValue >> để biết Range của kiểu dữ liệu
*/
// Dùng type C# để check
Console.WriteLine(int.MinValue); // Output: –2147483648
Console.WriteLine(int.MaxValue); // Output: 2147483647
//Hoặc cũng có thể dùng type .Net để check
Console.WriteLine(Int32.MinValue); // Output: –2147483648
Console.WriteLine(Int32.MaxValue); // Output: 2147483647
Console.ReadKey();
}
}
}
[/code]
– Kiểu dữ liệu này chứa địa chỉ của vùng nhớ, nơi lưu giá trị thật của biến chứ không trực tiếp lưu giá trị của biến, nó tham chiếu tới một vùng nhớ được cấp phát trên bộ nhớ Heap (khác với kiểu tham trị là nó lưu trực tiếp giá trị của biến)
– Bạn có thể hình dung qua hình minh họa:
– Một số kiểu tham chiếu là: object, string, class, delegate, interface, array, dynamic, kiểu do lập trình viên tự định nghĩa (thực ra nó cũng là kiểu class, ví dụ như class Student, class Animal,… )
– Trong đó, kiểu object là lớp cơ sở cơ bản cho tất cả kiểu dữ liệu trong C# Common Type System (CTS). Object là một alias cho lớp System.Object. Các kiểu object có thể được gán giá trị của bất kỳ kiểu, kiểu giá trị, kiểu tham chiếu, kiểu tự định nghĩa (user-defined) khác. Tuy nhiên, trước khi gán giá trị, nó cần một sự chuyển đổi kiểu.
Khi một kiểu giá trị được chuyển đổi thành kiểu object, nó được gọi là boxing và ngược lại, khi một kiểu object được chuyển đổi thành kiểu giá trị, nó được gọi là unboxing.
namespace MinhHoangBlog
{
class ObjectTypeDemo
{
static void Main(string[] args)
{
int num = 123;
object obj = (object)num; // boxing
obj = 123;
num = (int)obj; // unboxing
// Khai báo mảng kiểu object
object[] arrObj = new object[4];
// Kiểu object có thể nhận giá trị của bất kỳ các kiểu dữ liệu khác
arrObj[0] = true;
arrObj[1] = 1987;
arrObj[2] = "Hello World!";
arrObj[3] = 5.2;
int ii = 0;
Console.WriteLine( "Cac gia tri cua mang: " );
do
{
Console.WriteLine(arrObj[ii]);
ii++;
}
while (ii < arrObj.Length);
Console.ReadKey();
}
}
}
[/code]
– Các kiểu tham chiếu còn lại như Class, Interface, Delegate, Dynamic,… chúng ta sẽ nói chi tiết từng loại trong các bài viết tiếp theo.
– Các biến kiểu con trỏ lưu giữ địa chỉ bộ nhớ của kiểu khác. Các con trỏ trong C# có khả năng như con trỏ trong C hoặc C++.
– C# cho phép sử dụng các biến con trỏ trong một hàm của khối code khi nó được đánh dấu bởi từ khóa unsafe. Khái niệm unsafe code hoặc unmanaged code trong C# là một khối code có sử dụng biến con trỏ.
■ Từ khóa unsafe có thể được sử dụng trong các trường hợp sau:
unsafe string DoSomething()
{
// code có sử dụng con trỏ
}
[/code]
unsafe class MyClass()
{
// có method bất kỳ sử dụng con trỏ
}
[/code]
class MyClass()
{
unsafe int* p; // khai báo 1 field là biến con trỏ
}
[/code]
unsafe struct Books
{
// có method bất kỳ sử dụng con trỏ
};
[/code]
void MyMethod()
{
// phần ‘safe’ code không sử dụng con trỏ
unsafe
{
// phần unsafe code sử dụng con trỏ
}
// phần ‘safe’ code không sử dụng con trỏ
}
[/code]
■ Từ khóa unsafe KHÔNG ĐƯỢC DÙNG cho biến cục bộ
{
unsafe int* p; // SAI, không được dùng.
}
[/code]
– Cú pháp để khai báo một kiểu con trỏ trong C# là:
– Để biên dịch và chạy các chương trình trong chế độ unsafe, bạn right click vào Project, sau đó chọn Properties > Build > check chọn Allow unsafe code, xong nhấn tổ hợp phím Ctrl + S để lưu thay đổi, rồi build project:
Code minh họa:
[code language=”csharp”] using System;namespace MinhHoangBlog
{
class KieuConTro
{
static unsafe void Main(string[] args)
{
int* pInt1, pInt2, pInt3; /* pInt1, pInt2, pInt3 là 3 biến con trỏ tham chiếu đến kiểu nguyên */
int** ppInt1; /* ppInt1 là một con trỏ tham chiếu đến con trỏ đến kiểu nguyên */
int*[] ppInt2; /* ppInt2 là một mảng của các con trỏ tham chiếu đến kiểu nguyên */
double* pDbl; /* pDbl là một con trỏ tham chiếu đến kiểu số thực */
char* pChar; /* pChar là một con trỏ tham chiếu đến kiểu ký tự */
void* pVoid; /* pVoid là con trỏ tham chiếu đến kiểu void, KHÔNG NÊN DÙNG tùy ý */
int num = 20;
int* p = # /* Khai báo 1 biến con trỏ p, trỏ vào địa chỉ của biến num */
Console.WriteLine("Gia tri cua bien num: {0} ", num);
Console.WriteLine("Gia tri cua bien num: {0}", p->ToString());
Console.WriteLine("Gia tri cua bien num: {0}", *p);
Console.WriteLine("Dia chi cua bien num: {0}", (int)p);
Console.ReadKey();
}
}
}
[/code]
[…] trong bài viết này mình sẽ hướng dẫn cách chuyển đổi qua lại kiểu dữ liệu User-defined và String với các nội dung […]
[…] Mảng là tập hợp của các phần tử có kích cỡ cố định và có cùng kiểu dữ liệu. Các phần tử trong mảng sẽ nằm tại các vị trí ô nhớ nhớ liền kề nhau. […]
[…] Đối với kiểu dữ liệu có sẵn như: int, double, string,… thì đã được .Net hỗ trợ phương thức so […]
[…] lớp do người dùng định nghĩa (user-defined) có thể có các chức năng như các kiểu dữ liệu có sẵn do ngôn ngữ lập trình đã định […]
[…] kỳ loại dữ liệu cụ thể nào. Khi người dùng khởi tạo mảng với bất kỳ kiểu dữ liệu nào thì trình biên dịch sẽ tự động chuyển đổi kiểu dữ liệu của mảng […]