दिलचस्प पोस्ट
XmlDocument से लाइन ब्रेक के साथ इंडेंडेड एक्सएमएल प्राप्त करने का सबसे आसान तरीका क्या है? एक या अधिक (एकाधिक) पैरामीटर्स के साथ खोज फ़ॉर्म हेडर और पादलेख फ़ाइलों को एकाधिक HTML पृष्ठों में शामिल करने के लिए बनाएं ज्ञात संसाधन नाम के साथ एक संसाधन आईडी कैसे प्राप्त करें? एक संदर्भित कम फ़ाइल सीएसएस में PHP के साथ स्वचालित रूप से संकलित करें Log4j का उपयोग कर किसी डेटाबेस में प्रवेश करें कैसे एक सी # आवेदन में एक VBScript फ़ाइल को कॉल करने के लिए? जांचें कि क्या वर्ष जावा स्क्रिप्ट में वर्ष है मैं अंगूएलजेएस को कैसे "ताज़ा करें" बता सकता हूं कैसे एक पासवर्ड हैश करने के लिए एक std :: नक्शा से आइटम कैसे फ़िल्टर करें? रीसाइक्लियर दृश्य / गतिविधियों के बीच राज्य बहाल / स्टोर एक चार सरणी में एक int स्टोर करें? jquery मोबाइल बाहरी पैनल स्टाइल पर नहीं ले रहा है Google समर्थन पुस्तकालय को अपडेट करने के बाद TextInputLayout इशारा फ़्लोट नहीं करता है

सी मैक्रो परिभाषा बड़े endian या थोड़ा endian मशीन निर्धारित करने के लिए?

क्या मशीन की अंतहीनता निर्धारित करने के लिए एक एक पंक्ति मैक्रो परिभाषा है। मैं निम्नलिखित कोड का उपयोग कर रहा हूं, लेकिन इसे मैक्रो में परिवर्तित करना बहुत लंबा होगा।

unsigned char test_endian( void ) { int test_var = 1; unsigned char test_endian* = (unsigned char*)&test_var; return (test_endian[0] == NULL); } 

वेब के समाधान से एकत्रित समाधान "सी मैक्रो परिभाषा बड़े endian या थोड़ा endian मशीन निर्धारित करने के लिए?"

संहिता के बाइट आदेशों का समर्थन करने वाला कोड, आदेश 32 हो नामक फ़ाइल में डालने के लिए तैयार है:

 #ifndef ORDER32_H #define ORDER32_H #include <limits.h> #include <stdint.h> #if CHAR_BIT != 8 #error "unsupported char size" #endif enum { O32_LITTLE_ENDIAN = 0x03020100ul, O32_BIG_ENDIAN = 0x00010203ul, O32_PDP_ENDIAN = 0x01000302ul }; static const union { unsigned char bytes[4]; uint32_t value; } o32_host_order = { { 0, 1, 2, 3 } }; #define O32_HOST_ORDER (o32_host_order.value) #endif 

आप छोटी एंडियन सिस्टम की जांच करेंगे

 O32_HOST_ORDER == O32_LITTLE_ENDIAN 

यदि आपके पास एक संकलक है जो C99 कम्पाउंड लिटरल्स का समर्थन करता है:

 #define IS_BIG_ENDIAN (!*(unsigned char *)&(uint16_t){1}) 

या:

 #define IS_BIG_ENDIAN (!(union { uint16_t u16; unsigned char c; }){ .u16 = 1 }.c) 

सामान्य तौर पर, आपको उस कोड को लिखने का प्रयास करना चाहिए जो मेजबान प्लेटफ़ॉर्म की अंत्यता पर निर्भर नहीं करता है।


ntohl() -endianness- ntohl() स्वतंत्र कार्यान्वयन का ntohl() :

 uint32_t ntohl(uint32_t n) { unsigned char *np = (unsigned char *)&n; return ((uint32_t)np[0] << 24) | ((uint32_t)np[1] << 16) | ((uint32_t)np[2] << 8) | (uint32_t)np[3]; } 

कोई मानक नहीं है, लेकिन <endian.h> सहित कई प्रणालियों पर आपको कुछ को परिभाषित करने की आवश्यकता होगी।

रनटाइम पर एंडियननेस का पता लगाने के लिए, आपको मेमोरी को संदर्भित करने में सक्षम होना चाहिए। यदि आप मानक सी पर चिपके रहते हैं, तो स्मृति में एक चर की घोषणा करने के लिए एक बयान की आवश्यकता होती है, लेकिन मान वापस करने के लिए अभिव्यक्ति की आवश्यकता होती है मुझे नहीं पता कि यह कैसे एक मैक्रो में करना है-यही कारण है कि जीसीसी के एक्सटेंशन हैं 🙂

यदि आप .h फाइल तैयार करना चाहते हैं, तो आप परिभाषित कर सकते हैं

 static uint32_t endianness = 0xdeadbeef; enum endianness { BIG, LITTLE }; #define ENDIANNESS ( *(const char *)&endianness == 0xef ? LITTLE \ : *(const char *)&endianness == 0xde ? BIG \ : assert(0)) 

और फिर आप के रूप में ENDIANNESS मैक्रो का उपयोग कर सकते हैं।

यदि आप केवल पूर्वप्रक्रमक पर भरोसा करना चाहते हैं, तो आपको पूर्वनिर्धारित प्रतीकों की सूची का पता लगाना होगा। प्रीप्रोसेसर अंकगणित में संबोधित करने की कोई अवधारणा नहीं है।

मैक पर जीसीसी __LITTLE_ENDIAN__ या __BIG_ENDIAN__ को परिभाषित करता है

 $ gcc -E -dM - < /dev/null |grep ENDIAN #define __LITTLE_ENDIAN__ 1 

उसके बाद, आप #ifdef _WIN32 आदि जैसे प्लेटफ़ॉर्म पता लगाने के आधार पर अधिक प्रीप्रोसेसर सशर्त निर्देश जोड़ सकते हैं।

मेरा मानना ​​है कि इस बारे में पूछा गया था। मैंने एमएसवीसी के तहत एक छोटे एंडियन मशीन पर केवल इसका परीक्षण किया। कोई बड़ा एन्डियन मशीन पर किसी चीज की पुष्टि करता है

  #define LITTLE_ENDIAN 0x41424344UL #define BIG_ENDIAN 0x44434241UL #define PDP_ENDIAN 0x42414443UL #define ENDIAN_ORDER ('ABCD') #if ENDIAN_ORDER==LITTLE_ENDIAN #error "machine is little endian" #elif ENDIAN_ORDER==BIG_ENDIAN #error "machine is big endian" #elif ENDIAN_ORDER==PDP_ENDIAN #error "jeez, machine is PDP!" #else #error "What kind of hardware is this?!" #endif 

एक पक्ष नोट (संकलक विशिष्ट) के रूप में, एक आक्रामक संकलक के साथ आप "मृत कोड उन्मूलन" अनुकूलन का उपयोग करके एक समान प्रभाव को प्राप्त कर सकते हैं, जैसे कि संकलन समय #if तरह से:

  unsigned yourOwnEndianSpecific_htonl(unsigned n) { static unsigned long signature= 0x01020304UL; if (1 == (unsigned char&)signature) // big endian return n; if (2 == (unsigned char&)signature) // the PDP style { n = ((n << 8) & 0xFF00FF00UL) | ((n>>8) & 0x00FF00FFUL); return n; } if (4 == (unsigned char&)signature) // little endian { n = (n << 16) | (n >> 16); n = ((n << 8) & 0xFF00FF00UL) | ((n>>8) & 0x00FF00FFUL); return n; } // only weird machines get here return n; // ? } 

उपर्युक्त इस तथ्य पर निर्भर करता है कि कंपाइलर समय के संकलन में निरंतर मूल्यों को पहचानता है, if (false) { ... } पूरी तरह से कोड को हटा दिया जाता if (false) { ... } और जैसे if (true) { foo(); } if (true) { foo(); } साथ foo(); सबसे खराब स्थिति: संकलक ऑप्टिमाइज़ेशन नहीं करता है, आप अभी भी सही कोड प्राप्त करते हैं लेकिन थोड़ा धीमा।

आप एक यौगिक शाब्दिक (सी 99) का उपयोग करके एक अस्थायी वस्तु की स्मृति का उपयोग कर सकते हैं :

 #define IS_LITTLE_ENDIAN (1 == *(unsigned char *)&(const int){1}) 

कौन सी जीसीसी समय संकलन पर मूल्यांकन करेगा।

'सी नेटवर्क लाइब्रेरी' एंडियन'स को संभालने के लिए फ़ंक्शन प्रदान करता है अर्थात् htons (), हंटल (), ntohs () और ntohl () … जहां n "नेटवर्क" है (यानी बड़ी-एंडियन) और h "होस्ट" है (यानी मशीन के अंत्यानुक्रम को चलाना कोड)।

ये स्पष्ट 'फ़ंक्शंस' (सामान्यतः) मैक्रोज़ के रूप में परिभाषित किए जाते हैं [देखें, नेटिनसेट / इन एच>], इसलिए उन्हें उपयोग करने के लिए कोई रनटाइम ओवरहेड नहीं है।

निम्नलिखित मैक्रोज़ 'एंडियन'स का मूल्यांकन करने के लिए इन' फ़ंक्शन 'का उपयोग करते हैं

 #include <arpa/inet.h> #define IS_BIG_ENDIAN (1 == htons(1)) #define IS_LITTLE_ENDIAN (!IS_BIG_ENDIAN) 

के अतिरिक्त:

केवल एक बार जब मुझे कभी सिस्टम की अंत्येष्टि की आवश्यकता हो, तो जब मैं लिखता-लिखता हूं [एक फाइल / अन्य में] जो कि अनजान एंडियन के दूसरे सिस्टम द्वारा पढ़ा जा सकता है (क्रॉस-प्लेटफॉर्म संगतता के लिए) ) … ऐसे मामलों में, आप सीधे एंडियन फ़ंक्शंस का उपयोग करना पसंद कर सकते हैं:

 #include <arpa/inet.h> #define JPEG_MAGIC (('J'<<24) | ('F'<<16) | ('I'<<8) | 'F') // Result will be in 'host' byte-order unsigned long jpeg_magic = JPEG_MAGIC; // Result will be in 'network' byte-order (IE. Big-Endian/Human-Readable) unsigned long jpeg_magic = htonl(JPEG_MAGIC); 

मैक्रो के बजाय इनलाइन फ़ंक्शन का उपयोग करें इसके अलावा, आपको मेमोरी में कुछ स्टोर करने की ज़रूरत है जो मैक्रो का एक बहुत अच्छा पक्ष प्रभाव नहीं है।

आप इसे एक स्थैतिक या वैश्विक चर का उपयोग करके एक संक्षिप्त मैक्रो में परिवर्तित कर सकते हैं, जैसे:

 static int s_endianess = 0; #define ENDIANESS() ((s_endianess = 1), (*(unsigned char*) &s_endianess) == 0) 

हालांकि कोई पोर्टेबल # परिभाषित नहीं है या किसी पर भरोसा करने के लिए, प्लेटफॉर्म आपके 'होस्ट' एंडियन में बदलने और उसके लिए मानक फ़ंक्शन प्रदान करते हैं

आम तौर पर, आप भंडारण करते हैं – डिस्क या नेटवर्क के लिए – 'नेटवर्क एंडियन' का उपयोग करते हुए, जो कि बिग एंडियन है, और मेजबान एंडियन का उपयोग करके स्थानीय कंप्यूटेशन (जो कि x86 पर लिटिल एन्डियन है)। आप दोनों के बीच कन्वर्ट करने के लिए htons() और ntohs() और दोस्तों का उपयोग करें

यदि आप एक संकलित समय परीक्षण की तलाश कर रहे हैं और आप जीसीसी का उपयोग कर रहे हैं, तो आप ऐसा कर सकते हैं:

 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 

अधिक जानकारी के लिए जीसीसी दस्तावेज़ीकरण देखें।

इसे इस्तेमाल करे:

 #include<stdio.h> int x=1; #define TEST (*(char*)&(x)==1)?printf("little endian"):printf("Big endian") int main() { TEST; } 
 #include <stdint.h> #define IS_LITTLE_ENDIAN (*(uint16_t*)"\0\1">>8) #define IS_BIG_ENDIAN (*(uint16_t*)"\1\0">>8) 

यह मत भूलिए कि अंत तक की पूरी कहानी नहीं है – char का आकार 8 बिट (जैसे डीएसपी) नहीं हो सकता है, दो के पूरक निषेध की गारंटी नहीं है (उदाहरण के लिए क्रे), सख्त संरेखण की आवश्यकता हो सकती है (जैसे SPARC, एआरएम भी स्प्रिंग्स में मध्य-एन्डियन जब अनलगित), आदि, आदि

इसके बजाय एक विशिष्ट सीपीयू वास्तुकला को लक्षित करने के लिए यह एक बेहतर विचार हो सकता है।

उदाहरण के लिए:

 #if defined(__i386__) || defined(_M_IX86) || defined(_M_IX64) #define USE_LITTLE_ENDIAN_IMPL #endif void my_func() { #ifdef USE_LITTLE_ENDIAN_IMPL // Intel x86-optimized, LE implementation #else // slow but safe implementation #endif } 

ध्यान दें कि यह समाधान दुर्भाग्य से अति-पोर्टेबल भी नहीं है, क्योंकि यह कंपाइलर-विशिष्ट परिभाषाओं पर निर्भर करता है (कोई मानक नहीं है, लेकिन यहां ऐसी परिभाषाओं का एक अच्छा संकलन है)।

मेरे जवाब के रूप में पूछा नहीं है, लेकिन यह वास्तव में पता लगाना है कि आपका सिस्टम बहुत ही कम है या बड़ा एन्डियन है?

कोड:

 #include<stdio.h> int main() { int a = 1; char *b; b = (char *)&a; if (*b) printf("Little Endian\n"); else printf("Big Endian\n"); } 

यह जांचने के लिए सी कोड है कि कोई सिस्टम छोटा है या बड़े भारतीय है या नहीं।

 int i = 7; char* pc = (char*)(&i); if (pc[0] == '\x7') // aliasing through char is ok puts("This system is little-endian"); else puts("This system is big-endian"); 

चुप देर से … लेकिन अगर आपके पास एक मैक्रो और अल्ट्रा-पोर्टेबल कोड होना चाहिए, तो उसे ढूंढें और इसे अपने निर्मित वातावरण (सेंकक / ऑटोटूल) से सेट करें।

यह सिर्फ यह करने के लिए एक सरल प्रोग्राम है, grepping के लिए उपयुक्त:

 #if __STDC_VERSION__ < 199901L #error "Requires C99 compatibility" #endif #include <stdint.h> #include <stdio.h> const char MAGIC[4] = {0xDE, 0xAD, 0xBE, 0xEF}; int main(void) { uint32_t magical = *(const uint32_t *)MAGIC; switch(magical) { case 0xEFBEADDE: printf("little\n"); break; case 0xDEADBEEF: printf("big\n"); break; case 0xADDEEFBE: printf("pdp\n"); break; default: for(; magical; magical >>= 8) { switch(magical & 0xff) { case 0xDE: printf("3"); break; case 0xAD: printf("2"); break; case 0xBE: printf("1"); break; default: printf("0"); } } printf("\n");} return (0); } 

एंड्रॉन्स खोजने के लिए मैक्रो

 #define ENDIANNES() ((1 && 1 == 0) ? printf("Big-Endian"):printf("Little-Endian")) 

या

 #include <stdio.h> #define ENDIAN() { \ volatile unsigned long ul = 1;\ volatile unsigned char *p;\ p = (volatile unsigned char *)&ul;\ if (*p == 1)\ puts("Little endian.");\ else if (*(p+(sizeof(unsigned long)-1)) == 1)\ puts("Big endian.");\ else puts("Unknown endian.");\ } int main(void) { ENDIAN(); return 0; }