পরিবর্তনশীল প্রস্থের প্রকারগুলি কি আধুনিক সি-তে নির্দিষ্ট ধরণের দ্বারা প্রতিস্থাপিত হয়েছে?


21

কোড রিভিউ সম্পর্কিত একটি পর্যালোচনাতে আমি আজ একটি আকর্ষণীয় পয়েন্ট পেয়েছি । @ ভাইড্রাক এই উত্তরে পুনঃবিবেচনা জানিয়েছে যে পরিবর্তনশীল আকারের ধরণের (যেমন intএবং long) নির্দিষ্ট আকারের মতো uint64_tএবং এর সাথে প্রতিস্থাপন করা হবে uint32_t। এই উত্তরের মন্তব্য থেকে উদ্ধৃতি:

দীর্ঘতর ও দীর্ঘ আকারের (এবং এভাবে তারা ধারণ করতে পারে এমন মানগুলি) প্ল্যাটফর্ম নির্ভর। অন্যদিকে, int32_t সর্বদা 32 বিট দীর্ঘ। ইন্ট ব্যবহারের অর্থ হ'ল আপনার কোডটি বিভিন্ন প্ল্যাটফর্মগুলিতে আলাদাভাবে কাজ করে, যা সাধারণত আপনি চান তা নয়।

সাধারণ ধরণের ফিক্সিং না করার পিছনে যুক্তিটি এখানে আংশিকভাবে @ সুপের্যাট দ্বারা ব্যাখ্যা করা হয়েছে । সি আর্কিটেকচার জুড়ে বহনযোগ্য হিসাবে লেখা হয়েছিল, বিধানের বিপরীতে যা সাধারণত তখন সিস্টেম প্রোগ্রামিংয়ের জন্য ব্যবহৃত হত।

আমি মনে করি ডিজাইনের অভিপ্রায়টি মূলত ছিল যে int ছাড়া অন্য প্রতিটি প্রকারটি হ'ল সবচেয়ে ছোট জিনিস যা বিভিন্ন আকারের সংখ্যাকে পরিচালনা করতে পারে এবং এটি আন্তঃরূপিক ব্যবহারিক "সাধারণ-উদ্দেশ্য" আকার যা +/- 32767 পরিচালনা করতে পারে।

আমার হিসাবে, আমি সবসময় ব্যবহার করেছি intএবং বিকল্পগুলি সম্পর্কে সত্যই চিন্তিত নই। আমি সবসময়ই ভেবেছি যে এটি সর্বোত্তম অভিনয়, গল্পের শেষে with সঞ্চয় স্থানের জন্য বা কোনও নেটওয়ার্কের মাধ্যমে স্থানান্তর করার জন্য ডেটা এনকোডিং করার সময় কেবলমাত্র স্থির প্রস্থটি কার্যকর মনে হয়েছিল place আমি অন্যদের দ্বারা লিখিত কোডে নির্দিষ্ট প্রস্থের ধরনগুলি খুব কমই দেখেছি।

আমি কি 70 এর দশকে আটকে আছি বা intC99 এর যুগে বা তার বাইরে এর ব্যবহারের পক্ষে আসলে যুক্তি আছে ?


1
লোকেদের একটি অংশ অন্যকে অনুকরণ করে। আমি বিশ্বাস করি যে সংখ্যাগরিষ্ঠ কোড স্থির-বিট-টাইপকে বিবেকহীন করা হয়েছিল। আকার নির্ধারণ না করার কোনও কারণ নেই। আমার কাছে প্রাথমিকভাবে 16 বিট প্ল্যাটফর্মগুলিতে (এমএস-ডস এবং 80 এর দশকের জেনিক্স) কোড তৈরি করা হয়েছে, যা কেবল আজই সংকলন করে নতুন শব্দের আকার এবং সম্বোধনের কোনও 64 এবং বেনিফিটের জন্য আজই সংকলন করে চলে। এর অর্থ এই যে রফতানি / আমদানির ডেটা সিরিয়ালাইজেশন এটি বহনযোগ্য রাখার জন্য একটি অত্যন্ত গুরুত্বপূর্ণ আর্কিটেকচার ডিজাইন।
লুসিও

1
সম্পর্কিত: stackoverflow.com/questions/24444356/...
dan04

উত্তর:


7

একটি সাধারণ এবং বিপজ্জনক কল্পিত কাহিনী রয়েছে যা uint32_tপ্রোগ্রামারদের আকার সম্পর্কে চিন্তা করতে থেকে বাঁচানোর মতো ধরণ রয়েছে int। যদিও এটি কার্যকর হবে যদি স্ট্যান্ডার্ড কমিটি মেশিন-স্বতন্ত্র শব্দার্থবিজ্ঞানের সাথে পূর্ণসংখ্যা ঘোষণার কোনও উপায় নির্ধারণ করে, স্বাক্ষরযুক্ত স্বাক্ষরযুক্ত ধরণের uint32_tশব্দার্থক থাকে যা কোডটি এমন একটি ফ্যাশনে লিখিত হতে দেয় যা পরিষ্কার এবং বহনযোগ্য উভয়ই; আরও, স্বাক্ষরযুক্ত ধরণের মতো int32শব্দার্থক শব্দ রয়েছে যা অনেকগুলি অ্যাপ্লিকেশন পদ্ধতির জন্য অযথা শক্তভাবে সংজ্ঞায়িত করা হয় এবং অন্যথায় দরকারী অপ্টিমাইজেশানগুলি কী হতে পারে তা নির্ধারণ করে।

উদাহরণস্বরূপ বিবেচনা করুন:

uint32_t upow(uint32_t n, uint32_t exponent)
{
  while(exponent--)
    n*=n;
  return n;
}

int32_t spow(int32_t n, uint32_t exponent)
{
  while(exponent--)
    n*=n;
  return n;
}

মেশিন যেখানে উপর intপারেন 4294967295 রাখা যাবে না, অথবা 18446744065119617025 ধরে রাখতে পারেন, প্রথম ফাংশনের সব মান জন্য সংজ্ঞায়িত করা হবে nএবং exponentএবং তার আচরণের আকার দ্বারা প্রভাবিত হবে না int; উপরন্তু, মান প্রয়োজন হয় না করবে তার কোনো আকার সঙ্গে মেশিনে বিভিন্ন আচরণ উত্পাদ int কিছু মান nএবং exponent, একটি যাইহোক, এটা কারণ মেশিনে অনির্ধারিত আচরণ যেখানে 4294967295 representable হয় ডাকা হবে intকিন্তু 18446744065119617025 নয়।

দ্বিতীয় ফাংশন কিছু মানের জন্য অনির্ধারিত আচরণ সমর্পণ করা হবে nএবং exponentমেশিন যেখানে উপর int4611686014132420609 ধরে রাখতে পারেন, কিন্তু সব মানের জন্য সংজ্ঞায়িত আচরণ সমর্পণ করা হবে nএবং exponentসব মেশিনে যেখানে এটি (নির্দিষ্টকরণের জন্য করতে int32_tপরোক্ষভাবে যে two's-সম্পূরক মেশিন যেখানে এটা মোড়ানো আচরণ এর চেয়ে ছোট int)।

Icallyতিহাসিকভাবে, স্ট্যান্ডার্ড যদিও intওভারফ্লো সম্পর্কে কী সংকলকগুলি করণীয় সে সম্পর্কে কিছুই বলেনি upow, কম্পাইলাররা ধারাবাহিকভাবে একই আচরণ করতে intপেরেছিল যেন প্রবাহিত না হওয়ার মতো যথেষ্ট বড় ছিল। দুর্ভাগ্যক্রমে, কিছু নতুন সংকলক স্ট্যান্ডার্ড দ্বারা বাধ্যতামূলক আচরণগুলি বাদ দিয়ে প্রোগ্রামগুলিকে "অনুকূলিতকরণ" করতে পারে।


3
ম্যানুয়ালি প্রয়োগ করতে চায় এমন যে কেউ ঘটছে pow, মনে রাখবেন এই কোডটি একটি উদাহরণ এবং এটি পূরণ করে না exponent=0!
মার্ক হার্ট

1
আমার মনে হয় আপনার প্রিফিক্স হ্রাস অপারেটরটি পোস্টফিক্স নয়, ব্যবহার করা উচিত, বর্তমানে এটি 1 টি অতিরিক্ত গুণ exponent=1করে চলেছে উদাহরণস্বরূপ n একবারে নিজেই গুণিত হবে, যেহেতু হ্রাসটি চেকের পরে সঞ্চালিত হয়, যদি চেকের আগে বর্ধন সম্পাদন করা হয় ( যেমন - অংশ), কোনও গুণ সম্পন্ন হবে না এবং n নিজেই ফিরে আসবে।
ALXGTV

2
@ মার্কহর্ড: ফাংশনটি খারাপভাবে নামকরণ করা হয়েছে, যেহেতু এটি প্রকৃতভাবে গণনা করে N^(2^exponent)তবে ফর্মের N^(2^exponent)গণনা প্রায়শই ক্ষয়ক্ষতি ফাংশনগুলির গণনায় ব্যবহৃত হয়, এবং মোড -২২৯৯6729 29 66 এক্সফোনেনটিশন দুটি স্ট্রিংয়ের সংশ্লেষের হ্যাশ গণনা করার মতো জিনিসগুলির জন্য দরকারী হ্যাশগুলি জানা যায়।
সুপারক্যাট

1
@ ওএলএক্সজিটিভি: ফাংশনটি এমন কোনও কিছুর উদাহরণস্বরূপ ছিল যা বিদ্যুৎ-সম্পর্কিত কিছু গণনা করে। এটি আসলে কী গণনা করে তা হ'ল এন ^ (2 ^ এক্সপোঞ্জার), যা দক্ষতার সাথে N ^ ঘনিষ্ঠর গণনা করার একটি অংশ, এবং এন ছোট হলেও ভাল ব্যর্থ হতে পারে ( uint32_t31 দ্বারা একটি বার বার করা গুণ কখনও ইউবি না দেয় তবে কার্যকর 31 ^ N গণনা করার পদ্ধতিতে 31 ^ (2 ^ N) এর গণনা আবশ্যক, যা হবে
সুপারক্যাট

আমি মনে করি না এটি একটি ভাল যুক্তি। উদ্দেশ্যটি সমস্ত ইনপুটগুলির জন্য সংজ্ঞায়িত ফাংশনগুলি তৈরি করা নয়, বুদ্ধিমান বা না; এটি আকার এবং ওভারফ্লো সম্পর্কে যুক্তি করতে সক্ষম হতে হবে। int32_tকখনও কখনও ওভারফ্লো সংজ্ঞায়িত হয়ে থাকে এবং কখনও কখনও না, যা আপনি উল্লেখ করছেন বলে মনে হয়, এটি তুলনামূলকভাবে ন্যূনতম গুরুত্ব বলে মনে হয় যে এটি আমাকে প্রথমে ওভারফ্লো প্রতিরোধের বিষয়ে যুক্তি দেয়। এবং যদি আপনি সংজ্ঞায়িত ওভারফ্লো করতে চান, তবে সম্ভাবনাগুলি হ'ল আপনি ফলাফলটি কিছু স্থির মানটি চান - তাই আপনি যেভাবে স্থির-প্রস্থের প্রকারগুলি ব্যবহার করছেন।
Veedrac

4

পয়েন্টারগুলির সাথে ঘনিষ্ঠভাবে সম্পর্কিত মানগুলির জন্য (এবং এইভাবে, ঠিকানাযোগ্য মেমরির পরিমাণে) যেমন বাফার আকার, অ্যারে সূচক এবং উইন্ডোজ ' lParam, এটি আর্কিটেকচার-নির্ভর আকারের সাথে একটি পূর্ণসংখ্যা টাইপ থাকা বোধগম্য হয়। সুতরাং, পরিবর্তনশীল-আকারের প্রকারগুলি এখনও কার্যকর। এই কেন আমরা typedefs আছে size_t, ptrdiff_t, intptr_t, ইত্যাদি তারা আছে প্রয়োজন কারণ বিল্ট-ইন সি ধরনের পূর্ণসংখ্যা কেউই পয়েন্টার আকারের হতে typedefs যাবে।

তাই প্রশ্ন সত্যিই কিনা char, short, int, long, এবং long longএখনও দরকারী।

আইএমই, সি এবং সি ++ প্রোগ্রামগুলির intবেশিরভাগ জিনিসের জন্য ব্যবহার করা এখনও সাধারণ । এবং বেশিরভাগ সময় (যেমন আপনার সংখ্যাগুলি যখন 7 32 767 এর মধ্যে থাকে এবং আপনার কঠোর পরিশ্রমের প্রয়োজনীয়তা না থাকে), এটি ঠিক কাজ করে fine

তবে আপনার যদি 17-32 বিট পরিসরে (বড় শহরগুলির জনসংখ্যার মতো) সংখ্যার সাথে কাজ করার দরকার হয়? আপনি ব্যবহার করতে পারেন int, তবে এটি প্ল্যাটফর্ম নির্ভরতা হার্ড কোডিং। আপনি যদি স্ট্যান্ডার্ডটি কঠোরভাবে মেনে চলতে চান তবে আপনি এটি ব্যবহার করতে পারেন longযা কমপক্ষে 32 বিট হওয়ার গ্যারান্টিযুক্ত।

সমস্যাটি হ'ল সি স্ট্যান্ডার্ড কোনও পূর্ণসংখ্যার ধরণের জন্য কোনও সর্বাধিক আকার নির্দিষ্ট করে না । এমন কিছু বাস্তবায়ন রয়েছে যার longউপরে b৪ বিট রয়েছে যা আপনার মেমরির ব্যবহার দ্বিগুণ করে। এবং যদি এগুলি longলক্ষ লক্ষ আইটেম সহ কোনও অ্যারের উপাদান হিসাবে ঘটে থাকে তবে আপনি স্মৃতিটিকে পাগলের মতো ছুঁড়ে মারবেন।

সুতরাং, আপনি যদি নিজের প্রোগ্রামটি ক্রস-প্ল্যাটফর্ম এবং মেমরি-দক্ষ উভয়ই হতে চান তবে এখানেও ব্যবহার করার উপযুক্ত intনয় long। প্রবেশ করান int_least32_t

  • আপনার আই 16 এল 32 সংকলকটি আপনাকে একটি 32-বিট দেয়, এর কাটা longসমস্যা এড়ানোint
  • আপনার I32L64 সংকলক 32৪-বিটের intনষ্ট স্মৃতি এড়িয়ে একটি 32-বিট দেয় long
  • আপনার I36L72 সংকলক আপনাকে একটি 36-বিট দেয় int

OTOH, আপনি অনুমান করা না বিশাল সংখ্যা বা বিশাল অ্যারে প্রয়োজন কিন্তু আপনি গতি জন্য একটি প্রয়োজন আছে। এবং intসমস্ত প্ল্যাটফর্মগুলিতে যথেষ্ট বড় হতে পারে তবে এটি দ্রুততম ধরণের নয়: 64-বিট সিস্টেমে সাধারণত এখনও 32-বিট থাকে int। কিন্তু আপনি ব্যবহার করতে পারেন int_fast16_tএবং "দ্রুততম" টাইপ পেতে, এটা কিনা int, longঅথবা long long

সুতরাং, থেকে প্রকারের জন্য ব্যবহারিক ব্যবহারের কেস রয়েছে <stdint.h>। স্ট্যান্ডার্ড পূর্ণসংখ্যার ধরণের অর্থ কিছুই নয়। বিশেষত long, যা 32 বা 64 বিট হতে পারে এবং সংকলক লেখকগুলির ঝকঝকে উপর নির্ভর করে পয়েন্টার ধরে রাখতে যথেষ্ট বড় বা নাও হতে পারে।


ধরণের ধরণের সমস্যাটি uint_least32_tহ'ল অন্যান্য ধরণের সাথে তাদের মিথস্ক্রিয়াগুলি এর চেয়ে আরও দুর্বলভাবে নির্দিষ্ট করা হয় uint32_t। আইএমএইচও, স্ট্যান্ডার্ডের মতো ধরণের সংজ্ঞা দেওয়া উচিত uwrap32_tএবং unum32_tশব্দার্থবিজ্ঞানের সাথে যে কোনও সংকলক টাইপ সংজ্ঞায়িত করে uwrap32_t, অবশ্যই int32 টি বিট হলে উন্নত হবে সেই একই ক্ষেত্রে একটি স্বাক্ষরবিহীন টাইপ হিসাবে প্রচার করতে হবে এবং যে সংকলক প্রকার সংজ্ঞায়িত করে unum32_tতা অবশ্যই নিশ্চিত করতে হবে মৌলিক গাণিতিক প্রচারগুলি সর্বদা এটির মান ধরে রাখতে সক্ষম কোনও স্বাক্ষরিত ধরণে রূপান্তর করে।
সুপারক্যাট

উপরন্তু, স্ট্যান্ডার্ড এছাড়াও ধরনের যার স্টোরেজ ও এলিয়াসিং সঙ্গে সামঞ্জস্যপূর্ণ ছিল সংজ্ঞায়িত করতে পারে intN_tএবং uintN_tএবং যাদের সংজ্ঞায়িত আচরণে হবে সামঞ্জস্যপূর্ণ সঙ্গে intN_tএবং uintN_t, কিন্তু যা কম্পাইলার তাদের পরিসীমা বাইরে মান নির্ধারিত ক্ষেত্রে কোডে কিছু স্বাধীনতা কাছে প্রার্থনা করি য়েন [যার ফলে ঐ যে অবস্থায় ছিল সেই অবস্থায় অনুরূপ শব্দার্থবিদ্যা সম্ভবত উদ্দেশ্যে করা হয়েছে uint_least32_t, তবে কোনও uint_least16_tএবং যুক্ত যুক্ত int32_tকোনও স্বাক্ষরিত বা স্বাক্ষরিত ফল পাবে কিনা তার মতো অনিশ্চয়তা ছাড়াই ।
সুপারক্যাট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.