সি-তে uint8_t
ওভার ব্যবহারের সুবিধা কী unsigned char
?
আমি জানি যে প্রায় প্রতিটি সিস্টেমে uint8_t
কেবল একটি টাইপিডেফ হয় unsigned char
, তবে কেন এটি ব্যবহার করবেন?
সি-তে uint8_t
ওভার ব্যবহারের সুবিধা কী unsigned char
?
আমি জানি যে প্রায় প্রতিটি সিস্টেমে uint8_t
কেবল একটি টাইপিডেফ হয় unsigned char
, তবে কেন এটি ব্যবহার করবেন?
উত্তর:
এটি আপনার উদ্দেশ্যটি দলিল করে - আপনি একটি চরিত্রের চেয়ে কম সংখ্যক সঞ্চয় করবেন।
এছাড়াও আপনার যেমন অন্যান্য typedefs ব্যবহার করছেন সুন্দর দেখায় uint16_t
বা int32_t
।
unsigned char
বা signed char
নথিবদ্ধ করে তোলে, যেহেতু অপরিজ্ঞাতভাবে char
এটি আপনাকে অক্ষরের সাথে কাজ করছেন তা দেখায়।
unsigned
ছিল unsigned int
সংজ্ঞা দিয়ে?
char
একটি চরিত্রকে বোঝায় বলে মনে হচ্ছে, যেখানে কোনও ইউটিএফ 8 স্ট্রিংয়ের প্রসঙ্গে এটি মাল্টবাইট চরিত্রের কেবল একটি বাইট হতে পারে। Uint8_t ব্যবহার করে এটি স্পষ্ট হয়ে উঠতে পারে যে প্রতিটি অবস্থানে একটি চরিত্রের আশা করা উচিত নয় - অন্য কথায় স্ট্রিং / অ্যারের প্রতিটি উপাদান একটি স্বেচ্ছাসেবী পূর্ণসংখ্যা যা সম্পর্কে কোনও শব্দার্থিক অনুমান করা উচিত নয়। অবশ্যই সমস্ত সি প্রোগ্রামাররা এটি জানেন তবে এটি প্রাথমিকভাবে সঠিক প্রশ্ন জিজ্ঞাসা করতে চাপ দিতে পারে।
কেবলমাত্র পেডেন্টিক হতে, কিছু সিস্টেমে 8 বিট টাইপ নাও থাকতে পারে। উইকিপিডিয়া অনুসারে :
N = 8, 16, 32, বা 64 এর জন্য সঠিক-প্রস্থের পূর্ণসংখ্যার ধরণের সংজ্ঞা দিতে একটি বাস্তবায়নের প্রয়োজন হয় এবং কেবল যদি এর প্রয়োজনীয়তা মেলে এমন কোনও ধরণের থাকে। এটি অন্য কোনও এন এর জন্য তাদের সংজ্ঞায়িত করার প্রয়োজন হয় না, এমনকি যদি এটি উপযুক্ত ধরণের সমর্থন করে।
সুতরাং uint8_t
অস্তিত্বের নিশ্চয়তা নেই, যদিও এটি সমস্ত প্ল্যাটফর্মের জন্য যেখানে 8 বিট = 1 বাইট রয়েছে। কিছু এম্বেড থাকা প্ল্যাটফর্ম আলাদা হতে পারে তবে এটি খুব বিরল getting কিছু সিস্টেম char
16 বিট হিসাবে প্রকারগুলি সংজ্ঞায়িত করতে পারে, এক্ষেত্রে সম্ভবত কোনও 8-বিট ধরণের হবে না।
এটি (নাবালক) ইস্যু ব্যতীত @ মার্ক র্যানসমের উত্তর আমার মতে সেরা। আপনি যেটি ডেটা ব্যবহার করছেন তা সর্বাধিক স্পষ্টভাবে দেখায় এমন একটি ব্যবহার করুন।
এছাড়াও, আমি ধরে নিচ্ছি যে আপনি বোঝাচ্ছেন uint8_t
(সি 99 এর মানক টাইপডেফটি stdint.h
শিরোনামে সরবরাহ করা হয়েছে ) পরিবর্তে uint_8
(কোনও মানের অংশ নয়)।
uint8_t
(বা এটি এটিকে টাইপ করতে হবে )। এটি কারণ 8 বিট প্রকারের স্টোরেজ উপস্থাপনায় অব্যবহৃত বিট থাকবে যা uint8_t
অবশ্যই তা নয়।
typedef unsigned integer type uint8_t; // optional
সুতরাং, প্রকৃতপক্ষে, uint8_t সংজ্ঞা দেওয়ার জন্য কোনও সি ++ স্ট্যান্ডার্ড অনুসারে গ্রন্থাগারের প্রয়োজন নেই (মন্তব্য দেখুন // alচ্ছিক )
পুরো বিষয়টি হ'ল বাস্তবায়ন-স্বাধীন কোড লিখতে। unsigned char
8-বিট প্রকারের গ্যারান্টি নেই। uint8_t
(যদি উপলব্ধ থাকে) হয়।
sizeof(unsigned char)
ফিরে আসবে 1
। তবে যদি কোনও সিস্টেমের চর এবং INT একই আকারের হয়, উদাহরণস্বরূপ, 16-বিটগুলি তখনও sizeof(int)
ফিরে আসবে1
যেমনটি আপনি বলেছেন, " প্রায় প্রতিটি সিস্টেম"।
char
সম্ভবত পরিবর্তিত হওয়ার সম্ভাবনাগুলির মধ্যে একটি হ'ল তবে আপনি একবার uint16_t
এবং বন্ধুবান্ধব ব্যবহার শুরু করার সাথে uint8_t
মিশ্রণগুলি আরও ভাল ব্যবহার করতে শুরু করেছেন এবং কোডিং স্ট্যান্ডার্ডের একটি অংশও হতে পারে।
আমার অভিজ্ঞতায় দুটি জায়গা রয়েছে যেখানে আমরা 8 টি বিট (এবং uint16_t ইত্যাদি) বোঝাতে uint8_t ব্যবহার করতে চাই এবং যেখানে আমাদের 8 বিটের চেয়ে কম ক্ষেত্র থাকতে পারে। উভয় জায়গাতেই স্থানের বিষয়টি গুরুত্বপূর্ণ এবং ডিবাগ করার সময় আমাদের প্রায়শই ডেটার একটি কাঁচা ডাম্প দেখতে হবে এবং এটি কী উপস্থাপন করে তা দ্রুত নির্ধারণ করতে সক্ষম হওয়া দরকার।
প্রথমটি আরএফ প্রোটোকলগুলিতে, বিশেষত সংকীর্ণ-ব্যান্ড সিস্টেমগুলিতে। এই পরিবেশে আমাদের একক বার্তায় যতটা সম্ভব তথ্য প্যাক করতে হবে। দ্বিতীয়টি ফ্ল্যাশ স্টোরেজে যেখানে আমাদের খুব সীমিত জায়গা থাকতে পারে (যেমন এম্বেড থাকা সিস্টেমগুলিতে)। উভয় ক্ষেত্রেই আমরা একটি প্যাকযুক্ত ডেটা কাঠামো ব্যবহার করতে পারি যেখানে সংকলকটি আমাদের জন্য প্যাকিং এবং আনপ্যাকিংয়ের যত্ন নেবে:
#pragma pack(1)
typedef struct {
uint8_t flag1:1;
uint8_t flag2:1;
padding1 reserved:6; /* not necessary but makes this struct more readable */
uint32_t sequence_no;
uint8_t data[8];
uint32_t crc32;
} s_mypacket __attribute__((packed));
#pragma pack()
আপনি কোন পদ্ধতিটি ব্যবহার করেন তা আপনার সংকলকের উপর নির্ভর করে। আপনাকে একই হেডার ফাইলগুলির সাথে বিভিন্ন বিভিন্ন সংকলককে সমর্থন করার প্রয়োজন হতে পারে। এম্বেড থাকা সিস্টেমে এটি ঘটে যেখানে ডিভাইস এবং সার্ভারগুলি সম্পূর্ণ আলাদা হতে পারে - উদাহরণস্বরূপ আপনার কাছে একটি আর্ম ডিভাইস থাকতে পারে যা একটি x86 লিনাক্স সার্ভারের সাথে যোগাযোগ করে।
প্যাকড স্ট্রাকচার ব্যবহার করে কয়েকটি ক্যাভেট রয়েছে। সর্বাধিক গোটাচা হ'ল আপনাকে অবশ্যই কোনও সদস্যের ঠিকানাটি অবজ্ঞা করা এড়াতে হবে। মুটিবাইটে সারিবদ্ধ শব্দের সাথে সিস্টেমগুলিতে, এর ফলশ্রুতিতে ভুল বিহীন ব্যতিক্রম ঘটতে পারে - এবং একটি কর্ড্প।
কিছু লোকেরা কর্মক্ষমতা সম্পর্কেও চিন্তিত হবে এবং তর্ক করবে যে এই প্যাকড স্ট্রাকচারগুলি ব্যবহার করা আপনার সিস্টেমকে ধীর করে দেবে। এটি সত্য যে, পর্দার আড়ালে, সংকলকটি স্বাক্ষরবিহীন ডেটা সদস্যদের অ্যাক্সেসের জন্য কোড যুক্ত করে। আপনার আইডিইতে এসেম্বলি কোডটি দেখে আপনি এটি দেখতে পারেন।
তবে যেহেতু প্যাক করা কাঠামো যোগাযোগ এবং ডেটা স্টোরেজের জন্য সবচেয়ে কার্যকর, তখন মেমরিতে এটির সাথে কাজ করার সময় ডেটা একটি প্যাক-প্যাক উপস্থাপনায় নেওয়া যেতে পারে। সাধারণত আমাদের যেভাবেই মেমরিতে পুরো ডেটা প্যাকেটটি নিয়ে কাজ করার দরকার নেই।
এখানে কিছু প্রাসঙ্গিক আলোচনা:
প্রগমা প্যাক (1) বা __attribute__ ((সারিবদ্ধ (1))) কাজ করে
জিসিসির __অনেকটি __ ((প্যাকড)) / # প্রগমা প্যাকটি কি নিরাপদ?
http://solidsmoke.blogspot.ca/2010/07/woes-of-structure-packing-pragma-pack.html
কিছুটা আছে। বহনযোগ্যতার দৃষ্টিকোণ থেকে, char
8 টি বিটের চেয়ে ছোট হতে পারে না, এবং কিছুই এর চেয়ে ছোট হতে পারে না char
, সুতরাং প্রদত্ত সি প্রয়োগকারীটির যদি স্বাক্ষরবিহীন 8-বিট পূর্ণসংখ্যার টাইপ থাকে, এটি হতে চলেছে char
। বিকল্পভাবে, এটি মোটেও একটি নাও থাকতে পারে, যার বিন্দুতে কোনও typedef
কৌশল কৌশলযুক্ত নয়।
এটি আপনার কোডটি আরও ভালভাবে ডকুমেন্ট করার জন্য ব্যবহার করা যেতে পারে যাতে এটি স্পষ্ট হয়ে যায় যে আপনার সেখানে 8-বিট বাইট প্রয়োজন এবং অন্য কিছু নেই। তবে বাস্তবে এটি ইতিমধ্যে যে কোনও জায়গায় যুক্তিসঙ্গত প্রত্যাশা রয়েছে (এমন কোনও ডিএসপি প্ল্যাটফর্ম রয়েছে যার উপরে এটি সত্য নয়, তবে আপনার কোডটি সেখানে চালিত হওয়ার সম্ভাবনা স্লিম রয়েছে, এবং আপনি আপনার প্রোগ্রামের শীর্ষে স্থির প্রতিবন্ধকতা ব্যবহার করে ত্রুটিযুক্ত হতে পারেন) on যেমন একটি প্ল্যাটফর্ম)।
unsigned char
0 থেকে 255 এর মধ্যে মান ধরে রাখতে সক্ষম হওয়া দরকার you আপনি যদি 4 টি বিটগুলিতে এটি করতে পারেন তবে আমার টুপি আপনার কাছে বন্ধ রয়েছে।
uint8_t
বাস্তবায়নে যুক্ত করুন। আমি অবাক হই, 16 বিট চরগুলি সহ ডিএসপিগুলির সংকলকগুলি সাধারণত প্রয়োগ করে uint8_t
, না?
#include <stdint.h>
এবং ব্যবহার করার পক্ষে এটি সম্ভবত সবচেয়ে সোজা উপায় uint8_t
। প্ল্যাটফর্মটিতে এটি থাকলে তা এটি আপনাকে দেবে। প্ল্যাটফর্মটিতে এটি না থাকলে আপনার প্রোগ্রামটি সংকলন করবে না এবং কারণটি পরিষ্কার এবং সোজা হবে।
উদাহরণস্বরূপ, আপনি যখন কোনও নেটওয়ার্ক বিশ্লেষক লিখছেন তখন এটি সত্যিই গুরুত্বপূর্ণ। প্যাকেট শিরোনামগুলি নির্দিষ্ট প্ল্যাটফর্মের সি সংকলক যেভাবে কাজ করে তা নয়, প্রোটোকল নির্দিষ্টকরণ দ্বারা সংজ্ঞায়িত হয়।
প্রায় প্রতিটি সিস্টেমে আমি uint8_t == স্বাক্ষরবিহীন চরটি পূরণ করেছি, তবে এটি সি স্ট্যান্ডার্ড দ্বারা গ্যারান্টিযুক্ত নয়। আপনি যদি পোর্টেবল কোড লেখার চেষ্টা করছেন এবং মেমরিটি ঠিক কত আকারের তা বিবেচনা করে তবে uint8_t ব্যবহার করুন। অন্যথায় স্বাক্ষরবিহীন চর ব্যবহার করুন।
uint8_t
8-বিট থাকলে সর্বদা পরিসীমা এবং আকার unsigned char
এবং প্যাডিং (কোনও নয়) এর সাথে মেলে unsigned char
। যখন unsigned char
8-বিট uint8_t
নয়, অস্তিত্ব নেই।
unsigned char
8-বিট, হয় uint8_t
একটি হতে নিশ্চিত typedef
উহার এবং না একটি typedef
একটি এর বর্ধিত স্বাক্ষরবিহীন পূর্ণসংখ্যা টাইপ ?
unsigned char/signed char/char
সর্বনিম্ন প্রকারের মতো সহজেই হ্রাস করা হয় - 8 বিটের চেয়ে ছোট নয়। unsigned char
কোন প্যাডিং আছে। জন্য uint8_t
হতে পারে, এটা 8-বিট, কোনো প্যাডিং হতে হবে, একটি বাস্তবায়ন উপলব্ধ পূর্ণসংখ্যা ধরনের কারণ অস্তিত্ব: এর সংক্ষিপ্ত প্রয়োজনীয়তা মিলে unsigned char
। "... টাইপয়েফ হওয়ার গ্যারান্টিযুক্ত ..." পোস্ট করা ভাল প্রশ্নের মতো মনে হচ্ছে।