Wednesday, June 4, 2014

Enumerations (enum) - Kiểu dữ liệu enum


Giới Thiệu:
Enumerations về cơ bản cấu trúc dữ liệu.
Chúng cho phép bạn:
  • tạo ra một khối dữ liệu và thiết lập giá trị khác nhau vào nó.
  • tạo ra các hằng số của riêng bạn với incrementing tự động.
  • tạo ra các thẻ của riêng bạn cho các biến.


Cú Pháp Cơ Bản:

cú pháp cơ bản của enum như bên dưới:
Code:
enum [[_:]TagName] [(IncrementType)]
{
    [TagForConstant:]Constant1 [= Value1],
    [TagForConstant:]Constant2 [= Value2],
    ...
    [TagForConstant:]ConstantN [= ValueN]
}
Chúng ta hãy phân tích từng phần của cú pháp:
  • Đầu tiên, dữ liệu gói gọn trong dấu ngoặc vuông [] là tùy chọn cho các cú pháp.
  • [_:]TagName
    Đây là tên của thẻ mà bạn sẽ được tạo ra.
    Tên thẻ có giá trị đó là kích thước của enum, đó là giá trị không đổi cuối cùng + 1.
    Nếu bạn đặt các optional_: trước tên thẻ, có nghĩa là nó không còn là một từ khóa.
  • (IncrementType)
    Đây là phương pháp được sử dụng để cung cấp cho mỗi hằng số một giá trị trong enuma.
    Cú pháp cho điều này là: Toán tử =  giá trị
    Mặc định cho điều này là (+ = 1) để mỗi liên tục là 1 nhiều hơn liên tục trước đó.
  • [TagForConstant:]Constant1 [= Value1]
    Đây là tên của hằng số đó đang được tạo ra và cũng tùy chọn cho nó một giá trị. Hằng số đầu tiên là 0 nếu nó không được đưa ra một giá trị. Hãy nhớ rằng, hằng số cuối cùng được liệt kê không có một dấu phẩy sau nó! 


Tạo Tags:

Tạo ra các thẻ của riêng bạn là dễ dàng.
Đây là một ví dụ của thẻ bool:
Code:
enum bool
{
    false,
    true
}
Nó tạo ra thẻ bool, và tạo ra 2 hằng số.
False tương đương với bool: 0 bởi vì hằng số đầu tiên bắt đầu từ 0.
true tương đương với bool: 1 vì tăng mặc định là hằng số trước khi nó + 1.
bool cũng là một hằng số bằng bool: 2, bởi vì đúng là hằng số mới nhất và hiện bool: 1.

Tạo ra các thẻ cho xử lý được thực hiện với một enum  để tạo ra thẻ và một hằng số định nghĩa cho một tay cầm.
Ví Dụ:
Code:
enum Array
{
    Invalid_Array = 0
}
Điều này tạo ra những mảng tag cho cellarrays và cũng là một Invalid_Array hằng số đó là bằng một mảng xử lý không hợp lệ.


Sử dụng khóa trên biến:

Sử dụng các thẻ đơn giản. Nếu bạn đã làm việc với bools hoặc Floats trong amxx trước, sau đó bạn đã sử dụng thẻ trước.
Bạn có thể tạo ra các biến được gắn thẻ với một từ khóa cụ thể:
Code:
new myInteger = 1
new bool:myBoolean = true
new Float:myFloat = 1.0
Hãy nhớ rằng các biến sử dụng các thẻ đã định nghĩa hằng số không giới hạn cho những hằng số.
Example:
Code:
new bool:myBoolean = bool:2
Vấn đề với cách làm như vậy là đúng và sai là chỉ có 1 và 0 tương ứng, vì vậy nếu bạn kiểm tra biến cho đúng, nó sẽ nói nó không phải là là True.


Constants - Hằng Số:

Enumerations có thể hữu ích để tạo ra một danh sách các hằng số mà không cần phải xác định mỗi một.
Ví Dụ:
Code:
#define CONSTANT1 0
#define CONSTANT2 1
#define CONSTANT3 2
#define CONSTANT_SIZE 3
Điều này có thể gây phiền nhiễu để cố gắng thêm / sửa / xóa các hằng số bởi vì bạn có thể phải chỉnh sửa nhiều hơn một dòng.
Đây là cách một enum  sẽ xem xét cho điều này:
Code:
enum _:CONSTANT_SIZE
{
    CONSTANT1,
    CONSTANT2,
    CONSTANT3
}
Bạn có thể làm một cái gì đó như thế này để tạo ra một danh sách các hằng số đại diện cho bit:
Code:
enum (<<= 1) // each value is the value before it shifted left once
{
    BIT1 = 1, // start with 1 because that is the first bit
    BIT2,     // 1 << 1 = 2
    BIT3,     // 2 << 1 = 4
    BIT4      // 4 << 1 = 8
}
Nếu bạn có các hằng số được xác định cho nhiệm vụ người chơi để bạn có thể có nhiệm vụ khác nhau cho mỗi người chơi cùng một lúc, bạn có thể có điều này:
Code:
#define TASK_ID_1 1000
#define TASK_ID_2 2000
#define TASK_ID_3 3000

// ...

set_task(1.0, "TaskHandler", id + TASK_ID_1)

// ...

public TaskHandler(taskid)
{
    new id = taskid - TASK_ID_1
}
Bạn cũng có thể có giá trị hằng số khác nhau cho id nhiệm vụ của bạn, vì vậy bạn có thể làm điều này dễ dàng để sao chép phong cách hiển thị:
Code:
enum (+= 1000) // task ids are 1000 apart
{
    TASK_ID_1 = 1000, // start with 1000
    TASK_ID_2,
    TASK_ID_3
}


Data structures - Cấu trúc dữ liệu:

Cấu trúc dữ liệu cho phép bạn đặt các loại khác nhau của dữ liệu trong một mảng.
Đây là một mã số ví dụ mà có thể sử dụng một cấu trúc dữ liệu:
Code:
new g_iKills[ 33 ]
new g_iDeaths[ 33 ]
new Float:g_flSpeed[ 33 ];

// g_iKills[ id ] = kills for id
// g_iDeaths[ id ] = deaths for id
// g_flSpeed[ id ] = run speed for id
Để đưa điều này vào một cấu trúc dữ liệu, bạn có thể làm điều này:
Code:
enum _:PlayerData
{
    Player_Kills,
    Player_Deaths,
    Float:Player_Speed
}

new g_ePlayerData[ 33 ][ PlayerData ]

// g_ePlayerData[ id ][ Player_Kills ] = kills for id
// g_ePlayerData[ id ][ Player_Deaths ] = deaths for id
// g_ePlayerData[ id ][ Player_Speed ] = run speed for id
Khi sử dụng thẻ cho các hằng số cấu trúc được sử dụng như một chỉ số mảng (ví dụ Player_Speed​​), bạn có thể cần phải gắn thẻ mảng chính nó khi thiết lập / nhận được một giá trị. 
Example:
Code:
g_ePlayerData[ id ][ Player_Speed ] = 250.0
// If the above code gives a tag mismatch warning, you can change it to this:
g_ePlayerData[ id ][ Player_Speed ] = _:250.0

// ...

if( g_ePlayerData[ id ][ Player_Speed ] == 250.0 )
// If the above code gives a tag mismatch warning, you can change it to this:
if( Float:g_ePlayerData[ id ][ Player_Speed ] == 250.0 )
Với cấu trúc dữ liệu, bạn thậm chí có thể tạo ra các mảng và chuỗi.
Example:
Code:
new g_szName[ 33 ][ 32 ];
new g_szAuthID[ 33 ][ 32 ];
new g_iUserID[ 33 ];

// can be changed to

enum _:PlayerInfo
{
    Player_Name[ 32 ],
    Player_AuthID[ 35 ],
    Player_UserID
}

new g_ePlayerData[ 33 ][ PlayerInfo ]
Khi sử dụng các mảng và chuỗi bên trong cấu trúc dữ liệu, có một vài quy tắc:
Code:
sizeof( Player_Name )
charsmax( Player_Name )
Những 2 dòng là không hợp lệ vì Player_Name không phải là một biến có kích thước.
Các Player_Name hằng chỉ bảo chỉ số 0-31 cho cấu trúc dữ liệu, và Player_AuthID bắt đầu là 32 và dừng lại ở 66.
Để có được kích thước của những mảng / chuỗi từ một cấu trúc dữ liệu, có 2 cách:

Method #1:
Code:
Player_AuthID // sizeof( Player_Name )
Player_AuthID - 1 // charsmax( Player_Name )
// ...
Player_UserID - Player_AuthID // sizeof( Player_AuthID )
Player_UserID - Player_AuthID - 1 // charsmax( Player_AuthID )
Method #2:
Code:
new eTempData[ PlayerData ]
// ...
sizeof( eTempData[ Player_Name ] )
charsmax( eTempData[ Player_Name ] )
// ...
sizeof( eTempData[ Player_AuthID ] )
charsmax( eTempData[ Player_AuthID ] )
Method #2  là cách tốt nhất vì nó đảm bảo kích thước thích hợp trong trường hợp một enum được sửa đổi. 
Ngoài ra, nó sẽ là cách thiết thực nhất kể từ khi lý do duy nhất bạn đang sử dụng một cấu trúc dữ liệu là tạo ra một mảng có sử dụng nó. 
Vì vậy, bạn nên sử dụng các biến có sử dụng các cấu trúc dữ liệu để có thể đọc. 

Khi sử dụng các mảng biến có kích thước bằng một cấu trúc dữ liệu trong chức năng, cấu trúc dữ liệu không thể có một thẻ.
Example:
Code:
enum PlayerData // PlayerData is a tag
{
    Player_Kills,
    Player_Deaths,
    Float:Player_Speed
}

// ...

new ePlayerData[ PlayerData ]
ePlayerData[ Player_Kills ] = 0
ePlayerData[ Player_Deaths ] = 0
ePlayerData[ Player_Speed ] = 250.0

// this line will throw an error
// because it does not accept arrays from data structures that are tagged
set_task( 1.0, "TaskSetPlayerData", id, ePlayerData, PlayerData )
Để khắc phục điều đó, bạn chỉ cần untag cấu trúc dữ liệu:
Code:
enum _:PlayerData // PlayerData is no longer a tag
{
    Player_Kills,
    Player_Deaths,
    Float:Player_Speed
}

// ...

new ePlayerData[ PlayerData ]
ePlayerData[ Player_Kills ] = 0
ePlayerData[ Player_Deaths ] = 0
ePlayerData[ Player_Speed ] = 250.0

// this line will work properly
set_task( 1.0, "TaskSetPlayerData", id, ePlayerData, PlayerData )

0 nhận xét:

Post a Comment