uint8_t বনাম স্বাক্ষরযুক্ত চর


231

সি-তে uint8_tওভার ব্যবহারের সুবিধা কী unsigned char?

আমি জানি যে প্রায় প্রতিটি সিস্টেমে uint8_tকেবল একটি টাইপিডেফ হয় unsigned char, তবে কেন এটি ব্যবহার করবেন?

উত্তর:


225

এটি আপনার উদ্দেশ্যটি দলিল করে - আপনি একটি চরিত্রের চেয়ে কম সংখ্যক সঞ্চয় করবেন।

এছাড়াও আপনার যেমন অন্যান্য typedefs ব্যবহার করছেন সুন্দর দেখায় uint16_tবা int32_t


1
আমরা যদি কোনও স্ট্যান্ডার্ড টাইপের কথা বলি বা না করি তবে এটি মূল প্রশ্নে পরিষ্কার ছিল না। আমি নিশ্চিত যে কয়েক বছর ধরে এই নামকরণের কনভেনশনের অনেকগুলি প্রকরণ রয়েছে।
মার্ক র্যানসোম

8
সুস্পষ্টভাবে উদ্দেশ্যটিও ব্যবহার করে unsigned charবা signed charনথিবদ্ধ করে তোলে, যেহেতু অপরিজ্ঞাতভাবে charএটি আপনাকে অক্ষরের সাথে কাজ করছেন তা দেখায়।
ক্যাফে

9
আমি ভেবেছিলাম একটি অপরিজ্ঞাত unsignedছিল unsigned intসংজ্ঞা দিয়ে?
মার্ক র্যানসোম

5
@endolith, স্ট্রিংয়ের জন্য uint8_t ব্যবহার করা অগত্যা ভুল নয়, তবে এটি অবশ্যই অদ্ভুত।
মার্ক র্যানসোম

5
@ এন্ডোলিথ, আমি মনে করি UTF8 পাঠ্যের সাহায্যে uint8_t এর জন্য আমি একটি মামলা করতে পারি। প্রকৃতপক্ষে, charএকটি চরিত্রকে বোঝায় বলে মনে হচ্ছে, যেখানে কোনও ইউটিএফ 8 স্ট্রিংয়ের প্রসঙ্গে এটি মাল্টবাইট চরিত্রের কেবল একটি বাইট হতে পারে। Uint8_t ব্যবহার করে এটি স্পষ্ট হয়ে উঠতে পারে যে প্রতিটি অবস্থানে একটি চরিত্রের আশা করা উচিত নয় - অন্য কথায় স্ট্রিং / অ্যারের প্রতিটি উপাদান একটি স্বেচ্ছাসেবী পূর্ণসংখ্যা যা সম্পর্কে কোনও শব্দার্থিক অনুমান করা উচিত নয়। অবশ্যই সমস্ত সি প্রোগ্রামাররা এটি জানেন তবে এটি প্রাথমিকভাবে সঠিক প্রশ্ন জিজ্ঞাসা করতে চাপ দিতে পারে।
tne

70

কেবলমাত্র পেডেন্টিক হতে, কিছু সিস্টেমে 8 বিট টাইপ নাও থাকতে পারে। উইকিপিডিয়া অনুসারে :

N = 8, 16, 32, বা 64 এর জন্য সঠিক-প্রস্থের পূর্ণসংখ্যার ধরণের সংজ্ঞা দিতে একটি বাস্তবায়নের প্রয়োজন হয় এবং কেবল যদি এর প্রয়োজনীয়তা মেলে এমন কোনও ধরণের থাকে। এটি অন্য কোনও এন এর জন্য তাদের সংজ্ঞায়িত করার প্রয়োজন হয় না, এমনকি যদি এটি উপযুক্ত ধরণের সমর্থন করে।

সুতরাং uint8_tঅস্তিত্বের নিশ্চয়তা নেই, যদিও এটি সমস্ত প্ল্যাটফর্মের জন্য যেখানে 8 বিট = 1 বাইট রয়েছে। কিছু এম্বেড থাকা প্ল্যাটফর্ম আলাদা হতে পারে তবে এটি খুব বিরল getting কিছু সিস্টেম char16 বিট হিসাবে প্রকারগুলি সংজ্ঞায়িত করতে পারে, এক্ষেত্রে সম্ভবত কোনও 8-বিট ধরণের হবে না।

এটি (নাবালক) ইস্যু ব্যতীত @ মার্ক র্যানসমের উত্তর আমার মতে সেরা। আপনি যেটি ডেটা ব্যবহার করছেন তা সর্বাধিক স্পষ্টভাবে দেখায় এমন একটি ব্যবহার করুন।

এছাড়াও, আমি ধরে নিচ্ছি যে আপনি বোঝাচ্ছেন uint8_t(সি 99 এর মানক টাইপডেফটি stdint.hশিরোনামে সরবরাহ করা হয়েছে ) পরিবর্তে uint_8(কোনও মানের অংশ নয়)।


3
নিছক কৌতূহলের বাইরে @ ক্যাফ- আপনি কারও বর্ণনার সাথে লিঙ্ক করতে পারেন? আমি জানি যে এগুলি বিদ্যমান কারণ কেউ একটি কমপ্লেক্স.এল.সি.এল.সি .++ এ একটি উল্লেখ করেছিলেন (এবং এর জন্য বিকাশকারী ডক্সের সাথে যুক্ত)। যে কোনও অনুরূপ আলোচনায় রেফারেন্স :)
পাভেল মিনায়েভ

3
"কিছু সিস্টেম চর বিট 16 টি বিট হিসাবে সংজ্ঞায়িত করতে পারে, এক্ষেত্রে সম্ভবত 8-বিট ধরণের কোনও ধরণের উপস্থিতি থাকবে না।" - এবং আমার কাছ থেকে কিছু ভুল আপত্তি সত্ত্বেও পাভেল তার উত্তরে প্রমাণ করেছে যে চরটি যদি 16 বিট হয় তবে সংকলকটি যদি 8 বিট প্রকার সরবরাহ করে তবে অবশ্যই তাকে এটি কল করতে হবে নাuint8_t (বা এটি এটিকে টাইপ করতে হবে )। এটি কারণ 8 বিট প্রকারের স্টোরেজ উপস্থাপনায় অব্যবহৃত বিট থাকবে যা uint8_tঅবশ্যই তা নয়।
স্টিভ জেসোপ

3
SHARC আর্কিটেকচারে 32-বিট শব্দ রয়েছে। বিশদ জানতে en.wikedia.org/wiki/… দেখুন ।
বিসিআরান

2
এবং টিআই এর সি 5000 ডিএসপিগুলি (যা ওএমএপি 1 এবং ওএমএপি 2 এ ছিল) 16 বিট। আমি মনে করি OMAP3- এর জন্য তারা 8 বিটের চর নিয়ে সি 6000-সিরিজে গিয়েছিল।
স্টিভ জেসোপ

4
N3242 এ খনন করা - "ওয়ার্কিং ড্রাফ্ট, প্রোগ্রামিং ল্যাঙ্গুয়েজ সি ++ এর জন্য স্ট্যান্ডার্ড", বিভাগ 18.4.1 <cstdint> প্রতিশব্দ বলে - typedef unsigned integer type uint8_t; // optional সুতরাং, প্রকৃতপক্ষে, uint8_t সংজ্ঞা দেওয়ার জন্য কোনও সি ++ স্ট্যান্ডার্ড অনুসারে গ্রন্থাগারের প্রয়োজন নেই (মন্তব্য দেখুন // alচ্ছিক )
রাত্রে ট্রিল

43

পুরো বিষয়টি হ'ল বাস্তবায়ন-স্বাধীন কোড লিখতে। unsigned char8-বিট প্রকারের গ্যারান্টি নেই। uint8_t(যদি উপলব্ধ থাকে) হয়।


4
... যদি এটি কোনও সিস্টেমে বিদ্যমান থাকে তবে এটি খুব বিরল হতে চলেছে। +1
ক্রিস লুটজ

2
ভাল যদি আপনার কোডটি কোনও সিস্টেমে সংকলন না করার ক্ষেত্রে সত্যিই সমস্যা ছিল কারণ uint8_t এর অস্তিত্ব ছিল না, আপনি uint8_t এর সমস্ত উপস্থিতি স্বাক্ষরযুক্ত চর বা আপনার জন্য আরও কার্যকর কিছুতে স্বয়ংক্রিয়ভাবে পরিবর্তন করতে সন্ধান করতে পারেন sed
বাজ

2
@ বাজজ - আপনি ধরে নিচ্ছেন এমন 8-বিট প্রকার যা আপনি পারবেন না - উদাহরণস্বরূপ দূরবর্তী সিস্টেমের মাধ্যমে বাই বাই ফ্যাশনে প্যাকেজ করা ডেটা আনপ্যাক করা। অন্তর্নিহিত অনুমানটি হ'ল uint8_t এর অস্তিত্ব না থাকার কারণটি এমন একটি প্রসেসরে রয়েছে যেখানে একটি চর 8 বিটের বেশি হয়।
ক্রিস স্ট্রাটন

প্রতিস্থাপন assert (আকারের (স্বাক্ষরযুক্ত স্বাক্ষরিত) == 8);
বাজ

3
@ বাজজ ভুল উক্তিটি আমি ভয় করি। 1 বাইট জন্য sizeof(unsigned char)ফিরে আসবে 1। তবে যদি কোনও সিস্টেমের চর এবং INT একই আকারের হয়, উদাহরণস্বরূপ, 16-বিটগুলি তখনও sizeof(int)ফিরে আসবে1
টবি

7

যেমনটি আপনি বলেছেন, " প্রায় প্রতিটি সিস্টেম"।

charসম্ভবত পরিবর্তিত হওয়ার সম্ভাবনাগুলির মধ্যে একটি হ'ল তবে আপনি একবার uint16_tএবং বন্ধুবান্ধব ব্যবহার শুরু করার সাথে uint8_tমিশ্রণগুলি আরও ভাল ব্যবহার করতে শুরু করেছেন এবং কোডিং স্ট্যান্ডার্ডের একটি অংশও হতে পারে।


7

আমার অভিজ্ঞতায় দুটি জায়গা রয়েছে যেখানে আমরা 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


6

কিছুটা আছে। বহনযোগ্যতার দৃষ্টিকোণ থেকে, char8 টি বিটের চেয়ে ছোট হতে পারে না, এবং কিছুই এর চেয়ে ছোট হতে পারে না char, সুতরাং প্রদত্ত সি প্রয়োগকারীটির যদি স্বাক্ষরবিহীন 8-বিট পূর্ণসংখ্যার টাইপ থাকে, এটি হতে চলেছে char। বিকল্পভাবে, এটি মোটেও একটি নাও থাকতে পারে, যার বিন্দুতে কোনও typedefকৌশল কৌশলযুক্ত নয়।

এটি আপনার কোডটি আরও ভালভাবে ডকুমেন্ট করার জন্য ব্যবহার করা যেতে পারে যাতে এটি স্পষ্ট হয়ে যায় যে আপনার সেখানে 8-বিট বাইট প্রয়োজন এবং অন্য কিছু নেই। তবে বাস্তবে এটি ইতিমধ্যে যে কোনও জায়গায় যুক্তিসঙ্গত প্রত্যাশা রয়েছে (এমন কোনও ডিএসপি প্ল্যাটফর্ম রয়েছে যার উপরে এটি সত্য নয়, তবে আপনার কোডটি সেখানে চালিত হওয়ার সম্ভাবনা স্লিম রয়েছে, এবং আপনি আপনার প্রোগ্রামের শীর্ষে স্থির প্রতিবন্ধকতা ব্যবহার করে ত্রুটিযুক্ত হতে পারেন) on যেমন একটি প্ল্যাটফর্ম)।


7
@ স্কিজ - না, মানটির unsigned char0 থেকে 255 এর মধ্যে মান ধরে রাখতে সক্ষম হওয়া দরকার you আপনি যদি 4 টি বিটগুলিতে এটি করতে পারেন তবে আমার টুপি আপনার কাছে বন্ধ রয়েছে।
ক্রিস লুটজ

1
"এটি কিছুটা আরও জটিল হয়ে উঠবে" - বোঝার দিক থেকে আপনাকে কম্পাইলার লেখক যেখানে ছিল সেখানে যেতে হবে (সাঁতার কাটা, বিমান ধরতে হবে ইত্যাদি), মাথার পিছনে থাপ্পর মারতে হবে। , এবং তাদের uint8_tবাস্তবায়নে যুক্ত করুন। আমি অবাক হই, 16 বিট চরগুলি সহ ডিএসপিগুলির সংকলকগুলি সাধারণত প্রয়োগ করে uint8_t, না?
স্টিভ জেসোপ

6
যাইহোক, দ্বিতীয় চিন্তায়, "সম্ভবত আমার 8 বিট লাগবে" - #include <stdint.h>এবং ব্যবহার করার পক্ষে এটি সম্ভবত সবচেয়ে সোজা উপায় uint8_t। প্ল্যাটফর্মটিতে এটি থাকলে তা এটি আপনাকে দেবে। প্ল্যাটফর্মটিতে এটি না থাকলে আপনার প্রোগ্রামটি সংকলন করবে না এবং কারণটি পরিষ্কার এবং সোজা হবে।
পাভেল মিনায়েভ

2
তবুও সিগার নেই, দুঃখিত: "স্বাক্ষরবিহীন চরিত্র ব্যতীত স্বাক্ষরযুক্ত পূর্ণসংখ্যার ধরণের জন্য, অবজেক্টের উপস্থাপনের বিটগুলি দুটি গ্রুপে বিভক্ত করা হবে: মান বিট এবং প্যাডিং বিট ... যদি এন মান বিট থাকে তবে প্রতিটি বিট পৃথক প্রতিনিধিত্ব করবে 1 থেকে 2 between (N-1) এর মধ্যে 2 পাওয়ার, যাতে এই ধরণের অবজেক্টগুলি একটি খাঁটি বাইনারি উপস্থাপনা ব্যবহার করে 0 থেকে 2 ^ (এন -1) পর্যন্ত মানগুলি উপস্থাপন করতে সক্ষম হতে পারে ... টাইপডেফ নামটিএনএনটি একটিকে মনোনীত করে প্রস্থ এন, কোনও প্যাডিং বিট এবং দু'জনের পরিপূরক উপস্থাপনা সহ স্বাক্ষরযুক্ত পূর্ণসংখ্যার প্রকার । "
পাভেল মিনায়েভ

1
আপনার যদি কেবল গাণিতিক মডুলোর প্রয়োজন হয়, স্বাক্ষরযুক্ত বিটফিল্ড ঠিক ঠিক করবে (অসুবিধে হলে)। এটি আপনার প্রয়োজন যখন বলুন, কোনও প্যাডিংবিহীন অক্টেটের একটি অ্যারে, যখন আপনি সোল হন। গল্পটির নৈতিকতা ডিএসপিগুলিকে কোড করার জন্য নয়, এবং যথাযথ, সৎ-
থেকে-

4

উদাহরণস্বরূপ, আপনি যখন কোনও নেটওয়ার্ক বিশ্লেষক লিখছেন তখন এটি সত্যিই গুরুত্বপূর্ণ। প্যাকেট শিরোনামগুলি নির্দিষ্ট প্ল্যাটফর্মের সি সংকলক যেভাবে কাজ করে তা নয়, প্রোটোকল নির্দিষ্টকরণ দ্বারা সংজ্ঞায়িত হয়।


ফিরে যখন আমি এটি জিজ্ঞাসা করলাম তখন আমি সিরিয়ালের ওপরে কমন্টিকেশন করার জন্য একটি সহজ প্রোটোকল ছিলাম।
লন্ডন হোয়াইট

2

প্রায় প্রতিটি সিস্টেমে আমি uint8_t == স্বাক্ষরবিহীন চরটি পূরণ করেছি, তবে এটি সি স্ট্যান্ডার্ড দ্বারা গ্যারান্টিযুক্ত নয়। আপনি যদি পোর্টেবল কোড লেখার চেষ্টা করছেন এবং মেমরিটি ঠিক কত আকারের তা বিবেচনা করে তবে uint8_t ব্যবহার করুন। অন্যথায় স্বাক্ষরবিহীন চর ব্যবহার করুন।


3
uint8_t 8-বিট থাকলে সর্বদা পরিসীমা এবং আকার unsigned charএবং প্যাডিং (কোনও নয়) এর সাথে মেলে unsigned char। যখন unsigned char8-বিট uint8_tনয়, অস্তিত্ব নেই।
chux - মনিকা

@ চিচস, আপনার যেখানে স্ট্যান্ডার্ড যেখানে এটি বলা হয়েছে সেখানে ঠিক সেই জায়গার রেফারেন্স রয়েছে? যদি unsigned char8-বিট, হয় uint8_tএকটি হতে নিশ্চিত typedefউহার এবং না একটি typedefএকটি এর বর্ধিত স্বাক্ষরবিহীন পূর্ণসংখ্যা টাইপ ?
hsivonen

@sivonen "স্ট্যান্ডার্ডের সঠিক জায়গা যেখানে এটি বলে?" -> না - তবু 7.20.1.1 এ দেখুন। এটি unsigned char/signed char/charসর্বনিম্ন প্রকারের মতো সহজেই হ্রাস করা হয় - 8 বিটের চেয়ে ছোট নয়। unsigned charকোন প্যাডিং আছে। জন্য uint8_tহতে পারে, এটা 8-বিট, কোনো প্যাডিং হতে হবে, একটি বাস্তবায়ন উপলব্ধ পূর্ণসংখ্যা ধরনের কারণ অস্তিত্ব: এর সংক্ষিপ্ত প্রয়োজনীয়তা মিলে unsigned char। "... টাইপয়েফ হওয়ার গ্যারান্টিযুক্ত ..." পোস্ট করা ভাল প্রশ্নের মতো মনে হচ্ছে।
chux - মনিকা পুনরায় ইনস্টল করুন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.