আপনি কি সি ++ এর পয়েন্টারগুলির জন্য NULL বা 0 (শূন্য) ব্যবহার করেন?


193

সি ++ এর প্রথম দিনগুলিতে যখন এটি সি এর শীর্ষে বোল্ট করা হত, আপনি NULL ব্যবহার করতে পারেন নি হিসাবে এটি সংজ্ঞায়িত হয়েছিল (void*)0। আপনি ব্যতীত অন্য কোনও পয়েন্টারে NULL বরাদ্দ করতে পারেন নি void*, যা এটিকে অকেজো করে তোলে। সেই দিনগুলিতে, এটি গৃহীত হয়েছিল যে আপনি 0নাল পয়েন্টারগুলির জন্য (শূন্য) ব্যবহার করেছেন।

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

if (p && !q)
  do_something();

তারপরে শূন্য ব্যবহার করা আরও অর্থবোধ করে (আপনি যদি ব্যবহার করেন তবে আপনি NULLযৌক্তিকভাবে ব্যবহার করতে পারবেন না p && !q- NULLযদি আপনি NULLশূন্য না ধরে থাকেন তবে আপনার ব্যবহারের ক্ষেত্রে স্পষ্টভাবে তুলনা করা দরকার NULL)।

NULL (বা তদ্বিপরীত) এর চেয়ে শূন্যকে প্রাধান্য দেওয়ার কোনও উদ্দেশ্যগত কারণ আছে, বা সমস্ত কি কেবল ব্যক্তিগত পছন্দ?

সম্পাদনা: আমার যুক্ত করা উচিত (এবং মূলত বলতে চাইছিলাম) যে RAII এবং ব্যতিক্রমগুলির সাথে আমি খুব কমই শূন্য / NULL পয়েন্টার ব্যবহার করি তবে কখনও কখনও আপনার এগুলি এখনও প্রয়োজন need


9
অপেক্ষা করুন, নাল অভ্যন্তরীণভাবে শূন্য হয় বা না হলে মিথ্যা হিসাবে মূল্যায়ন করার জন্য কোনও নাল পয়েন্টারের দরকার নেই?
মাকিং হাঁস

উত্তর:


185

স্ট্রাস্ট্রাপের এটি এখানে রয়েছে: সি ++ স্টাইল এবং টেকনিকের এফএকিউ

সি ++ এর সংজ্ঞা NULL0, সুতরাং কেবল একটি নান্দনিক পার্থক্য রয়েছে। আমি ম্যাক্রোগগুলি এড়াতে পছন্দ করি, তাই আমি 0 ব্যবহার করি with এর সাথে আরেকটি সমস্যা NULLহ'ল লোকে কখনও কখনও ভুলভাবে বিশ্বাস করে যে এটি 0 এবং / অথবা কোনও পূর্ণসংখ্যা নয় different প্রাক-মানক কোডে, NULLকখনও কখনও অনুপযুক্ত কিছুতে সংজ্ঞায়িত করা হয় এবং তাই / এড়ানো হয়েছিল। এই দিনগুলিতে এটি কম সাধারণ।

যদি আপনাকে নাল পয়েন্টারটির নাম দিতে হয়, কল করুন nullptr; এটি সি ++ 11 এ বলা হয়। তারপরে, nullptrএকটি কীওয়ার্ড হবে।

এটি বলেছিল, ছোট জিনিস ঘামবেন না।


7
C ++ 0x একটি নতুন নাল ধরণের কাজ শুরু করার আগে বর্জন এটি লিখেছিলেন। এটি প্ল্যাটফর্মের জন্য উপলভ্য হলে NUL এই ধরণের জন্য ব্যবহার করা হবে এবং আমি মনে করি আপনি এটি সম্পর্কে সাধারণ sensকমত্যে একটি সি-পরিবর্তন দেখতে পাবেন।
রিচার্ড কর্ডেন

122

কয়েকটি যুক্তি রয়েছে (যার মধ্যে একটি তুলনামূলকভাবে সাম্প্রতিক) যা আমি বিশ্বাস করি যে এটি সম্পর্কে বার্জারের অবস্থানের বিরোধী।

  1. অভিপ্রায় ডকুমেন্টেশন

ব্যবহার NULLএটা ব্যবহারের উপর অনুসন্ধানে এবং এটি হাইলাইট যা বিকাশকারীর জন্য করতে পারবেন চেয়েছিলেন ব্যবহার করতে NULLকিনা এটা যেমন কম্পাইলার ব্যাখ্যা করা হচ্ছে নির্বিশেষে পয়েন্টার NULLবা না।

  1. পয়েন্টার ও 'ইনট' এর ওভারলোড অপেক্ষাকৃত বিরল

প্রত্যেকে যে উদাহরণটি উদ্ধৃত করে তা হ'ল:

void foo(int*);
void foo (int);

void bar() {
  foo (NULL);  // Calls 'foo(int)'
}

তবে কমপক্ষে আমার মতে উপরের সমস্যাটি হ'ল আমরা নাল পয়েন্টার ধ্রুবকটির জন্য NULL ব্যবহার করছি না, আমাদের 'foo' ওভারলোড রয়েছে যা বিভিন্ন ধরণের যুক্তি গ্রহণ করে। প্যারামিটারটি অবশ্যই একটি হতে intহবে, যেহেতু অন্য কোনও প্রকারের ফলে একটি দ্ব্যর্থহীন কল আসে এবং তাই একটি সহায়ক সংকলক সতর্কতা জেনারেট করে।

  1. বিশ্লেষণ সরঞ্জাম আজকে সাহায্য করতে পারে!

এমনকি সি ++ 0x এর অভাবে আজও এমন সরঞ্জামগুলি পাওয়া যায় যা যাচাই করে যে NULLএটি পয়েন্টারগুলির জন্য ব্যবহৃত হচ্ছে এবং এটি 0অবিচ্ছেদ্য ধরণের জন্য ব্যবহৃত হচ্ছে।

  1. সি ++ 11 এ একটি নতুন std::nullptr_tধরণ থাকবে।

এটি টেবিলে নবীন যুক্তি। সমস্যা 0এবং NULLসক্রিয়ভাবে হচ্ছে সি ++ 0x জন্য সুরাহা, এবং আপনি নিশ্চিত করতে পারে না যে বাস্তবায়ন উপলব্ধ যে জন্য যে NULL, খুব প্রথম জিনিস যে তারা কি করতে হবে হল:

#define NULL  nullptr

এর NULLপরিবর্তে যারা ব্যবহার করেন তাদের পক্ষে 0পরিবর্তনটি টাইপ-সেফটিতে খুব কম বা কোনও প্রচেষ্টা ছাড়াই উন্নতি হবে - যদি কিছু হয় তবে এটি যেখানে কিছু ব্যাগ ব্যবহার NULLকরেছে সেগুলিও পেতে পারে 00আজকের যে কারও জন্য .... এরম ... ভাল আশা করি তারা নিয়মিত প্রকাশের ভাল জ্ঞান রাখবেন ...


1
সেগুলি কিছু বরং ভাল পয়েন্ট, আমি স্বীকার করতে হবে। আমি আনন্দিত যে সি ++ 0x এর নাল টাইপ হবে, আমি মনে করি এটি প্রচুর স্টাফ ক্লিনার করে দেবে।
রব

2
@ রিচার্ড, বিপরীত কেন করবেন না? আপনি মায়ার্স নালপ্ট্র_টি ব্যবহার করতে পারেন তারপরে 0x যখন উপলব্ধ হয় তখন আপনি সরিয়ে ফেলেন #includeএবং নিরাপদ দিকে রাখুন all
fnieto - ফার্নান্দো নিয়েটো

15
#define NULL nullptrবিপজ্জনক বলে মনে হচ্ছে ভাল বা খারাপের জন্য, প্রচুর লিগ্যাসি কোড 0 ছাড়া অন্য জিনিসগুলির জন্য নুল ব্যবহার করে For উদাহরণস্বরূপ, হ্যান্ডলগুলি প্রায়শই কিছু অবিচ্ছেদ্য প্রকার হিসাবে প্রয়োগ করা হয় এবং সেগুলি সেট করা NULLঅস্বাভাবিক নয়। এমনকি শূন্য-টার্মিনেটরে NULLসেট করতে ব্যবহার করার মতো গালিও দেখেছি char
অ্যাড্রিয়ান ম্যাকার্থি

8
@ অ্যাড্রিয়ানম্যাকার্থি: আমি কেবল তখনই বলব যদি কোডটি নিঃশব্দে সংকলন করার এবং অন্যরকম অর্থ ধারণ করার ঝুঁকি থাকে। আমি নিশ্চিত যে এটি তেমন নয়, তাই আসলে NUL এর সমস্ত ভুল ব্যবহার শনাক্ত করা হবে be
রিচার্ড কর্ডেন

3
@ রিচার্ডকার্ডেন: উম, ধরে নিল যে অন্যান্য ব্যবহারগুলি NULLআসলে ভুল। অনেকগুলি এপিআই NULLহ্যান্ডলগুলির সাথে দীর্ঘকাল ধরে ব্যবহৃত হয়েছে এবং এটি আসলে তাদের অনেকের সাথেই ডকুমেন্টেড ব্যবহার। হঠাৎ এগুলি ভেঙে ঘোষণা করা এবং তারা এটি ভুল করে চলেছে তা ঘোষণা করা যুক্তিযুক্ত নয়।
অ্যাড্রিয়ান ম্যাকার্থি

45

নুল ব্যবহার করুন। NULL আপনার অভিপ্রায় দেখায়। এটি 0 হ'ল একটি বাস্তবায়ন বিশদ যা বিবেচ্য নয়।


28
0 বাস্তবায়নের বিশদ নয়। মানটি 0 কে বিট প্যাটার্নটি নাল পয়েন্টার উপস্থাপন করে যা হতে সংজ্ঞায়িত করে।
ফেরুক্সিও

5
যেন ..!! বাবু, সি ++ একটি নিম্ন স্তরের ভাষা! 0 ব্যবহার করুন, এটি একটি সুপরিচিত পরিচয়।
হ্যাসেন

8
আমি বুঝতে পারি যে এটি স্ট্যান্ডার্ডের একটি অংশ। কোড পড়া যতদূর যায় এটি প্রয়োগের বিশদ। পাঠকের মনে করা উচিত "NULL pointer" not "0" যার ক্ষেত্রে এই ক্ষেত্রে NULL পয়েন্টার, একটি সংখ্যা নয় যা আমি পাটিগণিতের সাথে করতে পারি। "
অ্যান্ডি লেস্টার

2
+1 টি। অ্যান্ডির সাথে একমত @ ফারুচ্চিও, প্রোগ্রামার এর ধারণার বাস্তবায়ন বিবরণ সংকলক বাস্তবায়ন সংজ্ঞায়িত
ব্যবহারকারী

আপনি যদি জটিল শিরোনাম ছাড়াই একটি সরল কোডে NULL ব্যবহার করেন, তবে আপনি "NULL এই সুযোগে সংজ্ঞায়িত করা হয়নি" এর ত্রুটিটি দেখতে পাবেন ..
কৃত্রিমভাবেই

37

আমি সবসময় ব্যবহার:

  • NULL পয়েন্টার জন্য
  • '\0' চর জন্য
  • 0.0 ভাসা এবং দ্বৈত জন্য

যেখানে 0 জরিমানা করবে। ইঙ্গিতটি ইঙ্গিতের বিষয়টি। বলেছিল, আমি এ সম্পর্কে বেদনাপ্রাপ্ত নই।


24
ইম্পিলিটি টাইপকাস্ট এড়ানোর জন্য সম্ভবত ভাসমানদের জন্য 0.0 এফ ব্যবহার করা উচিত
এভিলটিচ

35

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

নতুন প্রকল্পগুলিতে, আমি এটি একটি প্রকল্পের শিরোনামে রেখেছি:

static const int nullptr = 0;

এখন, যখন C ++ 0x অনুবর্তী কম্পাইলারগুলি উপস্থিত হয়, তখন আমাকে কেবল লাইনটি সরিয়ে ফেলতে হবে। এর একটি দুর্দান্ত সুবিধা হ'ল ভিজ্যুয়াল স্টুডিও ইতিমধ্যে নালপ্টারকে একটি কীওয়ার্ড হিসাবে স্বীকৃতি দিয়েছে এবং এটিকে যথাযথভাবে হাইলাইট করে।


4
NULL ব্যবহার করা আরও বহনযোগ্য দীর্ঘমেয়াদী হবে। 'নাল্পটার' অন্য প্ল্যাটফর্মগুলির জন্য উপলব্ধ হবে এবং অন্যদের জন্য নয়। আপনার সমাধানটি এখানে প্রয়োজনীয় প্রয়োজন যে আপনি কেবলমাত্র প্রয়োজনের সময় উপস্থিত রয়েছে তা নিশ্চিত করার জন্য আপনার ঘোষণার চারপাশে প্রিপ্রসেসর ব্যবহার করুন use NULL এটি স্বয়ংক্রিয়ভাবে করবে।
রিচার্ড কর্ডেন

6
আমি একমত নই সংকলকরা না ধরা পর্যন্ত এটি স্বল্পমেয়াদে কম পোর্টেবল হবে। দীর্ঘমেয়াদী, এটি ঠিক পোর্টেবল এবং সম্ভবত আরও কিছুটা পাঠযোগ্য হবে।
ফেরুরসিও

4
এছাড়াও আপনি সবসময় আপনার নন-সি ++ 0 এক্স সংকলকটির জন্য নাল্প্টার নুলকে নির্ধারণ করতে পারেন।
আন্টেরু

20
    cerr << sizeof(0) << endl;
    cerr << sizeof(NULL) << endl;
    cerr << sizeof(void*) << endl;

    ============
    On a 64-bit gcc RHEL platform you get:
    4
    8
    8
    ================

গল্পটির সারাংশ হলো. আপনি যখন পয়েন্টারগুলি নিয়ে কাজ করছেন তখন আপনার নাল ব্যবহার করা উচিত।

1) এটি আপনার অভিপ্রায় ঘোষনা করে (কোনও ভেরিয়েবল পয়েন্টার বা কোনও সংখ্যার প্রকারের কিনা তা খুঁজে বের করার চেষ্টা করে আপনার সমস্ত কোড সন্ধানের চেষ্টা করবেন না)।

2) নির্দিষ্ট এপিআই কলগুলিতে ভেরিয়েবল আর্গুমেন্টের প্রত্যাশা করে, তারা আর্গুমেন্ট তালিকার সমাপ্তি নির্দেশ করতে একটি নল-পয়েন্টার ব্যবহার করবে। এই ক্ষেত্রে, NUL এর পরিবর্তে '0' ব্যবহার করা সমস্যার কারণ হতে পারে। একটি -৪-বিট প্ল্যাটফর্মে, ভিএআরগ কল একটি -৪-বিট পয়েন্টার চায়, তবুও আপনি কেবল একটি 32-বিট পূর্ণসংখ্যা পেরিয়ে যাবেন। আমার কাছে মনে হচ্ছে আপনি অন্য 32-বিটের উপর নির্ভর করছেন যা আপনার জন্য শূন্য হতে হবে? আমি কিছু সংকলক দেখেছি (যেমন ইন্টেলের আইসিপিসি) যা এতটা করুণাময় নয় - এবং এর ফলে রানটাইম ত্রুটি দেখা দিয়েছে।


NULLসম্ভবত বহনযোগ্য নয় এবং নিরাপদ নয়। এমন প্ল্যাটফর্মগুলি থাকতে পারে যা এখনও #define NULL 0( স্ট্রস্ট্রুপের এফএকিউ অনুসারে : শীর্ষ প্রশ্নের দ্বারা উদ্ধৃত হওয়া আমি কি নল বা 0 ব্যবহার করব ) এবং এটি প্রথম অনুসন্ধানের ফলাফলগুলির মধ্যে একটি)। কমপক্ষে পুরানো সি ++ 0এ পয়েন্টার প্রসঙ্গে একটি বিশেষ ধারণাগত অর্থ রয়েছে। আপনি বিট সম্পর্কে দৃ concrete়ভাবে চিন্তা করা উচিত নয়। এছাড়াও মনে রাখবেন বিভিন্ন পূর্ণসংখ্যা প্রেক্ষিতে ( short, int, long long) " sizeof(0)" আলাদা হতে হবে। আমি মনে করি এই উত্তরটি কিছুটা বিভ্রান্ত।
এফওএফ

(ব্যক্তিগতভাবে দৈনন্দিন জীবনের একটি সি প্রোগ্রামার হিসেবে আমি এই প্রশ্নের দেখার জন্য বুঝতে কেন মানুষ ব্যবহার করতে চান এসে NULLপরিবর্তে (char *)0, (const char *)0বা (struct Boo *)0বা (void *)0বা অভিপ্রায় আরও স্পষ্টভাবে প্রকাশ যাই হোক না কেন -। হচ্ছে (আমার মতে) অতি কষ্টকর ছাড়া)
FooF

ভোট দিন। এটি এমএসভিসি ২০১৩ সি সংকলনে ঘটছে। bit৪ বিট, 0 এ যখন পয়েন্টারে রূপান্তর করা হয় তখন নুল পয়েন্টার হওয়ার গ্যারান্টি নেই।
পেঙ্গমিয়াও

16

আমি যদি সঠিকভাবে স্মরণ করি তবে আমি যে শিরোনামটি ব্যবহার করেছি সেগুলিতে NULL আলাদাভাবে সংজ্ঞায়িত করা হয়। সি এর জন্য এটি (অকার্যকর *) 0 হিসাবে সংজ্ঞায়িত করা হয়েছে, এবং সি ++ এর জন্য এটি কেবল 0 হিসাবে সংজ্ঞায়িত করা হয়েছে কোডটি এমন কিছু দেখায়:

#ifndef __cplusplus
#define NULL (void*)0
#else
#define NULL 0
#endif

ব্যক্তিগতভাবে আমি এখনও নাল পয়েন্টার উপস্থাপনের জন্য নুল মানটি ব্যবহার করি, এটি স্পষ্ট করে দেয় যে আপনি কিছু অবিচ্ছেদ্য টাইপের পরিবর্তে পয়েন্টার ব্যবহার করছেন। হ্যাঁ অভ্যন্তরীণভাবে NULL মানটি এখনও 0 তবে এটি এরূপ হিসাবে প্রতিনিধিত্ব করে না।

অতিরিক্তভাবে আমি বুলিয়ান মানগুলিতে পূর্ণসংখ্যার স্বয়ংক্রিয় রূপান্তরের উপর নির্ভর করি না তবে তাদের সুস্পষ্টভাবে তুলনা করি।

উদাহরণস্বরূপ ব্যবহার করতে পছন্দ করুন:

if (pointer_value != NULL || integer_value == 0)

বরং:

if (pointer_value || !integer_value)

বলার অপেক্ষা রাখে না যে এটি সমস্ত সি ++ 11 এ চিকিত্সা করা হয়েছে যেখানে এর nullptrপরিবর্তে কেউ কেবল ব্যবহার করতে পারে NULLএবং এটিও nullptr_tএ এর ধরণ nullptr


15

আমি বলব যে ইতিহাস কথা বলেছে এবং যারা 0 (শূন্য) ব্যবহারের পক্ষে যুক্তি দিয়েছিল তারা ভুল ছিল (বজর্ন স্ট্রাস্ট্রাপ সহ)। 0 এর পক্ষে যুক্তিগুলি বেশিরভাগ নান্দনিকতা এবং "ব্যক্তিগত পছন্দ" ছিল।

সি ++ 11 তৈরির পরে, তার নতুন নলপ্টর টাইপের সাহায্যে কিছু সংকলক পয়েন্টার যুক্তি দিয়ে 0 ফাংশনে পাস করার বিষয়ে অভিযোগ (ডিফল্ট পরামিতি সহ) শুরু করেছেন, কারণ 0 পয়েন্টার নয়।

কোডটি যদি NULL ব্যবহার করে রচনা করা হত, তবে একটি সহজ অনুসন্ধান এবং প্রতিস্থাপন কোডবেজটির পরিবর্তে এটিকে নাল্পটার হিসাবে তৈরি করা যেতে পারে। আপনি যদি পয়েন্টার হিসাবে 0 টি পছন্দ ব্যবহার করে লিখিত কোডটি আটকে থাকেন তবে এটি আপডেট করা আরও বেশি ক্লান্তিকর।

এবং যদি আপনাকে এখনই সি ++ 03 স্ট্যান্ডার্ডে নতুন কোড লিখতে হবে (এবং নাল্প্ট্রার ব্যবহার করতে পারবেন না), আপনার সত্যিই কেবল নুল ব্যবহার করা উচিত। এটি আপনার পক্ষে ভবিষ্যতে আপডেট করা আরও সহজ করে তুলবে।


11

আমি সাধারণত 0 ব্যবহার করি I আমি ম্যাক্রোগুলি পছন্দ করি না এবং এর কোনও গ্যারান্টি নেই যে আপনি ব্যবহার করছেন এমন কোনও তৃতীয় পক্ষের শিরোনাম নুলকে কিছুকে বিজোড় হিসাবে পুনরায় সংজ্ঞা দেয় না।

স্কট মেয়ার্স এবং অন্যদের প্রস্তাবিত আপনি নাল্প্টার অবজেক্টটি ব্যবহার করতে পারবেন যতক্ষণ না সি ++ নালপ্টার কীওয়ার্ড না পান:

const // It is a const object...
class nullptr_t 
{
public:
    template<class T>
    operator T*() const // convertible to any type of null non-member pointer...
    { return 0; }

    template<class C, class T>
    operator T C::*() const   // or any type of null member pointer...
    { return 0; }

private:
    void operator&() const;  // Can't take address of nullptr

} nullptr = {};

আরও তথ্যের জন্য গুগল "নালপ্ট্র"।


9
কোনও তৃতীয় পক্ষের লাইব্রেরি যা 0 টি ব্যতীত অন্য কোনও কিছুতে NULL সংজ্ঞায়িত করে (বা (void*)0যদি সি কোড হিসাবে সংকলিত হচ্ছে) কেবল সমস্যার জন্য জিজ্ঞাসা করছে এবং ব্যবহার করা উচিত নয়।
অ্যাডাম রোজেনফিল্ড

2
আপনি কি কখনও এমন একটি লাইব্রেরি দেখেছেন যা নালকে নতুন করে সংজ্ঞায়িত করে? কখনো? যদি এমন লাইব্রেরি যদি কখনও থাকে তবে আপনার পুনরায় সংজ্ঞায়িত NUL এর চেয়ে বড় সমস্যা হতে পারে যেমন আপনি NUL পুনর্নির্ধারণের জন্য পর্যাপ্ত মূumb় একটি লাইব্রেরি ব্যবহার করছেন।
অ্যান্ডি লেস্টার

1
এক দশকেরও বেশি সময় আগে আমি অস্পষ্টভাবে কিছু তৃতীয় পক্ষের শিরোনামের সাথে ডিল করার কথা মনে রেখেছি, সম্ভবত অর্বিক্স বা অবজেক্টস্টোর, যা ন্যূনালকে সংজ্ঞায়িত করেছিল। আমি মনে করি বেশ কয়েকটি দিন এবং রাত নষ্ট করার পরে আমার ম্যাক্রোগুলির একটি প্যাথলজিকাল বিদ্বেষ রয়েছে windows
জন-হ্যানসন

2
"ম্যাক্রোগুলিকে পছন্দ করবেন না" হ'ল # ডেফাইনের মতো অবজেক্টের একটি বিজোড় সমালোচনা। হয়তো আপনি বলতে চাইছেন যে আপনি সি-প্রিপ্রসেসর পছন্দ করেন না?
অ্যান্ড্রু প্রক

@Andrew - একমাত্র সুবিধা NULLধরে (type *)0অনুসন্ধান যোগ্যতা, এটা আমার মনে হচ্ছে। অন্যথায় এটি সি আইডিয়াম না থাকলে এটি অপ্রয়োজনীয় অবহেলা মনে হয়। আমি ব্যক্তিগতভাবে মনে করি পুরো NULLজায়গা জুড়ে ছড়িয়ে ছড়িয়ে ছিটিয়ে থাকা মরার যোগ্য die NULLআমার মতে বেহুদা ম্যাক্রো। ওকামের
রেজারটি

11

আমি একবার এমন মেশিনে কাজ করেছি যেখানে 0 একটি বৈধ ঠিকানা ছিল এবং NUL কে একটি বিশেষ অক্টাল মান হিসাবে সংজ্ঞায়িত করা হয়েছিল। সেই মেশিনে (0! = NULL), সুতরাং কোড যেমন

char *p;

...

if (p) { ... }

আপনি আশা হিসাবে কাজ করবে না। আপনার লিখতে হবে

if (p != NULL) { ... }

যদিও আমি বিশ্বাস করি যে বেশিরভাগ সংকলকগণ আজকাল NUL কে সংজ্ঞায়িত করেছেন আমি এখনও এই বছরগুলি আগের পাঠটি মনে করি: NUL অগত্যা 0 নয়।


26
আপনি কোনও কমপ্লায়েন্ট সংকলক ব্যবহার করছেন না। মান বলছেন শূন্য হয় 0 এবং কম্পাইলার খিলান জন্য একটি সঠিক সত্য শূন্য মান মধ্যে একটি পয়েন্টার প্রেক্ষাপটে 0 রূপান্তর উচিত।
ইভান তেরান

17
হ্যাঁ তুমিই ঠিক. এটিএনএসআই একটি সি স্ট্যান্ডার্ড তৈরি করার আগে এটি 80-এর দশকের মাঝামাঝি ছিল। তত্কালীন মেনে চলার মতো কোনও জিনিস ছিল না এবং সংকলক লেখকরা যেমন উপযুক্ত দেখেন তেমন ভাষার ব্যাখ্যা দিতে পারতেন। এজন্য একটি স্ট্যান্ডার্ড প্রয়োজনীয় ছিল।
এমএক্সজি

9

আমি মনে করি যে মানটি গ্যারান্টি দেয় যে NULL == 0, যাতে আপনি এটি করতে পারেন। আমি নুলকে পছন্দ করি কারণ এটি আপনার উদ্দেশ্যকে দলিল করে।


যদি আপনার কাঠামোগত নেস্ট থাকে তবে আমি মনে করি foo.bar_ptr = (Bar *) 0এই অভিপ্রায়টি আরও পরিষ্কারভাবে প্রকাশ করে foo.bar_ptr = NULL। এই অভ্যাসটি আপনার জন্য ভুল ধারণাটি ত্রুটিগুলি ধরার জন্য সংকলককে ক্ষমতাও দেয়। আমার জন্য, foo.bar_ptr = 0অভিপ্রায়টি প্রকাশের পাশাপাশি ব্যবহারের পাশাপাশি NULLযদি আমি জানি যে foo.bar_ptrএটি একটি পয়েন্টার।
এফওএফ

9

0 বা NULL হয় ব্যবহার করলে একই প্রভাব থাকবে।

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

NULL, 0, 0.0, '\ 0', 0x00 এবং whetlse সব একই জিনিস অনুবাদ, কিন্তু আপনার প্রোগ্রামে বিভিন্ন লজিকাল সত্তা। সেগুলি যেমন ব্যবহার করা উচিত। NULL একটি পয়েন্টার, 0 পরিমাণ, 0x0 এমন একটি মান যার বিটগুলি আকর্ষণীয় etc. ইত্যাদি আপনি কোনও পয়েন্টারকে '\ 0' বরাদ্দ করবেন না এটি সংকলন করে কিনা।

আমি জানি কিছু সম্প্রদায় পরিবেশের চুক্তিগুলি ভঙ্গ করে কোনও পরিবেশের গভীর জ্ঞান প্রদর্শনের জন্য উত্সাহিত করে। দায়িত্বশীল প্রোগ্রামাররা তবে রক্ষণাবেক্ষণযোগ্য কোড তৈরি করে এবং এ জাতীয় অনুশীলনগুলিকে তাদের কোডের বাইরে রাখে।


5

আশ্চর্যের বিষয়, স্ট্রস্ট্রুপ সহ কেউই তা উল্লেখ করেনি। যদিও সম্পর্কে মান এবং নন্দনতত্ব কেউ কিছু অনেক কথা বলা লক্ষ্য করেছি যে, এটা বিপজ্জনক ব্যবহার করতে 0মধ্যে NULLস্থাপত্য যেখানে উপর, এর উপকার পরিবর্তনশীল যুক্তি তালিকায় উদাহরণস্বরূপ sizeof(int) != sizeof(void*)। স্ট্রাস্ট্রুপের মতো, আমি 0নান্দনিক কারণে পছন্দ করি , তবে এটির ধরণটি যেখানে অস্পষ্ট হতে পারে সেখানে এটি ব্যবহার না করা সম্পর্কে আমাদের সতর্ক থাকতে হবে।


আর বিপজ্জনক স্থানে আপনি এখনও ব্যবহার করতে পারেন 0আপনার নির্দিষ্ট করা যা প্রদান করা 0আপনি কি বলতে চান - উদাহরণস্বরূপ (int *)0, (char *)0, (const char *)0বা (void *)0বা (unsigned long long) 0বা যাই হোক না কেন। এটা আমার মতামত চেয়ে অভিপ্রায় অনেক পরিষ্কার প্রকাশ NULL
FooF

1
অবশ্যই, আপনি যদি না জানেন তবে কী NULLবোঝায়।
মাইকেল ক্রেলিন - হ্যাকার

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

ওয়েল, এজন্যই কাস্টিং এ (void*)বিমূর্ত হয়েছে NULL। এবং NULLআসলে বেশিরভাগ সময় বেশ স্পষ্টভাবে অভিপ্রায়টি প্রকাশ করে। এবং আমি মনে করি আপনার প্রত্যাহারটি ভুল। মান সম্পর্কে নিশ্চিত নয়, তবে বাস্তবে আমি বিশ্বাস করি এটি হয়েছে (void*)0। এবং হ্যাঁ, nullptrএটি একটি দুর্দান্ত প্রিটিটিফায়ার, যদিও এটি একই NULLজিনিসটির সমান - নির্দিষ্ট ধরণের নির্দিষ্টকরণ ছাড়াই নাল-পয়েন্টার নির্দিষ্ট করে।
মাইকেল ক্রেলিন - হ্যাকার

1
@FFF, কিছু প্ল্যাটফর্মে - সম্ভবত। আমার বাস্তবে এটি কাজ করেছিল এবং তাই আমি সন্দেহ করি এটি একটি পয়েন্টার হিসাবে সংজ্ঞায়িত করা হয়েছে। দৃust়তার জন্য, হ্যাঁ, আমি যা বলার চেষ্টা করছিলাম যে এটি ব্যবহার nullptrকরে একই বার্তাটি পাওয়া যায় NULL, এটি কেবল আপনি প্রথমে উল্লিখিত অভিপ্রায়টি প্রকাশ করার বিষয়ে। ( NULLআধুনিক gccফলনের উপর প্রাক প্রসেসিং __null, তা যাই হোক না কেন)।
মাইকেল ক্রেলিন - হ্যাকার

4

আমি যেখানে সম্ভব সেখানে সি ++ রেফারেন্স ব্যবহার করে পুরো প্রশ্নটি এড়াতে চেষ্টা করি। বরং

void foo(const Bar* pBar) { ... }

আপনি প্রায়শই লিখতে সক্ষম হতে পারেন

void foo(const Bar& bar) { ... }

অবশ্যই, এটি সবসময় কাজ করে না; তবে নাল পয়েন্টারগুলি অতিরিক্ত ব্যবহৃত হতে পারে।


3

আমি এই একটিতে স্ট্রাস্ট্রাপের সাথে আছি :-) যেহেতু NULL ভাষার অংশ নয়, তাই আমি 0 ব্যবহার করতে পছন্দ করি।


3

বেশিরভাগ ব্যক্তিগত পছন্দ, যদিও কেউ এই যুক্তিটি তৈরি করতে পারে যে নুল এটি একেবারে সুস্পষ্ট করে তোলে যে বস্তুটি এমন একটি পয়েন্টার যা বর্তমানে কোনও কিছুর প্রতি নির্দেশ দেয় না, যেমন

void *ptr = &something;
/* lots o' code */
ptr = NULL; // more obvious that it's a pointer and not being used

আইআইআরসি, স্ট্যান্ডার্ডের NUL 0 হওয়ার দরকার হয় না, সুতরাং <stddef.h> এ সংজ্ঞায়িত যা কিছু ব্যবহার করা সম্ভবত আপনার সংকলকের জন্য সেরা।

যুক্তিটির অন্য দিকটি হ'ল আপনার লজিকাল তুলনা করা উচিত (বুল করার জন্য অন্তর্নিহিত কাস্ট) বা NUL এর বিরুদ্ধে স্পষ্টতা পরীক্ষা করা উচিত, তবে এটি পড়ার ক্ষেত্রেও নেমে আসে।


3

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

এটি বলেছিল, পয়েন্টারগুলিকে নিজের মধ্যে সত্যের মান হিসাবে ব্যবহার করতে আমার কোনও সমস্যা নেই। ঠিক NULL এর মতোই এটি একটি অন্তর্নিহিত প্রতিমা।

সি ++ 09 নালপ্ট্র্ট কনস্ট্রাক্ট যুক্ত করবে যা আমার মনে হয় দীর্ঘ ওভার্ড।


1

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


1

কেউ আমাকে একবার বলেছিল ... আমি NUL কে 69 তে নতুন সংজ্ঞা দিতে যাচ্ছি then তখন থেকে আমি এটি ব্যবহার করি না: পি

এটি আপনার কোডটিকে বেশ দুর্বল করে তোলে।

সম্পাদনা:

মানক সব কিছুই নিখুঁত হয় না। ম্যাক্রো নুল হল একটি বাস্তবায়ন-সংজ্ঞায়িত সি ++ নাল পয়েন্টার ধ্রুবক সি নুল ম্যাক্রোর সাথে সম্পূর্ণরূপে সামঞ্জস্যপূর্ণ নয়, প্রকারের আড়াল থেকে লুকিয়ে থাকাটি এটিকে একটি অকেজো ও ত্রুটিযুক্ত সরঞ্জামে রূপান্তর করে।

NULL নাল পয়েন্টার হিসাবে নয় তবে ও / ওএল আক্ষরিক হিসাবে আচরণ করে।

আমাকে বলুন পরবর্তী উদাহরণটি বিভ্রান্তিকর নয়:

void foo(char *); 
void foo(int); 
foo(NULL); // calls int version instead of pointer version! 

এই সমস্ত কারণেই, নতুন স্ট্যান্ডার্ডে std :: nullptr_t প্রদর্শিত হবে

আপনি যদি নতুন স্ট্যান্ডারের জন্য অপেক্ষা করতে না চান এবং নাল্পটার ব্যবহার করতে চান না তবে মায়ারের প্রস্তাবিত মত কমপক্ষে একটি শালীন ব্যবহার করুন (jon.h মন্তব্য দেখুন)।


5
NULLসি ++ স্ট্যান্ডার্ডের একটি সুগঠিত অংশ। আপনার প্রকল্পে স্ট্যান্ডার্ড ম্যাক্রো সম্পাদনা কোডটিকে নতুন সংজ্ঞায়িত করতে দেওয়া আপনার কোডগুলি 'দুর্বল' করে তোলে; ব্যবহার NULLকরে না।
সিবি বেইলি

1

ঠিক আছে আমি যখনই সম্ভব 0 বা NULL পয়েন্টার ব্যবহার না করার পক্ষে যুক্তি দিচ্ছি।

এগুলি ব্যবহার করলে তাড়াতাড়ি বা পরে আপনার কোডে বিভাজন ত্রুটি ঘটবে। আমার অভিজ্ঞতায় এটি, এবং জেরারেলের পয়েন্টারগুলি সি ++ এর বাগগুলির বৃহত্তম উত্স

এছাড়াও, এটি আপনার কোডে সমস্ত "if-not-null" বিবৃতি বাড়ে। আপনি যদি সর্বদা একটি বৈধ রাষ্ট্রের উপর নির্ভর করতে পারেন তবে খুব সুন্দর।

প্রায় সবসময় একটি ভাল বিকল্প আছে।


2
গ্যারান্টিযুক্ত সেগমেন্টেশন ফল্ট (এবং করা হয় আধুনিক সিস্টেমে নিশ্চিত যখন আপনি dereference 0) হল দরকারী ডিবাগ করার জন্য। এলোমেলো আবর্জনা নির্ধারণ করা এবং কে কী ফলাফল জানতে পারে তার চেয়ে অনেক বেশি ভাল।
অরবিটে

-4

0 এ একটি পয়েন্টার সেট করা ঠিক এটি পরিষ্কার নয়। বিশেষত যদি আপনি সি ++ ব্যতীত অন্য কোনও ভাষাতে আসেন। এর মধ্যে সি এর পাশাপাশি জাভাস্ক্রিপ্ট রয়েছে।

আমি সম্প্রতি কিছু কোড সহ এরকম কিছু করেছি:

virtual void DrawTo(BITMAP *buffer) =0;

প্রথমবারের জন্য খাঁটি ভার্চুয়াল ফাংশনের জন্য। আমি ভেবেছিলাম এটি এক সপ্তাহের জন্য কিছু ম্যাজিক জিবারজ্যাশ হবে। যখন আমি বুঝতে পারলাম এটি কেবলমাত্র একটিতে ফাংশন পয়েন্টার সেট করছে null(কারণ ভার্চুয়াল ফাংশনগুলি সি ++ এর জন্য বেশিরভাগ ক্ষেত্রে কেবল ফাংশন পয়েন্টার হয়) আমি নিজেকে লাথি মেরেছিলাম।

virtual void DrawTo(BITMAP *buffer) =null;

আমার নতুন চোখে যথাযথ ব্যবধান না রেখে সেই বেসটারডেশনের চেয়ে কম বিভ্রান্তি হত। প্রকৃতপক্ষে, আমি ভাবছি যে কেন সি ++ লোয়ারকেসকে nullএতটা নিয়োগ দেয় না যেমন এটি লোয়ারকেসকে মিথ্যা এবং সত্যকে নিয়োগ করে ।


সাধারণভাবে আমি পয়েন্টারগুলির জন্য NULl থেকে 0 পছন্দ করি। তবে '= 0;' সি ++ তে খাঁটি ভার্চুয়াল ফাংশন ঘোষণার idiomatic উপায়। আমি আপনাকে দৃ =়ভাবে পরামর্শ দেব যে আপনি '= NULL' ব্যবহার করবেন না; এই বিশেষ ক্ষেত্রে।
ড্যানিও

এটি স্ট্যাকওভারফ্লোতে সবচেয়ে মজার মন্তব্য। আপনি সম্ভবত ইতিমধ্যে এখনই জানেন যে আপনি যে উদাহরণটি দিয়েছেন তা হ'ল খাঁটি ভার্চুয়াল ফাংশনের জন্য একটি সিনট্যাক্স এবং কোনও পয়েন্টার নয়। এবং হ্যাঁ @ স্প্যানিও ঠিক আছে, খাঁটি ভার্চুয়াল ফাংশনের জন্য আপনার NUL ব্যবহার করা উচিত নয়।
sgowd
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.