আমি যদি (পয়েন্টার! = NULL) এর পরিবর্তে (পয়েন্টার) ব্যবহার করতে পারি?


171

এটা হচ্ছে না একটি পয়েন্টার চেক করতে কি নিরাপদ NULLকেবল লিখে if(pointer)অথবা আমি ব্যবহার করতে হবে if(pointer != NULL)?


13
সত্য, আপনি যদি একটি স্পষ্ট চেক ব্যবহার করতে চলেছেন তবে এটি ঠিক তেমন কার্যকর - এবং প্রায়শই পছন্দ করা - 0বা এর বিরুদ্ধে পরীক্ষা করা nullptr। ( NULLএটি সি'জম, এবং একটি শিরোনাম ফাইল অন্তর্ভুক্ত করা দরকার
সি হাও

5
@ দানিজার আপনি আধুনিক সি ++ এ নালপ্ট্র ব্যবহার করতে পারেন।
সারভাইভালমাচাইন

9
@ সিএইচও "সি এর সাথে সামঞ্জস্যের লক্ষ্যে" বিন্দুটি কোথায়?
qdii

5
@ ডানিজার: হ্যাঁ, NULLএখান থেকে আপনার সি ++ ব্যবহার করা উচিত নয় কারণ NULLবাস্তবায়ন নির্ভর ম্যাক্রো যা আপনাকে দ্ব্যর্থক আচরণ করতে পারে।
অলোক সেভ

3
যদিও এটি 'যদি' কেস না হয় তবে এই আদর্শিক লাইভ ডেমোটি দেখুন যে আপনি কেন সি ++ এর পয়েন্টারগুলির জন্য "NULL" এবং "0" এড়ানো উচিত: আদর্শ one.com/tbvXNs
কেফসোন

উত্তর:


197

আপনি পারেন; নাল পয়েন্টারটি সুস্পষ্টভাবে বুলেট ফ্যালে রূপান্তরিত হয় যখন নন-নাল পয়েন্টারগুলি সত্যে রূপান্তরিত হয়। সি ++ 11 স্ট্যান্ডার্ড থেকে, বুলিয়ান রূপান্তরগুলিতে বিভাগ:

পাটিগণিত, আনস্কোপড গণনা, পয়েন্টার বা পয়েন্টার থেকে সদস্য প্রকারের একটি মূল্য প্রকারভেদে রূপান্তরিত হতে পারে bool। একটি শূন্য মান, নাল পয়েন্টার মান বা নাল সদস্য পয়েন্টার মান রূপান্তরিত হয় false; অন্য কোনও মান রূপান্তরিত হয় true । প্রকারের একটি মূল্যকে প্রকারভেদে std::nullptr_t রূপান্তর করা যায় bool ; ফলাফল মান হয় false


42

হ্যাঁ, আপনি করতে পারেন।

  • একটি নাল পয়েন্টার মিথ্যা রূপে রূপান্তরিত হয়
  • একটি নন-নাল পয়েন্টারটি সত্যে রূপান্তরিত হয়।

এটি সি ++ স্ট্যান্ডার্ড রূপান্তরটির অংশ, যা বুলিয়ান রূপান্তর ধারায় পড়ে :

12 4.12 বুলিয়ান রূপান্তর

পাটিগণিত, আনস্কোপড গণনা, পয়েন্টার বা পয়েন্টার থেকে সদস্য প্রকারের একটি মূল্যকে টাইপ বুলের একটি মূল্যায় রূপান্তর করা যায়। একটি শূন্য মান, নাল পয়েন্টার মান বা নাল সদস্য পয়েন্টার মানকে মিথ্যে রূপান্তর করা হয়; অন্য যে কোনও মানকে সত্যে রূপান্তরিত করা হয়। Std :: nullptr_t প্রকারের একটি মূল্যকে বুল প্রকারের রূপে রূপান্তর করা যায়; ফলাফল মান মিথ্যা।


29

হ্যা, তুমি পারো. আসলে, আমি ব্যবহার করতে পছন্দ করি if(pointer)কারণ আপনি একবারে অভ্যস্ত হয়ে উঠলে এটি পড়তে এবং লিখতে সহজ।

এছাড়াও মনে রাখবেন সি ++ 11 চালু যে nullptrযার উপর পছন্দ করা হয় NULL


10
পয়েন্টারটি বুলিয়ান এক্সপ্রেশন নয়। এটি স্পষ্টত রূপান্তরিত। আপনি যখন বুঝতে চান এই রূপান্তরটি মনে রাখবেন তখন এটি আরও ভাল হয় যদি আপনার মতামত হয়। এটি কেবল এক ধরণের কোডিং স্টাইল।
হার্পার

7
@ হার্পার আপনি বলতে পারেন এটি একটি কোডিং শৈলী। কিন্তু আপনি একই যুক্তি প্রয়োগ করতে পারেন if(som_integer)বনাম if(some_integer != 0)কারণ পূর্ণসংখ্যার এছাড়াও Booleans, ডান না? আমি এড়াতে 0বা NULLকোনও বিবৃতিতে পছন্দ করি।
ইউ হাও

13
আমি সম্মত হব এটি কেবল কোডিং শৈলীর বিষয়। আমি if (pointer)নিজেকে পছন্দ করতে এসেছি , তবে আমার কাছে এটি if (ptr != nullptr)পুরোপুরি বৈধ বলে মনে হচ্ছে। অন্যদিকে, যদি আমার দলের আমি দেখেছি কেউ লিখেছে if (some_integer)আমি তাদের এটি পরিবর্তন করতে হবে if (some_integer != 0)। যাইহোক, আমি ভান করব না যে এটি আমার পক্ষ থেকে তুলনামূলকভাবে স্বেচ্ছাসেবী পছন্দ নয় - আমি কেবল পয়েন্টার এবং পূর্ণসংখ্যার সাথে একই আচরণ না করা পছন্দ করি।
জোয়েল

1
@ ইউহাউ এবং যেহেতু এটি কোড শৈলী আমি "এটি পছন্দসই" তবে "আমি পছন্দ করি" তা উল্লেখ করব না।
হার্পার

5
@ ফ্রানজি 1 তাহলে কেমন if(isReady) if(filePtr) if(serviceNo)? উদ্দেশ্য হিসাবে খারাপ পরিবর্তনশীল নাম তৈরির অর্থ এই ক্ষেত্রে খুব বেশি বোঝায় না। যাইহোক আমি ইতিমধ্যে আপনার বক্তব্য পেয়েছি এবং এটি বুঝতে পেরেছি, তবে আমি নিজের কোডিং শৈলীটি নিজেই ব্যবহার করে জোর দিতে পারি, ঠিক আছে?
ইউ হাও

13

প্রশ্নের উত্তর দেওয়া হয়েছে, তবে আমি আমার পয়েন্টগুলি যুক্ত করতে চাই।

আমি সর্বদা এর if(pointer)পরিবর্তে if(pointer != NULL)এবং if(!pointer)পরিবর্তে পছন্দ করব if(pointer == NULL):

  • এটি সহজ, ছোট
  • কম সম্ভাবনাগুলি হতে পারে বগী কোড লিখতে, আমি যদি সমতা চেক অপারেটর বানান ভুল অনুমান ==সঙ্গে =
    if(pointer == NULL)বানান ভুল করা যাবে if(pointer = NULL)তাই আমি এটা এড়াতে হবে, সেরা ঠিক হয় if(pointer)
    (আমিও একটি উত্তরে কিছু যোদা শর্তের পরামর্শ দিয়েছি , তবে এটি ভিন্ন বিষয়)

  • একইভাবে while (node != NULL && node->data == key), আমি সহজভাবে লিখতে হবেwhile (node && node->data == key) যা আমার কাছে আরও স্পষ্ট (শর্ট সার্কিট ব্যবহার করে দেখায়)।

  • (নির্বোধ কারণ হতে পারে) কারণ NULL হ'ল একটি ম্যাক্রো, যদি ধরা যাক কেউ অন্য মান দিয়ে ভুল করে পুনরায় সংজ্ঞায়িত হয়।

6
== এর পরিবর্তে = ব্যবহার করা প্রায়শই একটি সংকলক সতর্কতা উত্পন্ন করে, যে দিনগুলিতে লোকেরা এটি ব্যবহার করত না (NULL == ptr)
পলম

@ পলম যে আমি এই পয়েন্টটি যুক্ত করেছি যার নাম ইয়োডা কন্ডিশন কিছু লোক এটির কম পাঠযোগ্য হিসাবে পছন্দ করে না।
গ্রিজেশ চৌহান

2
(boolean expression)? true : falseসম্পূর্ণ অর্থহীন। অভিব্যক্তি হয় trueবা হয় মূল্যায়ন false; আপনি যা বলছেন তা "যদি এটি সত্য হয় তবে সত্য দিন, যদি এটি মিথ্যা হয় তবে আমাকে মিথ্যা দিন"। সংক্ষেপে: এটি নিজেই বুলিয়ান অভিব্যক্তির সমতুল্য। নোট যে node == NULLএকটি বুলিয়ান এক্সপ্রেশন। বিটিডাব্লু, আপনার দুটি বাস্তবায়ন একে অপরের বিপরীতে ফিরে আসে return হয় আপনি !=প্রথমটিতে চান , বা !দ্বিতীয়টিতে কেবল একটি ।
celtschk

বিটিডাব্লু, এর =পরিবর্তে একটি সম্ভাব্য সুরক্ষা ==হ'ল constযখনই সম্ভব আপনার পরিবর্তনশীল করা । উদাহরণস্বরূপ, আপনি নিজের ফাংশনটিকে এটি হিসাবে সংজ্ঞায়িত করতে পারেন isEmnpy(node* const head) { ... }, এবং তারপরে আপনি যদি ঘটনাক্রমে node = NULLপরিবর্তে লিখেছিলেন তবে সংকলক এটি সংকলন করতে অস্বীকার করবে node == NULL। অবশ্যই এটি কেবল পরিবর্তনশীলগুলির জন্য কাজ করে যা আপনার সত্যিকারের পরিবর্তনের দরকার নেই।
celtschk

2
কারণ অন্তর্নিহিত রূপান্তরগুলি এড়ানোর T* get() constপরিবর্তে স্মার্ট পয়েন্টার ক্লাসগুলির রয়েছে operator T*() const। তারা তবে একটি আছে operator bool() const
স্টার্লোরওয়ারটেক্স

13

পরিষ্কারভাবে NULL পরীক্ষা করা আপনি যা করতে চেষ্টা করছেন তার সংকলককে একটি ইঙ্গিত সরবরাহ করতে পারে, যার ফলে কম ত্রুটি-ঝুঁকির কারণ হতে পারে।

এখানে চিত্র বর্ণনা লিখুন


8

হ্যা, তুমি পারো. স্পষ্টভাবে শূন্যের সাথে মানগুলির তুলনা করার ক্ষমতা সি থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হয়েছে, এবং সেখানে সি ++ এর সমস্ত সংস্করণ রয়েছে। আপনি if (!pointer)NULL এর জন্য পয়েন্টারগুলি পরীক্ষা করতেও ব্যবহার করতে পারেন ।


2

নাল পয়েন্টারগুলির জন্য প্রাসঙ্গিক ব্যবহারের কেসগুলি

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

    Derived* derived_ptr = dynamic_cast<Derived*>(base_ptr);
    if(derived_ptr != nullptr) { ... }

    (বা, পছন্দসই, auto derived_ptr = ...)। এখন, এটি খারাপ, কারণ এটি সুরক্ষা-রক্ষণকারী ifব্লকের স্কোপের বাইরে (সম্ভবত অবৈধ, অর্থাৎ নাল) উত্পন্ন পয়েন্টারটি রেখে দেয় leaves এই প্রয়োজন হয় না যেমন সি ++ আপনি বুলিয়ান-convertable ভেরিয়েবল পরিচয় করিয়ে দিতে পারেন একটি ভিতরে if-condition :

    if(auto derived_ptr = dynamic_cast<Derived*>(base_ptr)) { ... }

    যা কেবলমাত্র খাটো এবং স্কোপ-নিরাপদই নয়, এটি এর উদ্দেশ্যতে আরও স্পষ্ট: আপনি যদি আলাদা শর্তে শূন্যতার জন্য পরীক্ষা করেন, পাঠক আশ্চর্য হয় যে "ঠিক আছে, তাই derived_ptrএখানে অবশ্যই নালু হওয়া উচিত না ... ভাল, কেন হবে? এটা নাল হতে হবে? " যেখানে এক লাইন সংস্করণ খুব স্পষ্টভাবে বলে "যদি আপনি নিরাপদে কাস্ট করতে পারেন base_ptrথেকে Derived*, তারপর জন্য এটি ব্যবহার ..."।

    একইভাবে অন্য যে কোনও সম্ভাব্য-ব্যর্থতার ক্রিয়াকলাপের জন্য ঠিক একই কাজ করে যা আপনাকে পয়েন্টার দেয়, যদিও আইএমও আপনার সাধারণত এড়ানো উচিত: boost::optionalপয়েন্টারগুলির পরিবর্তে সম্ভবত ব্যর্থ ক্রিয়াকলাপগুলির ফলাফলের জন্য "ধারক" এর মতো কিছু ব্যবহার করা ভাল ।

সুতরাং, নাল পয়েন্টার জন্য প্রধান ব্যবহারের ক্ষেত্রে সবসময় অন্তর্নিহিত-Cast-শৈলীর একটি পরিবর্তন লিখতে হবে যদি, আমি দৃঢ়তা কারণে এটা ভাল বলতে চাই সবসময় এই শৈলী ব্যবহার, IE আমি প্রচার চাই if(ptr)ওভার if(ptr!=nullptr)


আমার ভয় আমি একটি বিজ্ঞাপন দিয়ে শেষ করতে হবে নই: if(auto bla = ...)সিনট্যাক্স আসলে ঠিক সামান্য কষ্টকর পড়তা হয় বাস্তব : যেমন সমস্যার সমাধান প্যাটার্ন ম্যাচিং । আপনি কেন প্রথমে কিছু পদক্ষেপ (যেমন একটি পয়েন্টার কাস্টিং) জোর করবেন এবং তারপরে বিবেচনা করুন যে কোনও ব্যর্থতা হতে পারে ... মানে, এটি হাস্যকর, তাই না? এটি এর মতো, আপনার কাছে কিছু খাদ্যদ্রব্য রয়েছে এবং স্যুপ বানাতে চান। রস বের করার জন্য আপনি এটি আপনার সহকারীকে হস্তান্তর করুন, যদি এটি কোনও নরম উদ্ভিজ্জ হয়। আপনি প্রথমে এটি তাকান না। আপনার যদি আলু থাকে, আপনি এখনও এটি আপনার সহকারীকে দেন তবে তারা ব্যর্থতার নোট সহ আপনার মুখে তাড়াতাড়ি করে দেয়। আহ, জরুরী প্রোগ্রামিং!

আরও ভাল: আপনি যে সমস্ত ক্ষেত্রে মুখোমুখি হতে পারেন তা এখনই বিবেচনা করুন। তারপরে সেই অনুযায়ী কাজ করুন। Haskell,:

makeSoupOf :: Foodstuff -> Liquid
makeSoupOf p@(Potato{..}) = mash (boil p) <> water
makeSoupOf vegetable
 | isSoft vegetable  = squeeze vegetable <> salt
makeSoupOf stuff  = boil (throwIn (water<>salt) stuff)

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

⟨/ Advert⟩


1
আমি কেবলমাত্র এই অন্তর্বর্তী বিভক্তিতে একটি বাক্য দেখতে পারি যা আসলে প্রশ্নের উত্তর দেয়।
লার্নের মারকুইস

@ ইজেপি: আপনি যদি প্রশ্নটি আক্ষরিকভাবে গ্রহণ করেন (" আমি কি ব্যবহার করতে পারি"), তবে এর কোনও উত্তর সুস্পষ্টভাবে দেওয়া হয়নি (উত্তরটি কেবল "হ্যাঁ")। আমি কেন ওপি এর পরিবর্তে বাস্তবে ব্যবহার করা উচিত তার সঠিক কারণ দেওয়ার চেষ্টা করেছি , যার কাছে আরও কিছুটা বলার আছে। if(ptr)if(ptr != nullptr)
নভেম্বর

1

হ্যা অবশ্যই! প্রকৃতপক্ষে, (পয়েন্টার) লিখলে লেখার আরও সুবিধাজনক উপায় যদি হয় (পয়েন্টার! = NULL) কারণ: 1. এটি ডিবাগ করা সহজ 2 বোঝা সহজ 3 accident যদি দুর্ঘটনাক্রমে NULL এর মান সংজ্ঞায়িত হয়, তাহলেও কোডটি ক্রাশ হবে না



0

অন্যরা ইতিমধ্যে ভাল উত্তর হিসাবে, তারা উভয় বিনিময়যোগ্য।

তা সত্ত্বেও, এটা মূল্য উল্লেখ একটি মামলা যেখানে আপনি স্পষ্ট বিবৃতি ব্যবহার করার অর্থাত চাইতে পারেন সেখানে হতে পারে যে pointer != NULL

Https://stackoverflow.com/a/60891279/2463963 এও দেখুন


-1

হ্যাঁ, আপনি যখনই 'আইএফ' শর্তটি মূল্যায়ণ করেন কেবল তখনই তার অভ্যন্তরের অবস্থাটি সত্য হয়ে যায় আপনি এটি করতে পারেন। সি-তে কোনও বুলিয়ান রিটার্ন টাইপ নেই এবং শর্তটি সত্য হলে 'শূন্য-বহির্ভূত মান' প্রদান করে যখনই 'আইএফ' এর শর্তটি মিথ্যা বলে প্রমাণিত হয় তখন 0 প্রদান করে। ডিফল্টরূপে ফিরে আসা শূন্য নয় মান 1। সুতরাং কোড লেখার উভয় পদ্ধতিই সঠিক এবং আমি সর্বদা দ্বিতীয়টিকে পছন্দ করব।


1
যদি আমি সঠিকভাবে মনে করি তবে ডিফল্টরূপে শূন্যহীন মানটি অপরিজ্ঞাত হয়।
লার্নের মারকুইস

-1

আমি মনে করি থাম্বের নিয়ম হিসাবে, যদি আপনার যদি-এক্সপ্রেশনটি পুনরায় লেখা যায়

const bool local_predicate = *if-expression*;
if (local_predicate) ...

যেমন এটি কোনও সতর্কতা সৃষ্টি করে না, তবে এটি যদি-এক্সপ্রেশনটির জন্য পছন্দসই শৈলী হওয়া উচিত । (আমি জানি যখন আমি একটি পুরানো সি BOOL( #define BOOL int)) একটি সি ++ এ নিয়োগ করি তখন boolপয়েন্টার একা থাকি)


-1

"এটি নিরাপদ..?" ভাষা মান এবং উত্পন্ন কোড সম্পর্কে একটি প্রশ্ন।

"একটি ভাল অনুশীলন হয়?" বিবৃতিটি যে কোনও স্ট্যান্ডার্ড মানব পাঠক দ্বারা বিবৃতিটি কতটা বোঝা যায় তা একটি প্রশ্ন। আপনি যদি এই প্রশ্নটি জিজ্ঞাসা করছেন তবে এটি পরামর্শ দেয় যে "নিরাপদ" সংস্করণ ভবিষ্যতের পাঠক এবং লেখকদের কাছে কম স্পষ্ট।


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

@ দানিজার আপনি কি মনে করেন না আপনি কখন স্ট্যাক ওভারফ্লোতে নতুন ছিলেন এবং সাফল্য ছাড়াই 'মন্তব্য' বিভাগটি অনুসন্ধান করেছিলেন? 7 খ্যাতি সম্পন্ন কেউ এটি করতে পারে না।
ব্রক্সজিয়ার

@ জিমবাল্টার যা খুব বিভ্রান্তিকর, যেহেতু আপনি অন্যকে এটি করতে দেখেন। আমি যখন এসওতে নতুন ছিলাম তখন কেউ আমাকে এর জন্য দোষারোপ করেছিল।
ব্রক্সজিয়ার

@ জিমবাল্টার আমি হত্যা এবং চুরি করছি না। আমি দানিজরকে বলছিলাম যে ফ্রেড মিচেল একজন নতুন ব্যবহারকারী এবং মন্তব্য পোস্ট করতে পারেনি।
ব্রক্সজিয়ার

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