সি ++ এ ভেরিয়েবলগুলি কীভাবে তাদের ধরণ সঞ্চয় করে?


42

যদি আমি একটি নির্দিষ্ট ধরণের একটি ভেরিয়েবল সংজ্ঞায়িত করি (যা আমি জানি, কেবল ভেরিয়েবলের বিষয়বস্তুর জন্য ডেটা বরাদ্দ করে) তবে এটি কোন ধরণের ভেরিয়েবলের ট্র্যাক রাখে?


8
" এটি " কীভাবে এটি ট্র্যাক রাখে "" আপনি " কে" দ্বারা উল্লেখ করছেন ? সংকলক বা সিপিইউ বা অন্য কিছু / ভাষা বা প্রোগ্রামের মতো?
এরিক tদ


8
@ এরিকইড্ট আইএমও ওপির স্পষ্টতই "এর দ্বারা" তারতম্য হয় means অবশ্যই প্রশ্নের দ্বি-শব্দের উত্তর "এটি হয় না"।
আলেফজেরো

2
দুর্দান্ত প্রশ্ন! বিশেষত প্রাসঙ্গিক যে সমস্ত অভিনব ভাষা তাদের ধরণের সংরক্ষণ করে given
ট্রেভর বয়ড স্মিথ

@ এলফজারো এটি অবশ্যই একটি শীর্ষস্থানীয় প্রশ্ন ছিল।
লুয়ান

উত্তর:


105

চলক (বা আরও সাধারণভাবে: "সি" এর অর্থে "অবজেক্ট") রানটাইমের সময় তাদের ধরণের সঞ্চয় করে না। যতক্ষণ না মেশিন কোড সম্পর্কিত, কেবলমাত্র টাইপযুক্ত মেমরি। পরিবর্তে, এই ডেটাতে করা ক্রিয়াকলাপগুলি ডেটাটিকে নির্দিষ্ট ধরণের হিসাবে ব্যাখ্যা করে (যেমন একটি ফ্লোট হিসাবে বা পয়েন্টার হিসাবে)। প্রকারগুলি কেবল সংকলক দ্বারা ব্যবহৃত হয়।

উদাহরণস্বরূপ, আমাদের স্ট্রাক্ট বা ক্লাস struct Foo { int x; float y; };এবং একটি ভেরিয়েবল থাকতে পারে Foo f {}। ক্ষেত্রের অ্যাক্সেস auto result = f.y;কীভাবে সংকলন করা যায়? সংকলকটি জানে যে fএটি কোনও ধরণের একটি অবজেক্ট Fooএবং Fooob-প্রকল্পগুলির বিন্যাসটি জানে । প্ল্যাটফর্ম-নির্দিষ্ট বিশদের উপর নির্ভর করে এটি "পয়েন্টারটি শুরুতে নিন f, 4 বাইট যুক্ত করুন, তারপরে 4 বাইট লোড করুন এবং এই ডেটাটিকে একটি ফ্লোট হিসাবে ব্যাখ্যা করুন " হিসাবে সংকলিত হতে পারে many ) ফ্লোটগুলি বা ইনটগুলি লোড করার জন্য বিভিন্ন প্রসেসরের নির্দেশাবলী রয়েছে।

একটি উদাহরণ যেখানে সি ++ টাইপ সিস্টেমটি আমাদের জন্য প্রকারের উপর নজর রাখতে পারে না তা হল একটি ইউনিয়ন union Bar { int as_int; float as_float; }। একটি ইউনিয়নে বিভিন্ন ধরণের একটি অবজেক্ট থাকে। যদি আমরা কোনও ইউনিয়নে কোনও বস্তু সঞ্চয় করি তবে এটি ইউনিয়নের সক্রিয় প্রকার। আমাদের কেবল সেই ধরণের ইউনিয়ন থেকে ফিরে আসার চেষ্টা করতে হবে, অন্য যে কোনও কিছুই হবে অপরিবর্তিত আচরণ। সক্রিয় প্রকারটি কী তা প্রোগ্রাম করার সময় আমরা "জানি", অথবা আমরা একটি ট্যাগ ইউনিয়ন তৈরি করতে পারি যেখানে আমরা আলাদাভাবে কোনও টাইপ ট্যাগ (সাধারণত একটি এনাম) সঞ্চয় করি। এটি সি তে একটি সাধারণ কৌশল, তবে আমাদের ইউনিয়ন এবং টাইপ ট্যাগটি সিঙ্কে রাখতে হবে কারণ এটি মোটামুটি ত্রুটিযুক্ত। একটি void*পয়েন্টার একটি ইউনিয়নের অনুরূপ তবে কেবল ফাংশন পয়েন্টার ব্যতীত পয়েন্টার অবজেক্টগুলি ধরে রাখতে পারে।
সি ++ অজানা ধরণের জিনিসগুলির সাথে মোকাবিলা করার জন্য দুটি আরও ভাল প্রক্রিয়া সরবরাহ করে: আমরা প্রকার মুছে ফেলার জন্য অবজেক্ট-ওরিয়েন্টেড কৌশলগুলি ব্যবহার করতে পারি (কেবলমাত্র ভার্চুয়াল পদ্ধতির মাধ্যমে বস্তুর সাথে ইন্টারঅ্যাক্ট করতে হবে যাতে আমাদের প্রকৃত প্রকারটি জানতে প্রয়োজন না হয়), বা আমরা করতে পারি ব্যবহার std::variant, টাইপ-নিরাপদ ইউনিয়ন এক প্রকার।

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

সি ++ আমাদের typeid()অপারেটরের সাথে একটি বস্তুর গতিশীল প্রকারের পরীক্ষা করতে দেয় যা আমাদের একটি std::type_infoবস্তু দেয় । হয় সংকলক কম্পাইল সময়ে অবজেক্টের ধরণটি জানে বা সংকলকটি প্রয়োজনীয় ধরণের তথ্য অবজেক্টের অভ্যন্তরে সঞ্চিত করেছে এবং রানটাইম এ এটি পুনরুদ্ধার করতে পারে।


3
খুব ব্যাপক।
Deduplicator

9
নোট করুন যে বহুবর্ষাত্মক বস্তুর প্রকারের অ্যাক্সেসের জন্য সংকলকটিকে এখনও জানতে হবে যে অবজেক্টটি নির্দিষ্ট উত্তরাধিকার পরিবারের অন্তর্ভুক্ত (যেমন বস্তুর সাথে টাইপযুক্ত রেফারেন্স / পয়েন্টার রয়েছে, নয় void*)।
Ruslan

5
+0 কারণ প্রথম বাক্যটি অসত্য বলে শেষ দুটি অনুচ্ছেদটি এটি সংশোধন করে।
মার্সিন

3
পলিমারফিক অবজেক্টের শুরুতে সাধারণত যা সঞ্চিত থাকে তা ভার্চুয়াল পদ্ধতি টেবিলের পয়েন্টার হয়, টেবিলটি নিজেই নয়।
পিটার গ্রিন

3
@ v.oddou আমার অনুচ্ছেদে আমি কিছু বিবরণ উপেক্ষা করেছি। typeid(e)অভিব্যক্তির স্থিতিশীল প্রকারকে আত্মপ্রকাশ করে e। যদি স্ট্যাটিক টাইপটি একটি বহুকর্মী ধরণের হয় তবে অভিব্যক্তিটি মূল্যায়ন করা হবে এবং সেই অবজেক্টের গতিশীল প্রকারটি পুনরুদ্ধার করা হবে। আপনি অজানা টাইপের স্মৃতিতে টাইপড নির্দেশ করতে পারবেন না এবং দরকারী তথ্য পাবেন। ইউনিয়নের উদাহরণস্বরূপ, ইউনিয়নের বস্তু নয়, ইউনিয়নের বর্ণনা দেয়। একটির টাইপড কেবল একটি শূন্য void*পয়েন্টার। এবং এগুলির void*বিষয়বস্তুগুলি পাওয়ার জন্য এটিকে অবহেলা করা সম্ভব নয় । সি ++ তে কোনও বক্সিং নেই, যতক্ষণ না স্পষ্টভাবে সেভাবে প্রোগ্রাম করা হয়।
আমন

51

অন্য উত্তরটি প্রযুক্তিগত দিকটি ভালভাবে ব্যাখ্যা করে তবে আমি কিছু সাধারণ "মেশিনের কোড সম্পর্কে কীভাবে চিন্তা করব" যুক্ত করতে চাই।

সংকলনের পরে মেশিন কোডটি বেশ বোবা, এবং এটি সত্যই ধরে নিয়েছে যে সমস্ত কিছু ইচ্ছা মত কাজ করে। বলুন আপনার মত একটি সাধারণ ফাংশন আছে

bool isEven(int i) { return i % 2 == 0; }

এটি একটি অন্তর্নির্মিত লাগে, এবং একটি বুল আউট spits।

আপনি এটি সংকলন করার পরে, আপনি এটি এই স্বয়ংক্রিয় কমলা জুসার জাতীয় কিছু হিসাবে ভাবতে পারেন:

স্বয়ংক্রিয় কমলা জুসার

এটি কমলা নেয়, এবং রস দেয়। এটি কী ধরণের বস্তুগুলিতে প্রবেশ করে তা স্বীকৃতি দেয়? না, তারা কমলা হওয়ার কথা। যদি এটি কমলা পরিবর্তে একটি আপেল পায় তবে কী হবে? সম্ভবত এটি বিরতি হবে। এটি কোনও বিষয় নয়, কারণ দায়িত্বশীল একজন মালিক এটিকে এভাবে ব্যবহার করার চেষ্টা করবেন না।

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

সতর্কবাণীটি হ'ল এমন কিছু সংঘটিত কোড রয়েছে যা সংকলক পাস করবে। উদাহরণগুলি হ'ল:

  • ভুল টাইপ ভোটদান: স্পষ্ট কাস্ট সঠিক গণ্য করা হয়, এবং এটি তা নিশ্চিত করার জন্য তিনি ভোটদান নয় প্রোগ্রামার হয় void*থেকে orange*যখন পয়েন্টার অপর প্রান্তের একটি আপেল হয়,
  • মেমরি ম্যানেজমেন্ট ইস্যু যেমন নাল পয়েন্টার, ঝুলন্ত পয়েন্টার বা ব্যবহারের পরে সুযোগ; সংকলক তাদের বেশিরভাগ সন্ধান করতে সক্ষম নয়,
  • আমি নিশ্চিত যে আমি মিস করছি এমন আরও কিছু আছে।

যেমনটি বলা হয়েছে, সংকলিত কোডটি ঠিক জুসার মেশিনের মতো - এটি কী প্রক্রিয়া করে তা জানে না, এটি কেবল নির্দেশগুলি কার্যকর করে। এবং নির্দেশাবলী ভুল হলে, এটি বিরতি। এজন্য সি ++ এর উপরের সমস্যাগুলি অনিয়ন্ত্রিত ক্র্যাশগুলির ফলাফল।


4
সংকলকটি পরীক্ষা করার চেষ্টা করে যে ফাংশনটি সঠিক ধরণের একটি অবজেক্টকে পাস করেছে, তবে সি এবং সি ++ উভয়ই জটিল ক্ষেত্রে এটি প্রতিটি ক্ষেত্রেই প্রমাণ করতে জটিল। সুতরাং, জুসারের সাথে আপনার আপেল-ও-কমলা তুলনা বেশ শিক্ষণীয়।
নিরাপত্তা পেয়ে ক্যালকাস

@ কালচাস আপনার মন্তব্যের জন্য ধন্যবাদ! এই বাক্যটি প্রকৃতপক্ষে একটি ওভারসিম্প্লিফিকেশন। আমি সম্ভাব্য সমস্যাগুলি সম্পর্কে কিছুটা ব্যাখ্যা করেছি, এগুলি আসলে প্রশ্নের সাথে সম্পর্কিত।
ফ্রেক্স

5
বাহ মেশিন কোডের জন্য দুর্দান্ত রূপক! আপনার রূপকটি 10x আরও ভাল ছবি দ্বারা তৈরি করা হয়েছে!
ট্রেভর বয়ড স্মিথ

2
"আমি নিশ্চিত যে আমি আর কিছু মিস করছি।" - অবশ্যই! সি এর void*কাছে coerces foo*স্বাভাবিক গাণিতিক পদোন্নতি, unionটাইপ punning, NULLবনাম nullptr, এমনকি মাত্র থাকার একটি খারাপ পয়েন্টার UB, ইত্যাদি হয় কিন্তু আমি বস্তুগত আপনার উত্তর উন্নতি হবে সেগুলো খুঁজে সব তালিকা মনে করি না, তাই এটি সম্ভবত ছুটি সেরা এটা যেমন হয়।
কেভিন

@ কেভিন আমি এখানে সি যুক্ত করা দরকার বলে মনে করি না, কারণ প্রশ্নটি কেবল সি ++ হিসাবে ট্যাগ করা আছে। এবং সি ++ এ void*সুস্পষ্টভাবে রূপান্তর করে না foo*, এবং unionটাইপ পেনিং সমর্থন করে না (ইউবি রয়েছে)।
Ruslan

3

ভেরিয়েবলের সি এর মতো ভাষায় প্রচুর মৌলিক বৈশিষ্ট্য রয়েছে:

  1. একটি নাম
  2. একটি টাইপ
  3. একটি সুযোগ
  4. একটি জীবনকাল
  5. একটি অবস্থান
  6. একটি মান

আপনার উত্স কোডে , অবস্থান, (5) ধারণামূলক, এবং এই অবস্থানটি তার নাম দ্বারা উল্লেখ করা হয়েছে, (1)। সুতরাং, একটি ভেরিয়েবল ডিক্লেয়ারেশন মান, (6) এর অবস্থান এবং স্থান তৈরি করতে ব্যবহৃত হয় এবং উত্সের অন্যান্য লাইনে আমরা সেই অবস্থানটি উল্লেখ করি এবং কিছু অভিব্যক্তিতে ভেরিয়েবলের নাম রেখে এটির মানটি উল্লেখ করি।

কেবলমাত্র কিছুটা সরলকরণ, একবার আপনার প্রোগ্রামটি সংকলক দ্বারা মেশিন কোডে অনুবাদ করা হলে, অবস্থান, (5) কিছু মেমরি বা সিপিইউ নিবন্ধের অবস্থান এবং ভেরিয়েবলের রেফারেন্সের যে কোনও উত্স কোড এক্সপ্রেশনগুলি মেমরি কোড অনুক্রমগুলিতে অনুবাদ করা হয় যা সেই মেমরিকে উল্লেখ করে অথবা সিপিইউ নিবন্ধের অবস্থান।

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

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

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

প্রসেসর সরাসরি কিছু মৌলিক ডেটা ধরণের সমর্থন করে যেমন বাইট / শব্দ / ইনট / দীর্ঘ স্বাক্ষরিত / স্বাক্ষরিত, ভাসমান, ডাবল ইত্যাদি etc আপনি যদি একইভাবে মেমরির অবস্থানটি স্বাক্ষরিত বা স্বাক্ষরযুক্ত হিসাবে একইভাবে আচরণ করেন তবে প্রসেসর সাধারণত অভিযোগ বা আপত্তি জানাতে পারবেন না for উদাহরণস্বরূপ, যদিও এটি প্রোগ্রামে সাধারণত একটি যুক্তি ত্রুটি হতে পারে। ভেরিয়েবলের সাথে প্রতিটি মিথস্ক্রিয়ায় প্রসেসরকে নির্দেশ দেওয়া প্রোগ্রামিংয়ের কাজ।

এই মৌলিক আদিম প্রকারের বাইরে, আমাদের ডেটা স্ট্রাকচারগুলিতে জিনিসগুলি এনকোড করতে হবে এবং সেই আদিমগুলির পদগুলিতে এগুলি পরিচালনা করতে অ্যালগরিদম ব্যবহার করতে হবে।

সি ++ তে বহুবর্ষের জন্য শ্রেণি শ্রেণিবিন্যাসের সাথে জড়িত অবজেক্টগুলির একটি পয়েন্টার থাকে, সাধারণত অবজেক্টের শুরুতে, যা শ্রেণি-নির্দিষ্ট ডেটা কাঠামোকে বোঝায়, যা ভার্চুয়াল প্রেরণ, castালাই ইত্যাদিতে সহায়তা করে ..

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


1
"অনুবাদ শেষ হলে নামটি ভুলে যায়" এর সাথে সাবধানতা অবলম্বন করুন ... লিঙ্কিং নামগুলির মাধ্যমে করা হয় ("অপরিজ্ঞাত প্রতীক xy") এবং গতিশীল সংযোগের সাথে চলমান সময়েও এটি হতে পারে। Blog.fesnel.com/blog/2009/08/19/… দেখুন । কোনও ডিবাগ প্রতীক, এমনকি ছিনতাই করা হয়নি: গতিশীল সংযোগের জন্য আপনার ফাংশনটির (এবং, আমি ধরে নিই, বৈশ্বিক পরিবর্তনশীল) নামটি প্রয়োজন। সুতরাং কেবলমাত্র অভ্যন্তরীণ বস্তুর নামগুলি ভুলে যেতে পারে। উপায় দ্বারা, পরিবর্তনশীল বৈশিষ্ট্যের ভাল তালিকা।
পিটার - মনিকা

@ পিটারএ.স্নাইডার, আপনি একেবারে ঠিক বলেছেন, জিনিসের বড় ছবিতে, লিংকার এবং লোডাররা উত্স কোড থেকে আসা (গ্লোবাল) ফাংশন এবং ভেরিয়েবলের নামগুলিও অংশগ্রহণ করে এবং ব্যবহার করে।
এরিক tদ

একটি অতিরিক্ত জটিলতা হ'ল কিছু সংকলক নিয়মের ব্যাখ্যা করেন যা মানক অনুসারে, সংকলকরা কিছু নির্দিষ্ট জিনিসকে উপনাম হিসাবে ধরে রাখে না যা তাদেরকে বিভিন্ন ধরণের জড়িত অপ্রয়োজনীয় হিসাবে বিবেচনা করে না এমনকি এমন ক্ষেত্রেও যেগুলি লিখিতভাবে আলিয়াসিংয়ের সাথে জড়িত না । এর মতো কিছু দেওয়া হয়েছে useT1(&unionArray[i].member1); useT2(&unionArray[j].member2); useT1(&unionArray[i].member1);, ঝনঝন এবং জিসিসি অনুমান করে যে পয়েন্টারটি unionArray[j].member2অ্যাক্সেস করতে পারে না unionArray[i].member1যদিও উভয়ই একই থেকে প্রাপ্ত unionArray[]
সুপারক্যাট

সংকলকটি ভাষা স্পেসিফিকেশনকে সঠিকভাবে ব্যাখ্যা করে কিনা বা না, এর কাজ হ'ল মেশিন কোড নির্দেশ ক্রম তৈরি করা যা প্রোগ্রামটি চালায়। এর অর্থ হ'ল (মডুলো অপ্টিমাইজেশন এবং অন্যান্য অনেকগুলি উপাদান) উত্স কোডের প্রতিটি পরিবর্তনশীল অ্যাক্সেসের জন্য এটি কিছু মেশিন কোড নির্দেশাবলী তৈরি করতে পারে যা প্রসেসরকে স্টোরেজ অবস্থানের জন্য কী আকার এবং ডেটা ব্যাখ্যার জন্য ব্যবহার করতে হবে তা জানিয়ে দেয়। প্রসেসরটি ভেরিয়েবল সম্পর্কে কিছুই মনে রাখে না তাই প্রতিবার ভেরিয়েবলটি অ্যাক্সেস করার কথা মনে করা হয়, এটি কীভাবে করা যায় তার নির্দেশ দিতে হবে।
এরিক tদ

2

যদি আমি একটি নির্দিষ্ট ধরণের একটি ভেরিয়েবল সংজ্ঞায়িত করি তবে এটি কীভাবে এটি ভেরিয়েবলের প্রকারের ট্র্যাক রাখে।

এখানে দুটি প্রাসঙ্গিক পর্যায় রয়েছে:

  • সংকলন সময়

সি সংকলক সি কোডটি মেশিনের ভাষায় সংকলন করে। সংকলকটিতে সমস্ত তথ্য রয়েছে যা এটি আপনার উত্স ফাইল (এবং গ্রন্থাগারগুলি এবং এটির কাজটি করার জন্য যা কিছু অন্যান্য জিনিস প্রয়োজন) থেকে পেতে পারে। সি সংকলকটি কী বোঝায় তা ট্র্যাক করে। সি সংকলক জানে যে আপনি যদি কোনও ভেরিয়েবলকে ঘোষনা করেন charতবে এটি চর।

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

  • রানটাইম

সংকলকটির আউটপুট - সংকলিত এক্সিকিউটেবল - মেশিন ল্যাঙ্গুয়েজ, যা আপনার ওএস দ্বারা র‌্যামে লোড করা হয় এবং আপনার সিপিইউ দ্বারা সরাসরি চালিত হয়। যন্ত্রের ভাষায়, "টাইপ" এর কোনও ধারণা নেই - এটির কেবলমাত্র কমান্ড রয়েছে যা র‌্যামের কোনও স্থানে কাজ করে। কমান্ড প্রকৃতপক্ষে একটি নির্দিষ্ট টাইপ তারা চালনা আছে (অর্থাত, সেখানে একটি মেশিন ভাষা কমান্ড "এই দুটি 16 বিট র্যাম অবস্থানে 0x100 এবং 0x521 সংরক্ষিত পূর্ণসংখ্যার জুড়ুন" হতে পারে), কিন্তু কোন তথ্য নেই কোন জায়গায় সিস্টেম যে এই অবস্থানগুলিতে বাইটগুলি আসলে পূর্ণসংখ্যার প্রতিনিধিত্ব করে। সেখানে টাইপ ত্রুটি থেকে কোনো সুরক্ষা সব এখানে।


যদি কোনও সুযোগে আপনি "বাইট কোড ওরিয়েন্টেড ভাষাগুলি" দিয়ে সি # বা জাভা উল্লেখ করছেন তবে পয়েন্টারগুলি কোনওভাবেই সেগুলি থেকে বাদ পড়বে না; সম্পূর্ণ বিপরীতে: পয়েন্টারগুলি সি # এবং জাভাতে অনেক বেশি সাধারণ (এবং ফলস্বরূপ, জাভার অন্যতম সাধারণ ত্রুটি হ'ল "নুলপয়েন্টারএক্সসেপশন")। তাদের "রেফারেন্স" নামকরণ করা হয়েছে এটি কেবলমাত্র পরিভাষার একটি বিষয়।
পিটার - মনিকা

@ পিটারএ.স্নাইডার, অবশ্যই, নালপয়েন্টার এক্সসেপশন আছে, তবে আমি উল্লিখিত ভাষাগুলিতে একটি রেফারেন্স এবং পয়েন্টারের মধ্যে খুব নির্দিষ্ট পার্থক্য রয়েছে (যেমন জাভা, রুবি, সম্ভবত সি #, এমনকি কিছুটা পার্ল) - রেফারেন্সটি একসাথে যায় তাদের টাইপ সিস্টেম, আবর্জনা সংগ্রহ, স্বয়ংক্রিয় মেমরি পরিচালনা ইত্যাদি সহ; সাধারণত স্পষ্টভাবে কোনও মেমরি অবস্থান ( char *ptr = 0x123সি এর মতো ) বলা সম্ভব হয় না । আমি বিশ্বাস করি আমার "পয়েন্টার" শব্দটির ব্যবহারটি এই প্রসঙ্গে বেশ পরিষ্কার হওয়া উচিত। যদি তা না হয় তবে নির্দ্বিধায় আমাকে মাথা তুলে দিন এবং আমি উত্তরে একটি বাক্য যুক্ত করব।
AnoE

পয়েন্টারগুলি সি ++ তেও ;-)- তে "টাইপ সিস্টেমের সাথে একসাথে যান"। (আসলে, জাভার ক্লাসিক জেনেরিকগুলি সি ++ এর তুলনায় কম জোরালোভাবে টাইপ করা হয়েছে)) আবর্জনা সংগ্রহ এমন একটি বৈশিষ্ট্য যা সি ++ ম্যান্ডেট না করার সিদ্ধান্ত নিয়েছে, তবে এটি বাস্তবায়নের পক্ষে এটি সরবরাহ করা সম্ভব এবং আমরা পয়েন্টারগুলির জন্য কী শব্দ ব্যবহার করি তার সাথে এর কোনও যোগসূত্র নেই।
পিটার - মনিকা

ঠিক আছে, @ পিটারএ.স্নাইডার, আমি সত্যিই মনে করি না যে আমরা এখানে স্তর পেয়ে যাচ্ছি। আমি অনুচ্ছেদে সরিয়েছি যেখানে আমি পয়েন্টারগুলির উল্লেখ করেছি, যাইহোক এটি উত্তরের জন্য কিছুই করেনি।
AnoE

1

কয়েকটি গুরুত্বপূর্ণ বিশেষ কেস রয়েছে যেখানে সি টাইম রান টাইমে কোনও ধরণের সঞ্চয় করে।

ক্লাসিক সমাধানটি একটি বৈষম্যমূলক ইউনিয়ন: এমন একটি ডেটা স্ট্রাকচার যা বিভিন্ন ধরণের অবজেক্টের মধ্যে একটি থাকে, এবং এমন একটি ক্ষেত্র যা বলে যে এটি বর্তমানে কী ধরণের রয়েছে। একটি টেম্প্লেটেড সংস্করণ সি ++ স্ট্যান্ডার্ড লাইব্রেরিতে রয়েছে std::variant। সাধারণত, ট্যাগটি একটি হতে পারে enumতবে আপনার যদি আপনার ডেটার জন্য সমস্ত বিট স্টোরেজের প্রয়োজন না হয় তবে এটি একটি বিটফিল্ড হতে পারে।

এর অন্যান্য সাধারণ ক্ষেত্রে গতিশীল টাইপিং। যখন আপনার classকোনও virtualফাংশন রয়েছে, প্রোগ্রামটি ভার্চুয়াল ফাংশন সারণীতে সেই ফাংশনের একটি পয়েন্টার সংরক্ষণ করবে , যা এটি classনির্মাণের পরে প্রতিটি উদাহরণের জন্য সূচনা করবে । সাধারণত, এর অর্থ সমস্ত শ্রেণীর দৃষ্টান্তের জন্য একটি ভার্চুয়াল ফাংশন টেবিল এবং প্রতিটি উদাহরণ উপযুক্ত টেবিলের জন্য একটি পয়েন্টার ধারণ করে। (এটি সময় এবং স্মৃতি সাশ্রয় করে কারণ একক পয়েন্টারের চেয়ে টেবিলটি অনেক বড় হবে)) আপনি যখন virtualকোনও পয়েন্টার বা রেফারেন্সের মাধ্যমে সেই ফাংশনটি কল করবেন তখন প্রোগ্রামটি ভার্চুয়াল সারণীতে ফাংশন পয়েন্টারটি সন্ধান করবে। (যদি এটি সংকলনের সময় সঠিক ধরণেরটি জানেন তবে এটি এই পদক্ষেপটি এড়িয়ে যেতে পারে)) এটি কোডটি বেস শ্রেণীর পরিবর্তে ডাইরাইটেড টাইপের প্রয়োগ কল করতে পারে allows

জিনিস যে এখানে প্রাসঙ্গিক করে তোলে: প্রতিটি ofstreamএকটি পয়েন্টার রয়েছে ofstreamভার্চুয়াল টেবিল, প্রতিটি ifstreamথেকে ifstreamভার্চুয়াল টেবিল ইত্যাদি। শ্রেণি শ্রেণিবিন্যাসের জন্য, ভার্চুয়াল টেবিল পয়েন্টারটি ট্যাগ হিসাবে পরিবেশন করতে পারে যা প্রোগ্রামকে জানায় যে শ্রেণীর অবজেক্টটি কী ধরণের!

যদিও ভাষার স্ট্যান্ডার্ড এমন লোকগুলিকে না জানায় যারা সংকলকগুলি ডিজাইন করেন তাদের কীভাবে হুডের নীচে রানটাইম বাস্তবায়ন করতে হবে, আপনি কীভাবে আশা করতে পারেন dynamic_castএবং typeofকাজ করতে পারেন ।


"ভাষা মান পরিকল্পনাটি বলতে নেই" আপনি সম্ভবত জোর দেওয়া উচিত যে, "পরিকল্পনাটি" প্রশ্নে ভাবেন হয় লেখার জিসিসি, ঝনঝন শব্দ, msvc ইত্যাদি মানুষ ব্যবহার সেই ++, তাদের সি কম্পাইল করার।

@ ক্যালথ ভাল পরামর্শ!
ডেভিস্লোর 22:48
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.