Tải bản đầy đủ (.pdf) (6 trang)

Những chủ đề tiến bộ trong C# Các mã không an toàn – Phần 3 docx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (104.39 KB, 6 trang )

Những chủ đề tiến bộ trong C#
Các mã không an toàn – Phần 3


Dùng con trỏ để tối ưu hoá thực thi
Sau đây ta sẽ áp dụng những hiểu biết về con trỏ và minh họa 1 ví dụ mà ta
thấy rõ lợi ích của việc dùng con trỏ trong thực thi
Tạo ra mảng có nền là Stack
Để tạo ra mảng này ta cần từ khoá stackalloc. lệnh stackalloc chỉ dẫn thời
gian chạy .NET để cấp phát 1 số vùng nhớ trên stack khi ta gọi nó ,ta cần
cung cấp cho nó 2 thông tin
 Kiểu của biến mà ta muốn lưu trữ
 Ta cần lưu bao nhiêu biến
trong ví dụ , để cấp phát đủ vùng nhớ lưu trữ 10 số thập phân decimal , ta
viết :
decimal *pDecimals = stackalloc decimal [10];
lệnh này chỉ đơn giản cấp phát vùng nhớ. không khởi tạo bất kì giá trị nào.
Để lưu 20 số double ta viết :
double *pDoubles = stackalloc double [20];
mặc dù dòng mã này đặc tả số biến được lưu là hằng, điều này có thể là 1
định giá số lượng vào lúc chạy. vì thế ta có thể viết tương đương với ví dụ
trên như sau :
int size;
size = 20; // or some other value calculated at run-time
double *pDoubles = stackalloc double [size];
Kiểu mảng cơ bản nhất mà có thể có là 1 khối bộ nhớ lưu các phần tử như
sau :

Câu hỏi được đặt ra là làm thế nào ta sử dụng vùng nhớ mà ta vừa tạo.trở lại
ví dụ ta vừa nói rằng giá trị trả về từ stackalloc trỏ đến bắt đầu của vùng
nhớ.do đó cho phép ta có thể lấy vị trí đầu tiên của vùng nhớ được cấp


phát.ví dụ để cấp phát các số double và thiết lập phần tử đầu tiên ( phàn tử
0 của mảng) giá trị 3.0 tacó thể viết :
double *pDoubles = stackalloc double [20];
*pDoubles = 3.0;
Ta có thể thiết lập phần tử thứ 2 của mảng bằng cách dùng cách tính toán
trên con trỏ mà ta đã biết .Ví dụ nếu ta muốn đặt giá trị của phần tử thứ hai
ta làm như sau :
double *pDoubles = stackalloc double [20];
*pDoubles = 3.0;
*(pDoubles+1) = 8.4;
Nó chung ta có thể lấy phần tử thứ X của mảng với biểu thức
*(pDoubles+X)
Bên cạnh đó C# cũng định nghĩa 1 cú pháp thay thế .Nếu p là con trỏ và X là
kiểu số thì biểu thức p[X] tương đương với *(p+X).
double *pDoubles = stackalloc double [20];
pDoubles[0] = 3.0; // pDoubles[0] is the same as *pDoubles
pDoubles[1] = 8.4; // pDoubles[1] is the same as *(pDoubles+1)
Mặc dù mảng của ta có thể được truy xuất theo cùng cách như mảng bình
thường, ta cần quan tâm đến cảnh báo sau . đoạn mã sau đây sẽ gây ra 1 biệt
lệ:
double [] myDoubleArray = new double [20];
myDoubleArray[50] = 3.0;
Biệt lệ xuất hiện vì ta cố truy xuất vào mảng dùng chỉ mục vượt quá mảng (
chỉ mục là 50 , nhưng giá trị lớn nhất cho phép là 19).Tuy nhiên ,nếu ta khai
báo 1 mảng dùng stackalloc , điều đó sẽ không gây ra biệt lệ :
double *pDoubles = stackalloc double [20];
pDoubles[50] = 3.0;
Ví dụ QuickArray
Ta sẽ thảo luận về con trỏ với stackalloc trong ví dụ QuickArray. ví dụ hỏi
người dùng bao nhiêu phần tử họ muốn cấp phát cho mảng. sau đó ta dùng

stackalloc để cấp phát mảng với độ dài đó.các phần tử của mảng này được
gán giá trị là bình phương của chỉ mục của nó .kết quả trình bày bên dưới :
using System;
namespace Wrox.ProCSharp.AdvancedCSharp
{
class MainEntryPoint
{
static unsafe void Main()
{
Console.Write("How big an array do you want? \n> ");
string userInput = Console.ReadLine();
uint size = uint.Parse(userInput);
long *pArray = stackalloc long [(int)size];
for (int i=0 ; i<size ; i++)
pArray[i] = i*i;
for (int i=0 ; i<size ; i++)
Console.WriteLine("Element {0} = {1}", i, *(pArray+i));
}
}
}
QuickArray
How big an array do you want?
> 15
Element 0 = 0
Element 1 = 1
Element 2 = 4
Element 3 = 9
Element 4 = 16
Element 5 = 25
Element 6 = 36

Element 7 = 49
Element 8 = 64
Element 9 = 81
Element 10 = 100
Element 11 = 121
Element 12 = 144
Element 13 = 169
Element 14 = 196

×