কেন এক লাইনে একটি ভেরিয়েবল ঘোষণা করবেন এবং পরের দিকে এটি বরাদ্দ করবেন?


101

আমি প্রায়শই সি এবং সি ++ কোডে নিম্নলিখিত কনভেনশন দেখতে পাই:

some_type val;
val = something;

some_type *ptr = NULL;
ptr = &something_else;

পরিবর্তে

some_type val = something;
some_type *ptr = &something_else;

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


12
"1 জন অভিজ্ঞ বিকাশকারীদের অভ্যাস এত তাড়াতাড়ি বরখাস্ত করতে না শিখেছি।" এটি শেখার জন্য বুদ্ধিমানের পাঠ।
ওয়াইল্ডকার্ড

উত্তর:


92

সি

C89 তে সমস্ত ঘোষণা একটি সুযোগ ( ) এর শুরুতে হওয়া উচিত ছিল{ ... } , তবে এই প্রয়োজনীয়তাটি দ্রুত বাতিল করা হয়েছিল (প্রথমে সংকলক বর্ধনের সাথে এবং পরে মান সহ) and

সি ++

এই উদাহরণগুলি এক নয়। ডিফল্ট কনস্ট্রাক্টরকে কল করার some_type val = something;সময় অনুলিপি কনস্ট্রাক্টরকে val = something;ফোন করে তারপরে operator=ফাংশনটি। এই পার্থক্য প্রায়শই সমালোচনামূলক।

খাদ্যাভ্যাস

কিছু লোক প্রথমে ভেরিয়েবলগুলি ঘোষণা করতে পছন্দ করে এবং পরে তাদের সংজ্ঞায়িত করতে পছন্দ করে, যদি তারা পরে তাদের কোডটি পুনরায় ফর্ম্যাট করে একটি স্পটে ঘোষণা করে এবং অন্য জায়গায় সংজ্ঞা দেয়।

পয়েন্টারগুলি সম্পর্কে, কিছু লোকের প্রতিটি পয়েন্টারটি প্রাথমিকভাবে শুরু করার অভ্যাস থাকে NULLবা nullptrthat পয়েন্টারটি দিয়ে তারা যাই করুক না কেন।


1
সি ++ এর জন্য দুর্দান্ত পার্থক্য, ধন্যবাদ। প্লেইন সি-তে কী হবে?
জোনাথন স্টার্লিং

13
সিএস মোডে সংকলন করার পরে ব্লকের শুরুতে এমএসভিসি এখনও ঘোষণাপত্র সমর্থন করে না এটি আমার পক্ষে অন্তহীন জ্বালা উত্সের কারণ।
মাইকেল বুড় 22

5
@ মিশেল বুড়: এটি কারণ এমএসভিসি সি 99 কে মোটেই সমর্থন করে না।
orlp

3
"কিছু_প্রকারের ভল = কিছু; কপি কনস্ট্রাক্টরকে কল করে": এটি কপি কনস্ট্রাক্টরকে কল করতে পারে , তবে স্ট্যান্ডার্ডটি সংকলকটিকে কোনও অস্থায়ী ডিফল্ট-নির্মাণের এলিডের অনুমতি দেয়, ভালের অনুলিপি এবং অস্থায়ী ধ্বংস এবং সরাসরি ব্যবহার করে ভাল ব্যবহার করে ভাল ব্যবহার করে some_typeনির্মাণকারী somethingএকক যুক্তি হিসাবে গ্রহণ । এটি সি ++ এর একটি খুব আকর্ষণীয় এবং অস্বাভাবিক প্রান্তের কেস ... এর অর্থ এই ক্রিয়াকলাপগুলির অর্থগত অর্থ সম্পর্কে ধারণা আছে।

2
@ অ্যারোভিস্টে: অন্তর্নির্মিত ধরণের জন্য এগুলি একই, তবে ব্যবহারকারী-সংজ্ঞায়িত প্রকারের ক্ষেত্রে সবসময় একই বলা যায় না।
orlp

27

আপনি একই সাথে আপনার প্রশ্ন সি এবং সি ++ ট্যাগ করেছেন, যখন এই ভাষাগুলিতে উত্তর উল্লেখযোগ্যভাবে আলাদা।

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

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

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

C99 ভাষায় ব্লকের মাঝখানে ভেরিয়েবলগুলি ঘোষণা করা ঠিক আছে (ঠিক সি ++ এর মতো), যার অর্থ প্রথম দিকটি কেবলমাত্র নির্দিষ্ট কিছু পরিস্থিতিতে প্রয়োজন যখন প্রাথমিক অবস্থার ঘোষণার সময় জানা যায় না। (এটি সি ++ তেও প্রযোজ্য)।


2
@ জোনাথন স্টার্লিং: আমি আপনার উদাহরণগুলি পড়েছি। আপনার সম্ভবত সি এবং সি ++ ভাষার স্ট্যান্ডার্ড পরিভাষাটি ব্রাশ করা দরকার। বিশেষত, পদগুলির ঘোষণা এবং সংজ্ঞা সম্পর্কিত , যার এই ভাষাগুলির নির্দিষ্ট অর্থ রয়েছে। আমি এটি আবার পুনরুক্ত করব: আপনার দুটি উদাহরণে ভেরিয়েবলগুলি এক লাইনে ঘোষণা করা এবং সংজ্ঞায়িত করা হবে। সি / সি ++ এ লাইনটি some_type val;তাত্ক্ষণিকভাবে ঘোষিত এবং ভ্যারিয়েবল সংজ্ঞায়িত করে val। আমার উত্তরে আমি এটাই বোঝাতে চাইছি।

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

1
সুতরাং, যদি sensক্যমত্যটি হয় যে "ডিক্লেয়ার "টি ভুল শব্দ, তবে আমি পরামর্শ দেব যে আমার চেয়ে আরও ভাল মানের জ্ঞানযুক্ত কেউ আমার চেয়ে উইকিবুক পৃষ্ঠা সম্পাদনা করুন।
জোনাথন স্টার্লিং 21

2
অন্য যে কোনও প্রসঙ্গে ডিক্লেয়ারটি সঠিক শব্দ হবে তবে যেহেতু ডিক্লেয়ারটি একটি সু-সংজ্ঞায়িত ধারণা , এর পরিণতি সহ সি এবং সি ++ এ আপনি অন্য প্রসঙ্গে যেমন ব্যবহার করতে পারেন তেমন আলগাভাবে এটি ব্যবহার করতে পারবেন না।
orlp

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

13

আমি মনে করি এটি একটি প্রাচীন অভ্যাস, "স্থানীয় ঘোষণা" বার থেকে বাদ পড়ে f এবং তাই আপনার প্রশ্নের উত্তর হিসাবে: না আমি মনে করি না এর কোনও ভাল কারণ আছে। আমি নিজেই কখনই করি না।


4

আমি এই ব্যাপারে কিছু বলেন আমার উত্তর করতে Helium3 দ্বারা একটি প্রশ্ন

মূলত, আমি বলি এটি সহজেই কী পরিবর্তিত হয়েছে তা দেখার জন্য এটি একটি চাক্ষুষ সহায়তা।

if (a == 0) {
    struct whatever *myobject = 0;
    /* did `myobject` (the pointer) get assigned?
    ** or was it `*myobject` (the struct)? */
}

এবং

if (a == 0) {
    struct whatever *myobject;
    myobject = 0;
    /* `myobject` (the pointer) got assigned */
}

4

অন্য উত্তরগুলি বেশ ভাল। সি এর মধ্যে প্রায় কিছু ইতিহাস রয়েছে সি ++ তে একটি কনস্ট্রাক্টর এবং একটি অ্যাসাইনমেন্ট অপারেটরের মধ্যে পার্থক্য রয়েছে।

আমি আশ্চর্য হয়েছি যে কেউ অতিরিক্ত পয়েন্টটির উল্লেখ করেনি: ঘোষণাপত্রের ব্যবহার থেকে পৃথক পৃথক ঘোষণা রাখা অনেক সময় অনেক বেশি পাঠযোগ্য হতে পারে।

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

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

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


2

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


2

পরিবর্তনশীল সংজ্ঞা এবং তাদের অর্থবহ সূচনাটির স্থানীয়করণের জন্য পেশাদাররা:

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

  • আরও দক্ষ হতে পারে

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

  • পরিবর্তে ভেরিয়েবলের ব্যাপ্তি হ্রাস করা সুযোগের সাথে একই সাথে ভেরিয়েবলের গড় সংখ্যা হ্রাস করে : এটি

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

  • নির্দিষ্ট ধরণের যেমন রেফারেন্সের জন্য এবং যখন আপনি অবজেক্টটি চান তা প্রয়োজনীয় const

পরিবর্তনশীল সংজ্ঞাগুলিকে গোষ্ঠীকরণের জন্য যুক্তিগুলি:

  • কখনও কখনও এটি সুবিধাজনক এবং / অথবা সংখ্যক ভেরিয়েবলের প্রকারের সংক্ষিপ্ত বিবরণ:

    the_same_type v1, v2, v3;

    (যদি কারণটি কেবলমাত্র এটি হয় যে নামটির নামটি অত্যধিক দীর্ঘ বা জটিল, তবে typedefকখনও কখনও এটি আরও ভাল হতে পারে)

  • কখনও কখনও কিছু ক্রিয়াকলাপে জড়িত ভেরিয়েবলগুলির সেট (এবং প্রকারের) উপর জোর দেওয়ার জন্য তাদের ব্যবহারের বাইরে গ্রুপ ভেরিয়েবলগুলি স্বাধীনভাবে আকাঙ্ক্ষিত:

    type v1;
    type v2; type v3;

    এটি প্রকারের সাধারণতার উপর জোর দেয় এবং এগুলি পরিবর্তন করা কিছুটা সহজ করে তোলে, যখন এখনও প্রতি লাইনে কোনও ভেরিয়েবলের সাথে লেগে থাকে যা কপি-পেস্ট, //মন্তব্য ইত্যাদিতে সহায়তা করে ..

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


আমি চাই যে আরও ভাষাগুলি কেসটি পৃথক করতে পারে যেখানে কোডটি একটি ভেরিয়েবলের মান ঘোষণা করে এবং সেট করে যা অন্য কোথাও কখনও লেখা হয় না, যদিও নতুন ভেরিয়েবল একই নাম ব্যবহার করতে পারে [যেখানে পরবর্তী বিবৃতি একই রকম চলক ব্যবহার করেছিল কিনা তা আচরণ একই হবে বা ভিন্ন একটি], কোডগুলি এমন একটি ভেরিয়েবল তৈরি করে যা একাধিক স্থানে লিখতে হবে। উভয় ব্যবহারের ক্ষেত্রে একই পদ্ধতি কার্যকর করা হবে, ত্রুটিগুলি অনুসন্ধান করার সময় ভেরিয়েবলগুলি কখন পরিবর্তন হতে পারে তা জেনে রাখা খুব সহায়ক।
সুপারক্যাট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.