2010-08-10 42 views
5

Tôi đọc sách "C.Sharp 3.0 in a Nutshell" và gặp đoạn mã tiếp theo, điều đó làm tôi quan tâm.Mã không an toàn này hoạt động như thế nào?

unsafe void RedFilter(int[,] bitmap) 
    { 
     int length = bitmap.Length; 
     fixed (int* b = bitmap) 
     { 
     int* p = b; 
     for(int i = 0; i < length; i++) 
      *p++ &= 0xFF; 
     } 
    } 

Bất cứ ai có thể giải thích cho tôi cách hoạt động "* p ++ & = 0xFF" này?

Trả lời

9

Hàm này có lẽ có nghĩa là chụp ảnh bitmap và lọc ra tất cả các màu trừ màu đỏ.

Giả định rằng đó là bitmap 32 bit, trong đó mỗi pixel được biểu thị bằng int. Bạn đang dereferencing vị trí bộ nhớ hiện được trỏ đến bởi p (là int), và ANDING nó với 0xFF, có hiệu quả chỉ để lại thành phần màu đỏ của pixel (giả sử rằng byte thấp nhất là thành phần màu đỏ). Bạn cũng sẽ tự động tăng con trỏ đến int tiếp theo (với ++). Điều đó có trả lời không?

+0

Cảm ơn bạn đã giải thích.Có, tất cả các câu trả lời đều rất hữu ích. –

+0

Vậy tại sao không chấp nhận câu trả lời? –

6

Nó giống như này (IMO bản gốc *p++ &= 0xFF; Bí quyết là một chút khó chịu - đó là một dòng mã đó là làm hai việc):

*p = *p & 0xFF; 
p++; 

Một biểu hiện như a = a & 0xFF bộ tất cả ngoại trừ 8 bit đáy của biến số a bằng không.

+0

Cảm ơn bạn đã giải thích. –

1

Mã này tăng con trỏ p, làm cho nó trỏ tới pixel tiếp theo trong bitmap, sau đó loại bỏ mọi thứ nhưng byte ít quan trọng nhất, trong định dạng Microsoft BMP (và tôi giả định trong các triển khai không chuẩn) khác trong BGR định dạng.

Điều này có tác dụng loại bỏ tất cả các thành phần màu trừ màu đỏ.

+0

Cảm ơn bạn đã giải thích. –

1

Như bạn đã biết,

x &= y 

cũng giống như

x = x & y

Một 'int' anded với '0xff' sẽ đặt tất cả các bit trong cao hơn 3 byte đến 0 (mặt nạ).

Các askterisk được dereferencing con trỏ, vì vậy

*p 

là một số nguyên.

'Tăng bài đăng' cập nhật giá trị con trỏ thực tế để trỏ đến số nguyên tiếp theo trong bộ nhớ. Vì vậy, trong tổng số, mã sẽ chạy qua các số nguyên 'chiều dài' trong bộ nhớ, và loại bỏ tất cả trừ byte thấp nhất (tức là, 'byte' màu đỏ nếu đây là [A] giá trị màu BGR).

+0

Cảm ơn bạn đã giải thích. –

2

Đó là loại cú pháp bạn sẽ tìm thấy trong ngôn ngữ C, cũng cau mày khi ở đó nhưng không phổ biến. Viết ra:

int temp = *p; 
temp = temp & 0x000000ff; 
*p = temp; 
p = p + 1; // Move pointer by 4 bytes. 

Nó phụ thuộc vào định dạng bitmap nếu điều này sẽ hoạt động tốt. Không phổ biến, mã đặt lại alpha của pixel thành 0. Sản xuất một hình ảnh màu đen.

+0

Cảm ơn bạn đã giải thích. –

Các vấn đề liên quan