2011-12-30 31 views

Trả lời

14

Bạn có thể nhận các byte bằng cách sử dụng một số con trỏ số học:

int x = 12578329; // 0xBFEE19 
for (size_t i = 0; i < sizeof(x); ++i) { 
    // Convert to unsigned char* because a char is 1 byte in size. 
    // That is guaranteed by the standard. 
    // Note that is it NOT required to be 8 bits in size. 
    unsigned char byte = *((unsigned char *)&x + i); 
    printf("Byte %d = %u\n", i, (unsigned)byte); 
} 

Trên máy tính của tôi (Intel x86-64), đầu ra là:

Byte 0 = 25 // 0x19 
Byte 1 = 238 // 0xEE 
Byte 2 = 191 // 0xBF 
Byte 3 = 0 // 0x00 
+1

Làm thế nào 4294967278 là một byte? Kiểu 'char' mặc định có thể được ký trên hệ thống của bạn và đưa vào' unsigned' để tạo ra các số lớn. –

+0

@Eser Aygün Tôi sẽ cập nhật mã. Cảm ơn bạn đã bình luận. –

+0

Bất kỳ lý do nào để sử dụng số học con trỏ thủ công thay vì truy cập mảng dễ đọc hơn nhiều? –

3

Nếu bạn muốn nhận thông tin đó, hãy nói cho:

int value = -278; 

(Tôi đã chọn giá trị đó vì nó không quan tâm lắm ing cho 125 - byte trọng số thấp nhất là 125 và các byte khác đều 0)

Trước tiên, bạn cần một con trỏ đến giá trị mà:

int* pointer = &value; 

Bây giờ bạn có thể định kiểu đó để một 'char' con trỏ! chỉ có một byte và nhận các byte riêng lẻ bằng cách lập chỉ mục.

for (int i = 0; i < sizeof(value); i++) { 
    char thisbyte = *(((char*) pointer) + i); 
    // do whatever processing you want. 
} 

Lưu ý rằng thứ tự byte cho int và các loại dữ liệu khác phụ thuộc vào hệ thống của bạn - tra cứu 'big-endian' vs 'little-endian'.

+0

Bất kỳ lý do nào để sử dụng số học con trỏ thủ công thay vì truy cập mảng dễ đọc hơn nhiều? –

+0

Bởi vì nó làm cho nó rõ ràng cho những người được giáo dục rằng chúng tôi đang sử dụng một con trỏ? Tôi không xem xét số học con trỏ là sai hoặc không đọc được. – Dan

+1

Không sai, nhưng chắc chắn bạn không cho rằng nó có thể đọc được như truy cập mảng…! So sánh '* (x + i)' với 'x [i]'. Trên thực tế, tại sao tất cả cú pháp truy cập mảng tồn tại, nếu chúng ta không sử dụng nó khi thích hợp? –

2

này nên làm việc:

int x = 125; 
unsigned char *bytes = (unsigned char *) (&x); 
unsigned char byte0 = bytes[0]; 
unsigned char byte1 = bytes[1]; 
... 
unsigned char byteN = bytes[sizeof(int) - 1]; 

Nhưng lưu ý rằng thứ tự byte số nguyên phụ thuộc nền tảng.

+0

thứ tự byte phụ thuộc vào CPU không phụ thuộc vào hệ điều hành – DipSwitch

+0

@DipSwitch Bạn nói đúng. Đã sửa. –

3

Bạn có thể tận dụng một union nhưng hãy nhớ rằng thứ tự byte là phụ thuộc bộ xử lý và được gọi là Endian http://en.wikipedia.org/wiki/Endianness

#include <stdio.h> 
#include <stdint.h> 

union my_int { 
    int val; 
    uint8_t bytes[sizeof(int)]; 
}; 

int main(int argc, char** argv) { 
    union my_int mi; 
    int idx; 

    mi.val = 128; 

    for (idx = 0; idx < sizeof(int); idx++) 
     printf("byte %d = %hhu\n", idx, mi.bytes[idx]); 

    return 0; 
} 
+0

@WTP ah lol, thậm chí không nhận thấy: p – DipSwitch

14

Bạn cần phải biết số bit (thường 8) trong từng "byte ". Sau đó, bạn có thể trích xuất từng byte bằng cách ANDing int với mặt nạ thích hợp. Hãy tưởng tượng rằng một int là 32 bit, sau đó để có được 4 byte ra khỏi the_int:

int a = (the_int >> 24) & 0xff; // high-order (leftmost) byte: bits 24-31 
    int b = (the_int >> 16) & 0xff; // next byte, counting from left: bits 16-23 
    int c = (the_int >> 8) & 0xff; // next byte, bits 8-15 
    int d = the_int   & 0xff; // low-order byte: bits 0-7 

Và có bạn có nó: mỗi byte là trong bậc thấp 8 bit của a, b, c, và d.

+0

Bạn đang làm cho nó khó hơn nó và sử dụng chuyển dịch để trích xuất byte là khá nhiều CPU. Nó sẽ đơn giản hơn và nhanh hơn để truy cập từng vị trí byte trực tiếp trong bộ nhớ ... – DipSwitch

+0

@Dip - cách thô lỗ của tôi có đức tính là nó di động trên các CPU, trong khi những người khác có thể không. Nhưng như bạn muốn, tất nhiên. –

+1

+1: Tôi xem xét điều này tốt hơn nhiều so với không quan trọng với vị trí bộ nhớ. 1) nếu là endian-agnostic. 2) CPU có thể thực hiện các thao tác trong thanh ghi bộ xử lý, vì vậy nó thường hiệu quả hơn nhiều. Trong thực tế, đối với một số máy (8 bit), điều này có thể không tạo ra bất kỳ mã nào cả (nếu bạn có trình biên dịch tốt). – Lindydancer

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