সিতে শূন্যের অর্থ শূন্য হয় না কেন?


25

জাভা এবং সি # এর মতো দৃ )়-টাইপ করা ভাষায়, void(বা Void) কোনও পদ্ধতির রিটার্ন টাইপ হিসাবে বোঝায়:

এই পদ্ধতিটি কিছুই ফেরায় না। কিছুই নেই। ফেরত নেই. আপনি এই পদ্ধতি থেকে কিছুই পাবেন না।

সত্যিই আশ্চর্যের বিষয়টি হ'ল সিতে, voidরিটার্ন টাইপ হিসাবে বা এমনকি কোনও পদ্ধতি প্যারামিটার ধরণের অর্থ:

এটি সত্যিই কিছু হতে পারে। এটি জানতে আপনাকে উত্স কোডটি পড়তে হবে। শুভকামনা। যদি এটি কোনও পয়েন্টার হয় তবে আপনি কী করছেন তা সত্যই আপনার জানা উচিত।

সিতে নিম্নলিখিত উদাহরণগুলি বিবেচনা করুন:

void describe(void *thing)
{
    Object *obj = thing;
    printf("%s.\n", obj->description);
}

void *move(void *location, Direction direction)
{
    void *next = NULL;

    // logic!

    return next;
}

স্পষ্টতই, দ্বিতীয় পদ্ধতিটি একটি পয়েন্টার দেয়, যা সংজ্ঞা অনুসারে কিছু হতে পারে।

সি যেহেতু জাভা এবং সি # এর চেয়ে পুরানো, তাই কেন এই ভাষাগুলি void"কিছুই না" হিসাবে অর্থ গ্রহণ করেছিল যখন সি এটিকে "কিছুই বা কিছুই (যখন পয়েন্টার)" হিসাবে ব্যবহার করেছিল?


138
voidকোড উদাহরণটি ব্যবহার করে void*যা সম্পূর্ণ ভিন্ন কিছু বলে আপনার প্রশ্নের শিরোনাম এবং পাঠ্য সম্পর্কে আলোচনা ।

4
এছাড়াও নোট করুন যে জাভা এবং সি # এর একই ধারণা রয়েছে, তারা কেবল একে Objectএকে একে কেটে যাওয়ার জন্য কল করে ।
0:41 এ হাঁস মুচিং

4
@ মফি তারা কি দৃ exactly়ভাবে টাইপড নয়? সি # দ্বারা হাঁসের টাইপিং ব্যবহার করে, আপনি কি সেই dynamicটাইপটি বোঝেন যা খুব কমই ব্যবহৃত হয়?
অ্যাক্সারিড্যাক্স

9
@ মফি: গতবার আমি উইকিপিডিয়াকে " দৃ strongly় -টাইপড" এর জন্য এগারোটি পারস্পরিক বিরোধী অর্থের তালিকাভুক্ত পরীক্ষা করেছি । "সি # দৃ strongly়ভাবে টাইপ করা হয় না" বলা তাই অর্থহীন।
এরিক লিপার্ট

8
@ লাইটনেসেসেসিনআরবিট: না, মূল কথাটি হ'ল শব্দটির কোনও অনুমোদনযোগ্য সংজ্ঞা নেই। উইকিপিডিয়া কোনও ব্যবস্থাপত্র সংস্থান নয় যা আপনাকে জানায় যে কোনও শব্দটির সঠিক অর্থ কী। এটি বর্ণনামূলক সম্পদ। এটি এগারোটি ভিন্ন ভিন্ন বিরোধী অর্থ বর্ণনা করে বলে প্রমাণটি প্রমাণ করে যে শব্দটি সতর্কতার সাথে সংজ্ঞা না দিয়ে কথোপকথনে ব্যবহার করা যাবে না । অন্যথায় করা মানে এই যে প্রতিকূলতা খুব ভাল, কথোপকথনের লোকেরা একে অপরের সাথে নয়, অতীত কথা বলবে।
এরিক লিপার্ট

উত্তর:


58

মূলশব্দ void(কোনও পয়েন্টার নয়) এর অর্থ সেই ভাষাগুলিতে "কিছুই নয়"। এটি ধারাবাহিক।

আপনি যেমন উল্লেখ করেছেন, void*এমন ভাষাতে "কোনও কিছুর পয়েন্টার" অর্থ যা কাঁচা পয়েন্টার (সি এবং সি ++) সমর্থন করে। এটি একটি দুর্ভাগ্যজনক সিদ্ধান্ত কারণ আপনি যেমনটি উল্লেখ করেছেন, এটি voidদুটি ভিন্ন জিনিসকে বোঝায়।

voidবিভিন্ন প্রসঙ্গে "কিছুই না" এবং "কিছু" বোঝানোর পিছনে theতিহাসিক কারণটি আমি খুঁজে পেতে সক্ষম হইনি , তবে সি এটি বেশ কয়েকটি জায়গায় এটি করে। উদাহরণস্বরূপ, staticবিভিন্ন প্রসঙ্গে বিভিন্ন উদ্দেশ্য রয়েছে। অনুশীলন সম্পর্কে কেউ কী ভাবেন তা বিবেচনা না করেই এইভাবে কীওয়ার্ডগুলির পুনঃব্যবহারের সি ভাষায় স্পষ্টত নজির রয়েছে।

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


2
আমি বাড়ি এলে আমি একটি রেফারেন্স সরবরাহ করব

4
They also do not allow raw pointers and do not need easy C compatibility.মিথ্যা। সি # এর পয়েন্টার রয়েছে। এগুলি সাধারণত (এবং সাধারণত হওয়া উচিত) বন্ধ থাকে তবে তারা সেখানে থাকে।
ম্যাগাস

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

20
এমনকি void *, voidমানে হলো "কিছুই", নয় "কিছু"। আপনি void *এটিকে অবহেলা করতে পারবেন না , আপনাকে প্রথমে এটি অন্য পয়েন্টার টাইপ করতে হবে।
oefe

2
@oefe আমি মনে করি যে চুলগুলি বিভক্ত করা অর্থহীন, কারণ voidএবং void*এটি বিভিন্ন ধরণের (আসলে, void"কোনও প্রকারের নয়")। এটি " intইন int*মানে কিছু " বলতে যতটা বোঝা যায় । না, আপনি একবার পয়েন্টার ভেরিয়েবল ঘোষণা করলে আপনি বলছেন "এটি একটি মেমরি ঠিকানা যা কিছু ধারণ করতে সক্ষম।" এর ক্ষেত্রে void*, আপনি বলছেন "এই ঠিকানাটিতে কিছু রয়েছে তবে পয়েন্টারের ধরণ থেকে কোনও কিছু অনুমান করা যায় না।"

32

voidএবং void*দুটি ভিন্ন জিনিস। voidসি এর অর্থ জাভাতে ঠিক একই জিনিস, কোনও ফেরতের মূল্যের অনুপস্থিতি। A void*একটি পয়েন্টার যা কোনও ধরণের অনুপস্থিতি।

সি এর সমস্ত পয়েন্টারকে ডিফারেন্স করতে সক্ষম হওয়া দরকার। আপনি যদি ক এটিকে অবলম্বন করেন তবে আপনি void*কী ধরণের প্রত্যাশা করবেন? মনে রাখবেন সি পয়েন্টারগুলি কোনও রানটাইম টাইপের তথ্য বহন করে না, সুতরাং টাইপটি অবশ্যই সংকলনের সময় জানা উচিত।

সেই প্রসঙ্গটি দেওয়া, আপনি যুক্তিযুক্তভাবে কেবল কোনও void*অবজ্ঞার সাথে করতে পারেন কেবল তা এড়িয়ে যাওয়া, এটি হুবহু আচরণ যা voidটাইপটি নির্দেশ করে।


1
আপনি "এটিকে উপেক্ষা করুন" বিট না পাওয়া পর্যন্ত আমি সম্মত। ফিরে আসা জিনিসটিতে এটি কীভাবে ব্যাখ্যা করা যায় সে সম্পর্কে তথ্য রয়েছে possible অন্য কথায়, এটি বেসিক ভেরিয়েন্টের সি সমতুল্য হতে পারে। "আপনি যখন এটি পেয়েছেন তখন এটি কী তা নির্ধারণ করার জন্য একবার নজর দিন - আপনি কী পাবেন তা আমি আপনাকে সামনে বলতে পারছি না"।
ফ্লোরিস

1
অথবা এটি অন্যভাবে বলতে গেলে অনুমানের সাথে আমি পয়েন্টার দ্বারা সম্বোধন করা মেমরি লোকেশনে প্রথম বাইটে একটি প্রোগ্রামার-সংজ্ঞায়িত "টাইপ ডেস্ক্রিপ্টর" রাখতে পারি, যা আমাকে জানায় যে অনুসরণ করা বাইটগুলিতে আমি কী ধরনের ডেটা খুঁজে পেতে আশা করতে পারি।
রবার্ট হার্ভে

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

4
@ রবার্টহারভে হ্যাঁ, তবে তারপরে আপনি কোনও শূন্য পয়েন্টারকে অবজ্ঞা করছেন না; আপনি শূন্য পয়েন্টারটিকে একটি চর পয়েন্টারটিতে কাস্টিং করছেন এবং তারপরে চর পয়েন্টারটিকে ডিফারেন্সিং করছেন।
ব্যবহারকারী 253751

4
@ ফ্লোরিস gccআপনার সাথে একমত নয় যদি আপনি মানটি ব্যবহার করার চেষ্টা করেন তবে gccএকটি ত্রুটি বার্তা বলার উত্পাদন করুন error: void value not ignored as it ought to be
ক্যাস্পারড

19

সম্ভবত voidরিটার্নের ধরণ হিসাবে ভাবা আরও কার্যকর হবে । তারপরে আপনার দ্বিতীয় পদ্ধতিতে "এমন একটি পদ্ধতি পড়বে যা একটি টাইপযুক্ত পয়েন্টারটি ফেরত দেয়।"


যে সাহায্য করে। অবজেক্ট-ভিত্তিক ভাষাগুলিতে বছরের পর বছর কে সি (অবশেষে!) শিখছে এমন কেউ হিসাবে, পয়েন্টার এমন একটি জিনিস যা আমার কাছে খুব নতুন ধারণা। দেখে মনে হচ্ছে যে কোনও পয়েন্টার ফিরিয়ে দেওয়ার সময়, voidএটি *অ্যাকশনস্ক্রিপ্ট 3 এর মতো ভাষার সমান, যার সহজ অর্থ "কোনও রিটার্নের ধরণ"।
নাফটুলি কে

5
ভাল, voidএকটি ওয়াইল্ডকার্ড নয়। একটি পয়েন্টার কেবল একটি মেমরি ঠিকানা। *"এখানে এই ডেটা টাইপ যা আপনি এই পয়েন্টার দ্বারা উল্লেখ মেমরি ঠিকানা খুঁজে পেতে আশা করতে পারেন" বলার আগে একটি প্রকার স্থাপন করা । " সংকলকটির voidকাছে *বলার আগে রেখে দেওয়া "আমি টাইপটি জানি না; কেবল আমাকে কাঁচা পয়েন্টারটি ফিরিয়ে দিন এবং আমি এটি ডেটাতে যা নির্দেশ করব তাতে কী করতে হবে তা আমি বের করব" "
রবার্ট হারভে

2
এমনকি আমি এটিও বলব যে void*একটি "অকার্যকর" পয়েন্ট। কিছুই নেই এমন একটি খালি পয়েন্টার যার দিকে এটি নির্দেশ করে না। তবুও আপনি এটি অন্য পয়েন্টারের মতো কাস্ট করতে পারেন।
রবার্ট

11

পরিভাষাটি কিছুটা শক্ত করি।

থেকে অনলাইন সি 2011 মান :

6.2.5 প্রকার
...
19 voidধরণের মানগুলির একটি খালি সেট থাকে; এটি একটি অসম্পূর্ণ বস্তুর প্রকার যা সম্পূর্ণ করা যায় না।
... .3.৩
রূপান্তর
...
.3.৩.২.২ অকার্যকর

1 কোনও voidঅভিব্যক্তির (অস্তিত্বহীন) মান ( টাইপযুক্ত একটি এক্সপ্রেশন ) কোনওভাবেইvoid ব্যবহার করা হবে না এবং অন্তর্নিহিত বা স্পষ্ট রূপান্তরকরণ (বাদে void) প্রয়োগ করা হবে না যেমন একটি অভিব্যক্তি। যদি অন্য কোনও ধরণের void অভিব্যক্তিটিকে অভিব্যক্তি হিসাবে মূল্যায়ন করা হয়, তবে এর মান বা ডিজাইনারটি বাতিল করা হবে। ( voidএর পার্শ্ব প্রতিক্রিয়াগুলির জন্য একটি অভিব্যক্তি মূল্যায়ন করা হয়))

6.3.2.3 পয়েন্টার

1 এ পয়েন্টারvoidপয়েন্টার থেকে বা কোনও বস্তুর প্রকারে রূপান্তরিত হতে পারে। যে কোনও অবজেক্টের ধরণের পয়েন্টারটি পয়েন্টারকে অকার্যকর হয়ে আবার ফিরে যেতে পারে; ফলাফলটি মূল পয়েন্টারের সমান তুলনা করবে।

একটি voidঅভিব্যক্তি কোনো মূল্যই (যদিও এটা পার্শ্ব প্রতিক্রিয়া হতে পারে) আছে। আমার যদি কোনও ফাংশন ফেরত সংজ্ঞায়িত হয় void, তবে:

void foo( void ) { ... }

তারপর কল

foo();

একটি মান মূল্যায়ন না; আমি ফলাফলকে কিছুতেই বরাদ্দ করতে পারি না, কারণ কোনও ফলাফল নেই।

একটি পয়েন্টার থেকে voidমূলত একটি "জেনেরিক" পয়েন্টার টাইপ হয়; আপনি void *সুস্পষ্ট কাস্টের প্রয়োজন ছাড়াই অন্য যে কোনও অবজেক্ট পয়েন্টার টাইপের মান নির্ধারণ করতে পারেন (এজন্য সমস্ত সি প্রোগ্রামার আপনার ফলাফলটি কাস্ট করার জন্য আপনাকে চিত্কার করবে malloc)।

আপনি সরাসরি ড্রেফারেন্স করতে পারবেন না void *; পয়েন্ট-টু অবজেক্টে অ্যাক্সেস করার আগে আপনাকে প্রথমে এটি অবশ্যই আলাদা অবজেক্ট পয়েন্টার টাইপ করতে হবে।

voidপয়েন্টারগুলি (বেশি বা কম) জেনেরিক ইন্টারফেস প্রয়োগ করতে ব্যবহৃত হয়; ক্যানোনিকাল উদাহরণটি হ'ল qsortলাইব্রেরি ফাংশন, যা কোনও ধরণের অ্যারে বাছাই করতে পারে যতক্ষণ আপনি টাইপ-সচেতন তুলনা ফাংশন সরবরাহ করেন না।

হ্যাঁ, দুটি ভিন্ন ধারণার জন্য একই কীওয়ার্ডটি ব্যবহার করা (কোনও মূল্য বনাম জেনেরিক পয়েন্টার নয়) বিভ্রান্তিকর, তবে এটি এর মতো নয় যা নজির নেই; staticসি এবং সি ++ উভয়েরই একাধিক স্বতন্ত্র অর্থ রয়েছে।


9

জাভা এবং সি # তে কোনও পদ্ধতির রিটার্ন টাইপ হিসাবে বাতিল বলে মনে হচ্ছে: এই পদ্ধতিটি কোনও কিছুই ফেরায় না। কিছুই নেই। ফেরত নেই. আপনি এই পদ্ধতি থেকে কিছুই পাবেন না।

উক্তিটি সঠিক। এটি সি এবং সি ++ এর জন্যও সঠিক।

সি-তে, রিটার্ন টাইপ হিসাবে বা এমনকি পদ্ধতি প্যারামিটার টাইপের মতো অকার্যকর মানে something

উক্তিটি ভুল। voidসি বা সি ++ তে রিটার্ন টাইপের অর্থ এটি সি # এবং জাভাতে একই জিনিস does আপনি বিভ্রান্ত voidকরছেন void*এগুলি সম্পূর্ণ আলাদা।

এটি কি বিভ্রান্তিকর নয় voidএবং void*দুটি সম্পূর্ণ ভিন্ন জিনিস বোঝায়?

হাঁ।

পয়েন্টার কি? একটি অকার্যকর পয়েন্টার কি?

একটি পয়েন্টার এমন একটি মান যা মানানসই হতে পারে । একটি বৈধ পয়েন্টার নির্ধারণ করা পয়েন্ট-টু টাইপের একটি সঞ্চয় স্থান দেয় । একটি অকার্যকর পয়েন্টার একটি পয়েন্টার যা নির্দিষ্ট পয়েন্ট-টু টাইপ নেই; স্টোরেজের অবস্থান তৈরির জন্য মানটি অবলম্বন করার আগে এটি আরও নির্দিষ্ট পয়েন্টার টাইপে রূপান্তর করতে হবে ।

সি, সি ++, জাভা এবং সি # তে কি অকার্যকর পয়েন্টার একই?

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

সি যেহেতু জাভা এবং সি # এর চেয়ে পুরানো, তাই কেন এই ভাষাগুলি "কিছুই না" হিসাবে অকার্যকর রূপ গ্রহণ করেছিল, যখন সি এটিকে "কিছুই বা কিছুই (কখন একটি পয়েন্টার)" হিসাবে ব্যবহার করেছিল?

প্রশ্নটি অন্তর্নিহিত কারণ এটি মিথ্যাবাদীদের অনুমান করে। আসুন আরও কিছু ভাল প্রশ্ন জিজ্ঞাসা করা যাক।

জাভা এবং সি # কেন voidউদাহরণস্বরূপ, ভিজ্যুয়াল বেসিক কনভেনশনটি ব্যবহার করে যে ফাংশনগুলি কখনই অকার্যকর হয় না এবং সাব্রোটাইনগুলি সর্বদা বাতিল হয় না কেন কনভেনশনটি একটি বৈধ রিটার্ন টাইপ গ্রহণ করেছিল ?

জাভা বা সি # তে আগত voidপ্রকারের ভাষা থেকে আগত প্রোগ্রামারদের সাথে পরিচিত হতে ।

সি # কেন এমন বিভ্রান্তিকর কনভেনশন গ্রহণ করেছিল void*যার থেকে সম্পূর্ণ ভিন্ন অর্থ রয়েছে void?

প্রোগ্রামারদের সাথে পরিচিত হতে সি # তে যে ভাষাগুলি থেকে void*পয়েন্টার টাইপ হয়।


5
void describe(void *thing);
void *move(void *location, Direction direction);

প্রথম ফাংশন কিছুই দেয় না। দ্বিতীয় ফাংশনটি একটি অকার্যকর পয়েন্টার দেয়। আমি যে দ্বিতীয় ফাংশন হিসাবে ঘোষণা ছিল

void* move(void* location, Direction direction);

যদি আপনি "অকার্যকর" অর্থ "অর্থহীন" হিসাবে মনে করেন তবে সহায়তা করতে পারে। এর রিটার্ন মান describe"অর্থ ছাড়াই"। এই জাতীয় ফাংশন থেকে কোনও মান ফেরত দেওয়া অবৈধ কারণ আপনি সংকলককে বলেছিলেন যে ফেরতের মান অর্থহীন। আপনি সেই ফাংশন থেকে রিটার্ন মান ক্যাপচার করতে পারবেন না কারণ এটি অর্থহীন। আপনি কোনও প্রকারের পরিবর্তনশীল ঘোষণা করতে পারবেন না voidকারণ এটি অর্থহীন। উদাহরণস্বরূপ void nonsense;বাজে কথা এবং আসলে অবৈধ। আরও মনে রাখবেন যে শূন্যতার একটি অ্যারেও void void_array[42];বোকা।

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

সুতরাং আপনি যদি কোনও শূন্য পয়েন্টারকে অবজ্ঞা না করতে পারেন এবং আপনি কোনও শূন্যস্থান তৈরি করতে না পারেন তবে আপনি কীভাবে সেগুলি ব্যবহার করতে পারেন? উত্তরটি হ'ল যে কোনও ধরণের পয়েন্টারটি এখান থেকে যেতে পারে void*। কিছু পয়েন্টারকে ingালাই করা void*এবং মূল পয়েন্টারে ফিরে পয়েন্টারটি মূল পয়েন্টারের সমান মান অর্জন করবে। সি স্ট্যান্ডার্ড এই আচরণের গ্যারান্টি দেয়। আপনি সিতে এতগুলি শূন্য পয়েন্টার দেখানোর প্রাথমিক কারণ হ'ল এই ক্ষমতাটি তথ্য গোপন এবং অবজেক্ট-ভিত্তিক প্রোগ্রামিংকে বাস্তবায়ন করার একটি উপায় সরবরাহ করে যা খুব অ-অবজেক্ট ভিত্তিক ভাষা।

পরিশেষে, আপনি প্রায়শই বরং তার চেয়ে বেশি moveঘোষিত দেখতে পঠন কারণটি হ'ল ধরণের পরিবর্তে নামের পাশে তারকাচিহ্ন স্থাপন করা সি-তে একটি সাধারণ প্রচলিত কারণ reason নীচের ঘোষণাটি আপনাকে বড় সমস্যায় ফেলবে : এটি আপনাকে তৈরি করবে মনে হয় আপনি একটিতে দুটি পয়েন্টার ঘোষণা করছেন । তুমি নও. এই ঘোষণা প্রদান করে একটি একটি থেকে বদলে পয়েন্টার । যথাযথ ঘোষণাটি হ'ল আপনি নক্ষত্রটি প্রকারের সাথে সম্পর্কিত যদি আপনি ঘোষণাপত্রের প্রতি প্রতি পরিবর্তনশীল কেবলমাত্র ঘোষণার অনুশীলনকে আঁকড়ে থাকেন। তবে মনে রাখবেন যে আপনি ভান করছেন।void *move(...)void* move(...)int* iptr, jptr;intjptrintintint *iptr, *jptr;


"যে কোডটি নাল পয়েন্টারকে রেফারেন্স দেয় তা সংকলন করবে না" " আমি মনে করি আপনি এমন কোড বোঝাচ্ছেন যা একটি শূন্য পয়েন্টারটিকে সংকলন করবে না re সংকলক আপনাকে নাল পয়েন্টারকে অবজ্ঞা করা থেকে রক্ষা করে না; এটি একটি রানটাইম সমস্যা।
কোডি গ্রে

@ কোডি গ্রে - ধন্যবাদ! স্থির। যে কোডটি নাল পয়েন্টারটিকে রেফারেন্স দেয় তা সংকলন করবে (যতক্ষণ পয়েন্টারটি নয় void* null_ptr = 0;)।
ডেভিড হামেন

2

সহজ কথায় বলতে গেলে, কোনও পার্থক্য নেই । আমি আপনাকে কিছু উদাহরণ দিতে দিন।

বলুন আমার গাড়ি নামে একটি ক্লাস আছে।

Car obj = anotherCar; // obj is now of type Car
Car* obj = new Car(); // obj is now a pointer of type Car
void obj = 0; // obj has no type
void* = new Car(); // obj is a pointer with no type

আমি বিশ্বাস করি যে এখানে বিভ্রান্তি আপনি voidবনাম কীভাবে সংজ্ঞায়িত করবেন তা ভিত্তি করে তৈরি void*। রিটার্ন-টাইপের voidঅর্থ "আমি কিছুই ফিরিয়ে দিই না", আবার রিটার্নের ধরণের void*অর্থ "আমি কিছুই না বলে একটি পয়েন্টার ফিরিয়ে দিই"।

এটি একটি পয়েন্টার একটি বিশেষ ক্ষেত্রে এটি এই কারণে হয়। একটি পয়েন্টার অবজেক্ট সর্বদা স্মৃতিতে কোনও অবস্থানকে নির্দেশ করবে, সেখানে কোনও বৈধ অবজেক্ট রয়েছে কিনা whether আমার void* carরেফারেন্সগুলি বাইট, শব্দ, একটি গাড়ি বা সাইকেলের কোনও বিষয় নয় কারণ কোনও নির্দিষ্ট সংজ্ঞা ছাড়াই এমন কোনও জিনিসের প্রতি আমার void*পয়েন্ট । এটি পরে সংজ্ঞায়িত করা আমাদের ব্যাপার।

সি # এবং জাভা এর মতো ভাষাগুলিতে মেমরি পরিচালনা করা হয় এবং পয়েন্টারগুলির ধারণাটি বস্তু শ্রেণিতে পরিণত হয়। "কিছুই না" টাইপের কোনও বস্তুর রেফারেন্সের পরিবর্তে আমরা জানি যে খুব কমপক্ষে আমাদের অবজেক্টটি "অবজেক্ট" টাইপের হয়। কেন আমাকে ব্যাখ্যা করুন।

প্রচলিত সি / সি ++ এ আপনি যদি কোনও বস্তু তৈরি করেন এবং এর পয়েন্টারটি মুছেন, তবে সেই বস্তুর অ্যাক্সেস পাওয়া অসম্ভব। এটি মেমরি ফুটো হিসাবে পরিচিত ।

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

আমাদের প্রোগ্রামারদের জন্য, এর অর্থ হ'ল সি / সি ++ তে ম্যানুয়ালি আমাদের যে সমস্ত তথ্যের যত্ন নিতে হবে সেগুলির বেশিরভাগ বিষয় অবজেক্ট ক্লাস দ্বারা আমাদের জন্য যত্ন নেওয়া হয়, যা নির্দিষ্ট পয়েন্টারের বিশেষ ক্ষেত্রে প্রয়োজনীয়তা সরিয়ে দেয়।


"আমার অকার্যকর * কোনও সংজ্ঞায়িত প্রকারবিহীন কিছুকে নির্দেশ করে" - ঠিক না। এটি শূন্য-দৈর্ঘ্যের মানের (প্রায় 0 টি উপাদানযুক্ত অ্যারের মতো, তবে অ্যারের সাথে সম্পর্কিত কোনও ধরণের তথ্য ছাড়াই) পয়েন্টার বলা আরও সঠিক।
স্কট হুইটলক

2

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

ধরণের voidমধ্যে প্রথম শ্রেণির নাগরিক নয়। যদিও এটি কোনও অবজেক্টের ধরণ, এটি কোনও বস্তুর (বা মান) ক্ষেত্রের বা কোনও ফাংশন প্যারামিটারের ধরণের হতে পারে না; তবে এটি কোনও ফাংশনের রিটার্নের ধরণ হতে পারে, এবং এর মাধ্যমে কোনও অভিব্যক্তির প্রকার থাকতে পারে (মূলত এই জাতীয় ফাংশনগুলির কলগুলির জন্য, তবে শর্তসাপেক্ষ অপারেটরের সাথে গঠিত অভিব্যক্তিগুলিতেও অকার্যকর টাইপ থাকতে পারে)। কিন্তু এমনকি ন্যূনতম ব্যবহার voidএকটি মান টাইপ হিসাবে যে উপরোক্ত পাতার দরজা জন্য, যথা ফিরে একটি ফাংশন বিভক্তি খোলা voidফর্ম একটি বিবৃতি দিয়ে return E;যেখানে Eপ্রকারের একটি অভিব্যক্তি voidস্পষ্টভাবে (এটা ++, যদিও সি অনুমতি দেওয়া হয় সি নিষিদ্ধ করা হয়, তবে সি এর জন্য প্রযোজ্য নয়)

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

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


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

0

সি # এবং জাভাতে প্রতিটি ক্লাস একটি Objectক্লাস থেকে উদ্ভূত । সুতরাং যখনই আমরা "কিছু" এর সাথে একটি রেফারেন্স পাস করতে চাই, আমরা প্রকারের একটি রেফারেন্স ব্যবহার করতে পারি Object

যেহেতু এই ভাষাগুলিতে আমাদের সেই উদ্দেশ্যে অকার্যকর পয়েন্টার ব্যবহার করার দরকার voidনেই , তাই এখানে "কিছু বা কিছুই নয়" বোঝাতে হবে না।


0

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

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

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

void*আমি সুনির্দিষ্ট এবং সি ++ এর মতো প্রত্যক্ষ ডেরাইভেটিভগুলি সম্পর্কে স্বতঃস্ফূর্তভাবে স্বেচ্ছাচারী ধরণের কোনও কিছুর পয়েন্টারের জন্য নামকরণ হিসাবে ব্যবহার করি; অন্য ভাষাগুলি আমি স্বতন্ত্র-নামযুক্ত প্রকারটি ব্যবহার করে ধারণাটি হ্যান্ডেল করতে জানি।


-1

আপনি কীওয়ার্ডটি খালি শিরোনামেরvoid মতো ভাবতে পারেন struct( সি 99 খালি স্ট্রাক্টগুলিতে স্পষ্টতই অনুমতি দেওয়া হয়নি , নেট এবং সি ++ এ তারা 0 টিরও বেশি মেমরি নিয়েছে এবং শেষ পর্যন্ত আমি জাভার সমস্ত কিছুই একটি শ্রেণি মনে করি):

struct void {
};

... যার অর্থ এটি 0 দৈর্ঘ্যের একটি প্রকার। আপনি যখন কোনও ফাংশন কল করেন তখন এটি কাজ করে যা প্রত্যাবর্তন করে void... পূর্ণসংখ্যা ফেরতের জন্য স্ট্যাকের 4 বাইট বা আরও বরাদ্দ না করে, এটি স্ট্যাক পয়েন্টারটি মোটেও পরিবর্তন করে না (এটি 0 দৈর্ঘ্যের দ্বারা বৃদ্ধি করে) )।

সুতরাং, যদি আপনি কিছু ভেরিয়েবলের ঘোষণা করেন:

int a;
void b;
int c;

... এবং তারপরে আপনি সেই ভেরিয়েবলগুলির ঠিকানা নিয়েছিলেন, সম্ভবত bএবং সম্ভবত cএকই স্থানে স্মৃতিতে অবস্থিত হতে পারে, কারণ bদৈর্ঘ্যের শূন্য রয়েছে। সুতরাং একটি void*শূন্য দৈর্ঘ্য সহ অন্তর্নির্মিত টাইপ মেমরি একটি পয়েন্টার। আপনি সম্ভবত এটি জেনে থাকতে পারেন যে এটির পরেই এমন কিছু আছে যা আপনার পক্ষে উপকারী হতে পারে এটি অন্য একটি বিষয় এবং আপনি কী করছেন তা সত্যই জেনে রাখা দরকার (এবং বিপজ্জনক)।


আমি যে একমাত্র সংকলকটি সম্পর্কে জানি তা হ'ল শূন্য টাইপ করার জন্য একটি দৈর্ঘ্য নির্ধারণ করে জিসিসি, এবং জিসিসি এটি দৈর্ঘ্য 1 নির্ধারণ করে
জোশুয়া
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.