2014-06-13 13 views
56

Các manpage nói về memset:Cách bộ nhớ khởi tạo một mảng các số nguyên bằng -1?

#include <string.h> 
void *memset(void *s, int c, size_t n) 

Chức năng memset() lấp đầy đầu tiên nbyte của vùng nhớ được trỏ đến bởi s với byte liên tục c.

Rõ ràng là memset không thể được sử dụng để khởi int mảng như hình dưới đây:

int a[10]; 
memset(a, 1, sizeof(a)); 

đó là vì int được đại diện bởi 4 byte (nói) và người ta không thể có được những mong muốn giá trị cho các số nguyên trong mảng a.
Nhưng tôi thường thấy các lập trình viên sử dụng memset để đặt các thành phần mảng int thành 0 hoặc -1.

int a[10]; 
int b[10]; 
memset(a, 0, sizeof(a)); 
memset(b, -1, sizeof(b)); 

Theo hiểu biết của tôi, khởi tạo với số nguyên 0 là OK vì 0 thể được biểu diễn trong 1 byte (có thể tôi sai trong bối cảnh này). Nhưng làm cách nào để có thể khởi tạo b với -1 (giá trị 4 byte)?

+23

Người bỏ phiếu, quan tâm giải thích? Câu hỏi đó có liên quan đến trang web này hay cái gì khác không? – haccks

+0

Bạn hơi sai về lý do khởi tạo với '0' là OK. Nó là OK bởi vì '0' phù hợp trong một' unsigned char' (vì vậy nó không bị cắt bớt khi được sử dụng làm đối số thứ hai cho 'memset') * và * vì mẫu bit trong bộ nhớ cho một' sizeof (int) '-byte số không giống với mẫu bit trong bộ nhớ cho các số không byte một byte 'sizeof (int)'. Cả hai điều đó đều đúng cho việc này. Trong thực tế, những điều đó là đúng cho hai con số chính xác trong số học bổ sung twos: '0' và' -1'. – zwol

Trả lời

65

Nhưng kỳ lạ, nguyên nhân này làm việc với -1 là chính xác giống như lý do mà công trình này với số không: trong two's complement binary representation, -11 s trong tất cả các bit của nó, không phụ thuộc vào kích thước của số nguyên, vì vậy điền vào một khu vực với các byte được điền đầy đủ với tất cả 1 s tạo ra một vùng gồm -1 đã ký int s, long s và short s trên phần cứng bổ sung của hai.

Trên phần cứng khác với phần bổ sung của hai, kết quả sẽ khác. Hằng số -1 số nguyên sẽ được chuyển đổi thành một số unsigned char của tất cả những cái, vì tiêu chuẩn là cụ thể về cách thực hiện chuyển đổi. Tuy nhiên, một vùng byte với tất cả các bit của chúng được đặt là 1 sẽ được hiểu là các giá trị tích phân theo các quy tắc của nền tảng. Ví dụ: trên phần cứng ký hiệu và độ lớn, tất cả các phần tử trong mảng của bạn sẽ chứa giá trị âm nhỏ nhất của loại tương ứng.

+15

Không sử dụng '~ 0' có hiệu quả giống nhau (và rõ ràng hơn) không? –

+2

@FiddlingBits Có, sử dụng '~ 0' chắc chắn sẽ tránh được sự nhầm lẫn ở đây. – dasblinkenlight

+0

Tôi đã nhận được câu trả lời của bạn nhưng bạn có thể giải thích dòng này: * để điền vào một vùng với -1 byte tạo ra một vùng gồm -1 ký tự ints, longs và shorts. *? – haccks

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