मैंने हाल ही में C में ऐसा करने के लिए एक मैक्रो लिखा है, लेकिन यह C ++ में समान रूप से मान्य है:
#define REVERSE_BYTES(...) do for(size_t REVERSE_BYTES=0; REVERSE_BYTES<sizeof(__VA_ARGS__)>>1; ++REVERSE_BYTES)\
((unsigned char*)&(__VA_ARGS__))[REVERSE_BYTES] ^= ((unsigned char*)&(__VA_ARGS__))[sizeof(__VA_ARGS__)-1-REVERSE_BYTES],\
((unsigned char*)&(__VA_ARGS__))[sizeof(__VA_ARGS__)-1-REVERSE_BYTES] ^= ((unsigned char*)&(__VA_ARGS__))[REVERSE_BYTES],\
((unsigned char*)&(__VA_ARGS__))[REVERSE_BYTES] ^= ((unsigned char*)&(__VA_ARGS__))[sizeof(__VA_ARGS__)-1-REVERSE_BYTES];\
while(0)
यह किसी भी प्रकार को स्वीकार करता है और पारित तर्क में बाइट्स को उलट देता है। उदाहरण usages:
int main(){
unsigned long long x = 0xABCDEF0123456789;
printf("Before: %llX\n",x);
REVERSE_BYTES(x);
printf("After : %llX\n",x);
char c[7]="nametag";
printf("Before: %c%c%c%c%c%c%c\n",c[0],c[1],c[2],c[3],c[4],c[5],c[6]);
REVERSE_BYTES(c);
printf("After : %c%c%c%c%c%c%c\n",c[0],c[1],c[2],c[3],c[4],c[5],c[6]);
}
कौन सा प्रिंट:
Before: ABCDEF0123456789
After : 8967452301EFCDAB
Before: nametag
After : gateman
उपरोक्त पूरी तरह से कॉपी / पेस्ट-सक्षम है, लेकिन यहां बहुत कुछ चल रहा है, इसलिए मैं नीचे तोड़ दूँगा कि यह टुकड़े द्वारा कैसे काम करता है:
पहली उल्लेखनीय बात यह है कि एक do while(0)
खंड में पूरा मैक्रो संलग्न है । यह एक सामान्य मुहावरा हैमैक्रो के बाद सामान्य अर्धविराम उपयोग की अनुमति देने के लिए है।
अगला ऊपर लूप के काउंटर के REVERSE_BYTES
रूप में नामित चर का उपयोग है for
। मैक्रो का नाम ही एक चर नाम के रूप में उपयोग किया जाता है ताकि यह सुनिश्चित किया जा सके कि यह किसी भी अन्य प्रतीकों के साथ नहीं टकराता है जो कि मैक्रो का उपयोग करने के लिए गुंजाइश हो सकती है। चूंकि मैक्रो के विस्तार के भीतर नाम का उपयोग किया जा रहा है, इसलिए इसे फिर से विस्तारित नहीं किया जाएगा जब यहां एक चर नाम के रूप में उपयोग किया जाता है।
for
लूप के भीतर , दो बाइट्स संदर्भित किए जा रहे हैं और XOR स्वैप किए गए हैं (इसलिए एक अस्थायी चर नाम की आवश्यकता नहीं है):
((unsigned char*)&(__VA_ARGS__))[REVERSE_BYTES]
((unsigned char*)&(__VA_ARGS__))[sizeof(__VA_ARGS__)-1-REVERSE_BYTES]
__VA_ARGS__
मैक्रो को जो कुछ भी दिया गया था उसका प्रतिनिधित्व करता है, और जो पास हो सकता है उसके लचीलेपन को बढ़ाने के लिए उपयोग किया जाता है (यद्यपि बहुत से नहीं)। इस तर्क का पता तब लगाया जाता है और एक unsigned char
सूचक के लिए डाली जाती है, जो सरणी ब्रीडिंग के माध्यम से अपने बाइट्स की अदला-बदली की अनुमति देता है []
।
अंतिम अजीब बिंदु {}
ब्रेसिज़ की कमी है । वे आवश्यक नहीं हैं क्योंकि प्रत्येक स्वैप में सभी चरण अल्पविराम ऑपरेटर के साथ जुड़ जाते हैं , जिससे वे एक बयान देते हैं।
अंत में, यह ध्यान देने योग्य है कि यह आदर्श दृष्टिकोण नहीं है यदि गति एक सर्वोच्च प्राथमिकता है। यदि यह एक महत्वपूर्ण कारक है, तो अन्य उत्तरों में संदर्भित प्रकार-विशिष्ट मैक्रो या प्लेटफ़ॉर्म-विशिष्ट निर्देशों में से कुछ बेहतर विकल्प होने की संभावना है। यह दृष्टिकोण, हालांकि, सभी प्रकारों, सभी प्रमुख प्लेटफार्मों और सी और सी ++ दोनों भाषाओं के लिए पोर्टेबल है।