2011-11-01 62 views
6

Đã một thời gian kể từ khi tôi lập trình bằng C/C++. Đối với cuộc sống của tôi, tôi không thể nhớ (hoặc tìm thấy trong Google) làm thế nào để thực hiện công việc này. Tôi nghĩ là có một cách viết tắt của việc viết một chuỗi lặp lại của byte, như thế này:Ký hiệu byte viết tắt trong C/C++?

0x00 => 0x00000000 
0xFF => 0xFFFFFFFF 
0xCD => 0xCDCDCDCD 

Vì vậy, ví dụ, nếu tôi tuyên bố

int x = 0xCD; 
printf("%d", x) // prints "3452816845", not "205". 

Nếu không sử dụng bitshifts (ví dụ: Preprocessor xử lý nó). Tôi có phát điên không? PS Tôi đang sử dụng Microsoft Visual C++ 2010

+9

Không có loại nào trong số này tồn tại. –

+1

@Justin: Một trong số chúng tôi phát điên, và tôi không nghĩ đó là tôi! :-) Bạn viết là loại viết tắt nào? Một chuyển đổi định dạng?Một yếu tố lặp lại trong một tuyên bố? Một vòng lặp ngụ ý? – wallyk

+2

Thật khó để tưởng tượng một tính năng như vậy trong C hoặc C++ nếu chỉ vì không có nhiều nơi hữu ích. –

Trả lời

2

Trừ khi bạn viết macro của riêng mình, điều này là không thể. Làm thế nào nó sẽ biết bao lâu để lặp lại? 0xAB có thể có nghĩa là 0xABABABABABABABABABABAB cho tất cả những gì nó biết (sử dụng ý tưởng được đề xuất).

+0

Nó sẽ lặp lại nó tùy thuộc vào loại. – Jay

+1

Nếu điều này là cần thiết, hãy sử dụng macro như đề xuất của tôi và duskwuff. – jli

+1

@Justin: Không, nó sẽ không. C và C++ không khởi tạo theo cách đó. Có kiểu khởi tạo, kiểu biến, và cách chuyển đổi từ biến này sang biến khác. Giá trị và kiểu của bộ khởi tạo không bị ảnh hưởng bởi kiểu biến. Bạn có chắc là bạn đang nghĩ đến C hay C++? –

2

Không có cách viết tắt như vậy. 0x00 giống với 0. 0xFF giống với 0x000000FF.

+2

... mặc dù '0x00' là hex và' 0' là bát phân. :-) –

8

Không có gì giống như vậy theo mặc định trong C. Có điều gì đó tương tự trong CSS (màu #123 được mở rộng thành #112233), nhưng điều đó hoàn toàn khác. :)

Bạn có thể viết một macro để làm điều đó cho bạn, tuy nhiên, như:

#define REPEAT_BYTE(x) ((x) | ((x) << 8) | ((x) << 16) | ((x) << 24)) 
... 
int x = REPEAT_BYTE(0xcd); 
1

Bạn có thể sử dụng một số mẫu thủ đoạn gian trá:

#include <iostream> 
#include <climits> 

using namespace std; 

template<typename T, unsigned char Pattern, unsigned int N=sizeof(T)> 
struct FillInt 
{ 
    static const T Value=((T)Pattern)<<((N-1)*CHAR_BIT) | FillInt<T, Pattern, N-1>::Value; 
}; 

template<typename T, unsigned char Pattern> 
struct FillInt<T, Pattern, 0> 
{ 
    static const T Value=0; 
}; 

int main() 
{ 
    cout<<hex<<FillInt<unsigned int, 0xdc>::Value<<endl; // outputs dcdcdcdc on 32 bit machines 
} 

mà tự động điều chỉnh để loại không thể thiếu qua như là đối số đầu tiên và được giải quyết hoàn toàn tại thời gian biên dịch, nhưng đây chỉ là để giải trí, tôi không nghĩ rằng tôi muốn sử dụng một điều như vậy trong mã thực.

13

Cách đơn giản nhất là:

0x1010101u * x 

Tôi không thể nghĩ ra bất kỳ cú pháp mà có thể có thể được đơn giản trở lên tự giải thích ...

Edit: Tôi thấy bạn muốn nó để làm việc cho các loại tùy ý. Vì nó chỉ có ý nghĩa cho các loại unsigned, tôi sẽ giả sử bạn đang sử dụng một loại unsigned. Sau đó, hãy thử

#define REPB(t, x) ((t)-1/255 * (x)) 
+3

Thật tuyệt vời! –

2

Không. Nhưng bạn có thể sử dụng memset:

int x; 
memset(&x, 0xCD, sizeof(x)); 

Và bạn có thể làm một vĩ mô về điều đó:

#define INITVAR(var, value) memset(&(var), (int)(value), sizeof(var)) 
int x; 
INITVAR(x, 0xCD); 
1

Bạn có thể sử dụng tiền xử lý nối mã thông báo:

#include <stdio.h> 
#define multi4(a) (0x##a##a##a##a) 

int main() 
{ 
    int a = multi4(cd); 
    printf("0x%x\n", a); 
    return 0; 
} 

Kết quả:

0xcdcdcdcd 

Tất nhiên, y Bạn phải tạo macro mới mỗi lần bạn muốn tạo "trình tạo" với số lần lặp lại khác nhau.