সি এর নীচের বিবৃতিগুলির মধ্যে কোনটি ব্যবহার করা ভাল?
static const int var = 5;
অথবা
#define var 5
অথবা
enum { var = 5 };
সি এর নীচের বিবৃতিগুলির মধ্যে কোনটি ব্যবহার করা ভাল?
static const int var = 5;
অথবা
#define var 5
অথবা
enum { var = 5 };
উত্তর:
এটি আপনার মূল্য কী প্রয়োজন তার উপর নির্ভর করে। আপনি (এবং এখনও পর্যন্ত প্রত্যেকে) তৃতীয় বিকল্প বাদ দিয়েছেন:
static const int var = 5;
#define var 5
enum { var = 5 };
নামের পছন্দ সম্পর্কে বিষয়গুলি উপেক্ষা করা, তারপরে:
সুতরাং, বেশিরভাগ প্রসঙ্গে, বিকল্পগুলির চেয়ে 'এনাম' পছন্দ করুন। অন্যথায়, প্রথম এবং শেষ বুলেট পয়েন্টগুলি নিয়ন্ত্রণকারী কারণ হতে পারে - এবং আপনার যদি উভয়কে একবারে সন্তুষ্ট করতে হয় তবে আপনাকে আরও কঠোরভাবে চিন্তা করতে হবে।
আপনি যদি সি ++ সম্পর্কে জিজ্ঞাসা করছিলেন, তবে আপনি প্রতিবার স্ট্যাটিক কনস্ট - (1) বিকল্পটি ব্যবহার করবেন।
enum
হ'ল এগুলি int
([C99] 6.7.2.2/3) হিসাবে প্রয়োগ করা হয়েছে । এ #define
আপনাকে স্বাক্ষরবিহীন এবং দীর্ঘ U
এবং L
প্রত্যয়গুলি নির্দিষ্ট const
করতে দেয় এবং আপনাকে একটি প্রকার দিতে দেয়। enum
সাধারণ ধরণের রূপান্তরগুলির সাথে সমস্যা তৈরি করতে পারে।
enum
না #define
। তথ্য বিভাগে বা হিপ বা স্ট্যাকের স্টোরেজ বরাদ্দ না করে মানটি নির্দেশের অংশ হিসাবে অবজেক্ট কোডে উপস্থিত হবে। আপনার জন্য কিছু জায়গা বরাদ্দ থাকবে static const int
, তবে আপনি যদি কোনও ঠিকানা না নেন তবে সংকলকটি এটি অপ্টিমাইজ করতে পারে।
enum
গুলি (এবং static const
) এর জন্য অন্য একটি 'ভোট' : সেগুলি পরিবর্তন করা যায় না। একটি যেখানে 'd' দেওয়া define
যেতে পারে এবং #undefine
সেখানে দেওয়া মানের সাথে স্থির থাকে। enum
static const
সাধারণভাবে বলতে:
static const
কারণ এটি সুযোগকে সম্মান করে এবং টাইপ-নিরাপদ।
আমি কেবলমাত্র ক্যাভিয়েট দেখতে পেলাম: আপনি যদি ভেরিয়েবলটি সম্ভবত কমান্ড লাইনে সংজ্ঞায়িত করতে চান তবে। এখনও একটি বিকল্প আছে:
#ifdef VAR // Very bad name, not long enough, too general, etc..
static int const var = VAR;
#else
static int const var = 5; // default value
#endif
যখনই সম্ভব, ম্যাক্রোগুলি / উপবৃত্তির পরিবর্তে, একটি টাইপ-নিরাপদ বিকল্প ব্যবহার করুন।
যদি আপনি সত্যিই কোনও ম্যাক্রোর সাথে যেতে চান (উদাহরণস্বরূপ, আপনি চান __FILE__
বা __LINE__
), তবে আপনি আপনার ম্যাক্রোর খুব ভালভাবে নাম লিখবেন : এর নামকরণ কনভেনশনে বুস্ট প্রকল্পের নাম দিয়ে শুরু করে সমস্ত উচ্চ-মামলার প্রস্তাব দেয় (এখানে BOOST_ ), গ্রন্থাগারটি বন্ধ করার সময় আপনি লক্ষ্য করবেন যে এটি (সাধারণত) নির্দিষ্ট অঞ্চলের নাম (লাইব্রেরি) এর পরে অর্থবহ নাম সহ রয়েছে।
এটি সাধারণত দীর্ঘ নামগুলি তৈরি করে :)
static
যাদের ঠিকানা নেওয়া হয়েছে কেবল তারাই থাকবে; এবং যদি ঠিকানাটি নেওয়া হয় তবে তারা একটি #define
বা enum
(কোনও ঠিকানা) ব্যবহার করতে পারত না ... সুতরাং বিকল্পটি কী ব্যবহার করতে পারত তা আমি সত্যিই ব্যর্থ হয়েছি। আপনি যদি "সংকলনের সময় মূল্যায়ন" দিয়ে কিছু করতে পারেন তবে আপনি extern const
তার পরিবর্তে সন্ধান করতে পারেন ।
#if
চেয়ে বেশি পছন্দনীয় হতে পারে #ifdef
, তবে এক্ষেত্রে কমান্ড লাইন থেকে এটি নির্ধারণ var
করা অসম্ভব হয়ে উঠবে 0
। সুতরাং এই ক্ষেত্রে, #ifdef
যতক্ষণ না 0
আইনী মূল্য হিসাবে ততক্ষণ তা বোঝা যায় var
।
সি তে, বিশেষভাবে? সিতে সঠিক উত্তরটি হ'ল: #define
(অথবা উপযুক্ত হলে ব্যবহার করুন enum
)
যদিও কোনও const
বস্তুর স্কোপিং এবং টাইপিংয়ের বৈশিষ্ট্য থাকা সুবিধাজনক তবে বাস্তবে const
সিতে থাকা বস্তুগুলি (সি ++ এর বিপরীতে) সত্য ধ্রুবক নয় এবং তাই বেশিরভাগ ব্যবহারিক ক্ষেত্রে সাধারণত অকেজো হয়।
সুতরাং, সিতে পছন্দটি নির্ধারণ করা উচিত আপনি কীভাবে আপনার ধ্রুবকটি ব্যবহার করার পরিকল্পনা করছেন। উদাহরণস্বরূপ, আপনি কোনও const int
বস্তুকে case
লেবেল হিসাবে ব্যবহার করতে পারবেন না (যখন ম্যাক্রো কাজ করবে)। আপনি কোনও const int
বিষয়টিকে বিট-ফিল্ড প্রস্থ হিসাবে ব্যবহার করতে পারবেন না (যখন ম্যাক্রো কাজ করবে)। C89 / 90 এ আপনি const
কোনও অ্যারের আকার নির্দিষ্ট করতে কোনও বস্তু ব্যবহার করতে পারবেন না (যখন ম্যাক্রো কাজ করবে)। এমনকি C99 এ আপনি const
যখন বিন-ভিএলএ অ্যারে প্রয়োজন তখন কোনও অ্যারের আকার নির্দিষ্ট করতে কোনও অবজেক্ট ব্যবহার করতে পারবেন না ।
এটি যদি আপনার পক্ষে গুরুত্বপূর্ণ হয় তবে তা আপনার পছন্দটি নির্ধারণ করবে। বেশিরভাগ সময়, আপনার #define
সিতে ব্যবহার করা ছাড়া কোনও বিকল্প নেই এবং অন্য কোনও বিকল্প ভুলে যাবেন না, যা সিতে সত্যিকারের ধ্রুবক তৈরি করে enum
।
সি ++ const
অবজেক্টগুলিতে সত্যিকারের ধ্রুবক থাকে, সুতরাং সি ++ এ const
ভেরিয়েন্টটি পছন্দ করা প্রায় সর্বদা ভাল ( static
যদিও সি ++ তে স্পষ্ট করার প্রয়োজন নেই )।
const int
কেস-লেবেলে অবজেক্টগুলি ব্যবহার করা সি ভাষার সমস্ত সংস্করণে অবৈধ। (অবশ্যই, আপনার
const
মানে কেবল পঠনযোগ্য। const int r = rand();
পুরোপুরি আইনী।
constexpr
যেমন তুলনায় const
সঙ্গে বিশেষভাবে stl
মত পাত্রে array
বা bitset
।
switch()
বিবৃতিতে পরীক্ষা করেছেন, case
একটিতে নয়। আমি কেবল এটিরও ধরা পড়েছি
static const
এবং এর মধ্যে পার্থক্যটি #define
হ'ল প্রাক্তন মেমরিটি ব্যবহার করে এবং পরে স্টোরেজটির জন্য মেমরিটি ব্যবহার করে না। দ্বিতীয়ত, আপনি কোনওটির ঠিকানা পাস করতে পারবেন না #define
তবে আপনি এ এর ঠিকানাটি পাস করতে পারবেন static const
। আসলে এটি নির্ভর করে যে আমরা কোন পরিস্থিতিতে আছি তার উপর নির্ভর করে, আমাদের এই দুটিয়ের মধ্যে একটি নির্বাচন করা দরকার। উভয়ই বিভিন্ন পরিস্থিতিতে তাদের সেরা। দয়া করে ধরে নিবেন না যে একজন অন্যটির চেয়ে ভাল ... :-)
যদি এমনটি হত, ডেনিস রিচি সেরাকে একা রেখে দিতেন ... হাহাহাহা ... :-)
const
কোনও স্মৃতি ব্যবহার করে। জিসিসি (৪.৩.৩ এবং কয়েকটি নতুন সংস্করণ দিয়ে পরীক্ষা করা) const int
-O3 ব্যবহার করার সময় সহজেই আপনার কোডটিতে সরাসরি আক্ষরিক হয়ে যায়। সুতরাং আপনি যদি কম র্যাম এম্বেডড ডেভলপমেন্ট করেন (যেমন এভিআর) আপনি নিরাপদে সি কনসেটগুলি ব্যবহার করতে পারেন যদি আপনি জিসিসি বা অন্য কোনও সামঞ্জস্যপূর্ণ সংকলক ব্যবহার করেন। আমি এটি পরীক্ষা করে দেখিনি তবে কলং আশা করে বিটিডব্লিউ একই কাজ করবে।
সি #define
তে অনেক বেশি জনপ্রিয়। উদাহরণস্বরূপ অ্যারে আকারগুলি ঘোষণার জন্য আপনি এই মানগুলি ব্যবহার করতে পারেন:
#define MAXLEN 5
void foo(void) {
int bar[MAXLEN];
}
আমার জানা মতে এএনএসআই সি আপনাকে static const
এই প্রসঙ্গে ব্যবহার করতে দেয় না। সি ++ এ আপনার ক্ষেত্রে ম্যাক্রোগগুলি এড়ানো উচিত। তুমি লিখতে পারো
const int maxlen = 5;
void foo() {
int bar[maxlen];
}
এমনকি এমনকি ছেড়ে চলে যান static
কারণ অভ্যন্তরীণ লিঙ্কেজ const
ইতিমধ্যে [কেবলমাত্র C ++ এ) দ্বারা জড়িত।
const int MY_CONSTANT = 5;
একটি ফাইল থাকতে পারে এবং extern const int MY_CONSTANT;
অন্যটিতে এটি অ্যাক্সেস করতে পারি । আমি (অন্তত C99) মান যে কোন তথ্য খুঁজে পাইনি const
": 5 একটি বস্তুর জন্য একটি identi ফাই Er ঘোষণা ফাই Le সুযোগ এবং কোন স্টোরেজ ক্লাসের সুনিন্টি ফাই Er পারবে, তবে তার দুটো ঘটনার বাহ্যিক 6.2.2" ডিফল্ট আচরণ পরিবর্তন।
bar
একটি ভিএলএ (পরিবর্তনশীল দৈর্ঘ্যের অ্যারে); সংকলক সম্ভবত কোড জেনারেট করে যেমন এর দৈর্ঘ্য স্থির ছিল।
const
সি-তে আরেকটি অপূর্ণতা হ'ল আপনি আর কোনওটিকে আরম্ভ করার ক্ষেত্রে মানটি ব্যবহার করতে পারবেন না const
।
static int const NUMBER_OF_FINGERS_PER_HAND = 5;
static int const NUMBER_OF_HANDS = 2;
// initializer element is not constant, this does not work.
static int const NUMBER_OF_FINGERS = NUMBER_OF_FINGERS_PER_HAND
* NUMBER_OF_HANDS;
এমনকি এটি কোনও কনস্টের সাথে কাজ করে না যেহেতু সংকলক এটি ধ্রুবক হিসাবে দেখেনি:
static uint8_t const ARRAY_SIZE = 16;
static int8_t const lookup_table[ARRAY_SIZE] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; // ARRAY_SIZE not a constant!
আমি const
এই ক্ষেত্রে টাইপ ব্যবহার করতে পেরে খুশি হব , অন্যথায় ...
static uint8_t const ARRAY_SIZE = 16;
হঠাৎ আপনার সমস্ত সংকলন আর কেন সংকলনগুলি কিছুটা চ্যালেঞ্জের হতে পারে তা অনুসরণ করে তাড়না করা, বিশেষত যখন #define ARRAY_SIZE 256
হেডারগুলির জটলা ওয়েবের মধ্যে দশ স্তর গভীরভাবে সমাহিত করা হয়। সমস্ত ক্যাপের নাম ARRAY_SIZE
ঝামেলা চাইছে। ম্যাক্রোগুলির জন্য ALL_CAPS সংরক্ষণ করুন এবং ALL_CAPS আকারে নেই এমন ম্যাক্রো কখনই সংজ্ঞায়িত করবেন না।
const
। এটি আরও upvated হতে পারে!
আপনি যদি এটির সাথে পালাতে পারেন তবে এর static const
অনেক সুবিধা রয়েছে। এটি সাধারণ স্কোপ নীতিগুলি মান্য করে, একটি ডিবাগারে দৃশ্যমান হয় এবং সাধারণত নিয়মগুলি মানায় যা ভেরিয়েবলগুলি পালন করে।
তবে কমপক্ষে মূল সি স্ট্যান্ডার্ডে এটি আসলে ধ্রুবক নয়। যদি আপনি ব্যবহার করেন তবে আপনি ঘোষণা হিসাবে #define var 5
লিখতে পারেন int foo[var];
, তবে আপনি এটি করতে পারবেন না (সংকলক এক্সটেনশন হিসাবে "সহ" static const int var = 5;
এটি সি ++ তে নয়, যেখানে static const
সংস্করণটি যে কোনও জায়গায় ব্যবহার করা যেতে পারে #define
, এবং আমি এটি বিশ্বাস করি সি 99 এর ক্ষেত্রেও এটি।
তবে #define
ছোট হাতের নাম দিয়ে কোনও ধ্রুবকের নাম রাখবেন না। এটি অনুবাদ ইউনিট শেষ না হওয়া পর্যন্ত এই নামের যে কোনও সম্ভাব্য ব্যবহারকে ওভাররাইড করবে। ম্যাক্রো ধ্রুবকগুলি কার্যকরভাবে তাদের নিজস্ব নেমস্পেসে থাকা উচিত যা traditionতিহ্যগতভাবে সমস্ত মূলধন, সম্ভবত একটি উপসর্গ সহ।
const
C99 এ এখনও সত্যিকারের ধ্রুবক নয়। আপনি const
C99 এর সাথে অ্যারের আকার ঘোষণা করতে পারেন , তবে কেবলমাত্র C99 চলক দৈর্ঘ্যের অ্যারে সমর্থন করে। এই কারণে, এটি কেবলমাত্র যেখানে VLAs অনুমোদিত তা কাজ করবে। উদাহরণস্বরূপ, এমনকি সি 99 এ, আপনি এখনও const
কোনও সদস্য অ্যারের আকার ঘোষণা করতে একটি ব্যবহার করতে পারবেন না struct
।
const int
আকারের সাথে অ্যারেগুলি শুরু করতে দেবে যেন এটি সি ++ কনস্ট বা ম্যাক্রো। আপনি যদি মান থেকে জিসিসির এই বিচ্যুতির উপর নির্ভর করতে চান তবে অবশ্যই আপনার পছন্দ, আপনি যদি জিসিসি বা ক্ল্যাংয়ের চেয়ে অন্য সংকলকটি ব্যবহার করে সত্যিই ফর্স করতে না পারেন তবে আমি ব্যক্তিগতভাবে এটির সাথে যাব, পরবর্তীটির এখানে একই বৈশিষ্ট্য রয়েছে (ক্ল্যাংয়ের সাথে পরীক্ষা করা হয়েছে) 3.7)।
এটি # ডিফাইন পরিবর্তে কনস্ট ব্যবহার করা সর্বদা পছন্দনীয়। এর কারণ কনস্টাইলারটি সংকলক এবং প্রিপ্রসেসর দ্বারা # ডিফাইন দ্বারা চিকিত্সা করা হয়। এটি # ডিফাইন নিজেই কোডের অংশ নয় (মোটামুটি কথা বলার মতো) is
উদাহরণ:
#define PI 3.1416
প্রতীকী নাম পিআই কখনও সংকলকদের দ্বারা দেখা যায় না; উত্স কোড এমনকি কোনও সংকলকের কাছে যাওয়ার আগে এটি প্রিপ্রসেসর দ্বারা মুছে ফেলা হতে পারে। ফলস্বরূপ, পিআই নামটি প্রতীক সারণিতে প্রবেশ করতে পারে না। ধ্রুবক ব্যবহারের সাথে জড়িত সংকলনের সময় আপনি যদি ত্রুটি পান তবে এটি বিভ্রান্ত হতে পারে, কারণ ত্রুটি বার্তাটি পিআই নয়, 3.1416 উল্লেখ করতে পারে। আপনি লেখেন নি এমন একটি শিরোলেখ ফাইলটিতে যদি পিআই সংজ্ঞায়িত করা হয়, তবে আপনার কোন ধারণা নেই যে 3.1416 কোথা থেকে এসেছে।
এই সমস্যাটি একটি প্রতীকী ডিবাগারেও উত্থিত হতে পারে, কারণ, আবার আপনি যে নামটির সাথে প্রোগ্রামিং করছেন সেটি প্রতীক টেবিলের মধ্যে নাও থাকতে পারে।
সমাধান:
const double PI = 3.1416; //or static const...
#define var 5
আপনার মতো জিনিস থাকলে আপনাকে সমস্যা সৃষ্টি করবে mystruct.var
।
উদাহরণ স্বরূপ,
struct mystruct {
int var;
};
#define var 5
int main() {
struct mystruct foo;
foo.var = 1;
return 0;
}
প্রিপ্রসেসর এটি প্রতিস্থাপন করবে এবং কোডটি সংকলন করবে না। এই কারণে, traditionalতিহ্যবাহী কোডিং শৈলীতে সমস্ত ধ্রুবকগুলি #define
সংঘাত এড়ানোর জন্য বড় ধরণের অক্ষর ব্যবহার করার পরামর্শ দেয় ।
আমি একটি পার্থক্য প্রদর্শনের জন্য দ্রুত পরীক্ষা প্রোগ্রাম লিখেছি:
#include <stdio.h>
enum {ENUM_DEFINED=16};
enum {ENUM_DEFINED=32};
#define DEFINED_DEFINED 16
#define DEFINED_DEFINED 32
int main(int argc, char *argv[]) {
printf("%d, %d\n", DEFINED_DEFINED, ENUM_DEFINED);
return(0);
}
এটি এই ত্রুটিগুলি এবং সতর্কতার সাথে সংকলন করে:
main.c:6:7: error: redefinition of enumerator 'ENUM_DEFINED'
enum {ENUM_DEFINED=32};
^
main.c:5:7: note: previous definition is here
enum {ENUM_DEFINED=16};
^
main.c:9:9: warning: 'DEFINED_DEFINED' macro redefined [-Wmacro-redefined]
#define DEFINED_DEFINED 32
^
main.c:8:9: note: previous definition is here
#define DEFINED_DEFINED 16
^
নোট করুন যে এনাম একটি সংজ্ঞা দেয় যখন সংজ্ঞায়িত একটি সতর্কতা দেয়।
সংজ্ঞাটি
const int const_value = 5;
সর্বদা স্থির মান নির্ধারণ করে না। কিছু সংকলক (উদাহরণস্বরূপ tcc 0.9.26 ) "কনস্ট_ভ্যালু" নামের সাথে চিহ্নিত মেমরিটিকে কেবল বরাদ্দ করে। "কনস্ট_ভ্যালু" সনাক্তকারী ব্যবহার করে আপনি এই স্মৃতিটিকে পরিবর্তন করতে পারবেন না। তবে আপনি এখনও অন্য সনাক্তকারী ব্যবহার করে মেমরিটি পরিবর্তন করতে পারেন:
const int const_value = 5;
int *mutable_value = (int*) &const_value;
*mutable_value = 3;
printf("%i", const_value); // The output may be 5 or 3, depending on the compiler.
এর অর্থ সংজ্ঞা
#define CONST_VALUE 5
একটি ধ্রুবক মান সংজ্ঞায়নের একমাত্র উপায় যা কোনও উপায়ে পরিবর্তন করা যায় না।
#define
মেশিন কোডটি সম্পাদনা করেও সংশোধন করা যায়।
5
। তবে #define
কোনওটি সংশোধন করতে পারে না কারণ এটি একটি প্রিপ্রেসেসর ম্যাক্রো। এটি বাইনারি প্রোগ্রামে বিদ্যমান নেই। যদি কেউ যেখানে CONST_VALUE
ব্যবহৃত সমস্ত জায়গাগুলি পরিবর্তন করতে চায় তবে একে একে একে একে করতে হয়েছিল।
#define CONST 5
তখন লেখেন , if (CONST == 5) { do_this(); } else { do_that(); }
এবং সংকলকটি else
শাখাটি মুছে ফেলে । আপনি কীভাবে মেশিন কোডটি CONST
6 এ পরিবর্তন করার প্রস্তাব দিচ্ছেন ?
#define
বুলেট-প্রুফ নয়।
#define
। এটি করার একমাত্র আসল উপায় হ'ল উত্স কোডটি সম্পাদনা করা এবং পুনরায় সংযোগ করা।
যদিও প্রশ্নটি পূর্ণসংখ্যা সম্পর্কিত ছিল, তবে আপনার যদি ধ্রুবক কাঠামো বা স্ট্রিংয়ের প্রয়োজন হয় তবে # ডেফাইন এবং এনামগুলি অকেজো not এগুলি উভয়ই পয়েন্টার হিসাবে সাধারণত ফাংশনে প্রেরণ করা হয়। (স্ট্রিংগুলির সাথে এটি প্রয়োজনীয়; কাঠামোগুলি সহ এটি আরও কার্যকর)
পূর্ণসংখ্যার জন্য, আপনি খুব সীমাবদ্ধ মেমরির সাথে এম্বেড করা পরিবেশে থাকলে, ধ্রুবকটি কোথায় সংরক্ষণ করা হয় এবং কীভাবে এটিতে অ্যাক্সেস করা হয় তা কীভাবে সঙ্কলিত হয় তা নিয়ে আপনার চিন্তার প্রয়োজন হতে পারে। সংকলকটি রান সময়ে দুটি কনস্ট যুক্ত করতে পারে তবে সংকলনের সময় দুটি # সংজ্ঞা যুক্ত করতে পারে। একটি # নির্দিষ্ট ধ্রুবককে এক বা একাধিক এমওভি [তাত্ক্ষণিক] নির্দেশিকায় রূপান্তর করা যেতে পারে, যার অর্থ ধ্রুবকটি কার্যকরভাবে প্রোগ্রামের মেমোরিতে সংরক্ষিত থাকে। একটি কনস্ট কনস্ট্যান্ট ডেটা মেমরির .const বিভাগে সংরক্ষণ করা হবে। হার্ভার্ড আর্কিটেকচারযুক্ত সিস্টেমে কর্মক্ষমতা এবং মেমরির ব্যবহারের ক্ষেত্রে পার্থক্য থাকতে পারে, যদিও তারা সম্ভবত ছোট হবে be তারা অভ্যন্তরীণ লুপগুলির হার্ড-কোর অপ্টিমাইজেশনের জন্য গুরুত্বপূর্ণ হতে পারে।
"যা সর্বদা সেরা" এর মত উত্তর নেই তবে ম্যাথিউ বলেছিলেন বলে মনে করবেন না said
static const
টাইপ নিরাপদ। আমার সবচেয়ে বড় পোষা প্রাণীর সাথে #define
হল ভিজ্যুয়াল স্টুডিওতে ডিবাগ করার সময় আপনি পরিবর্তনশীলটি দেখতে পারবেন না। এটি একটি ত্রুটি দেয় যা প্রতীকটি খুঁজে পাওয়া যায় না।
ঘটনাচক্রে, এর বিকল্প #define
, যা সঠিক স্কোপিং সরবরাহ করে তবে একটি "সত্য" ধ্রুবকের মতো আচরণ করে, তা হ'ল এনাম "। উদাহরণ স্বরূপ:
enum {number_ten = 10;}
অনেক ক্ষেত্রে, এটি গণনা করা ধরণের সংজ্ঞা এবং এই ধরণের ভেরিয়েবলগুলি তৈরি করতে দরকারী; যদি এটি হয়ে যায়, ডিবাগারগুলি তাদের গণনার নাম অনুসারে চলক প্রদর্শন করতে সক্ষম হতে পারে।
এটি করার ক্ষেত্রে একটি গুরুত্বপূর্ণ সতর্কতা, তবে: সি ++ তে, গণিত প্রকারের পূর্ণসংখ্যার সাথে সীমিত সামঞ্জস্য থাকে। উদাহরণস্বরূপ, ডিফল্টরূপে, কেউ তাদের গাণিতিক সম্পাদন করতে পারে না। আমি দেখতে পেয়েছি যে এনামদের জন্য একটি কৌতূহল ডিফল্ট আচরণ; যদিও "কড়া এনাম" টাইপটি ভাল লাগত, সি ++ এর সাথে সি ++ এর সাথে সাধারণত সামঞ্জস্য রাখার আকাঙ্ক্ষা দেখাচ্ছিল, আমি মনে করব একটি "এনাম" টাইপের ডিফল্ট আচরণটি পূর্ণসংখ্যার সাথে বিনিময়যোগ্য হওয়া উচিত।
int
, সুতরাং "এনাম হ্যাক" অন্যান্য পূর্ণসংখ্যার প্রকারের সাথে ব্যবহার করা যায় না। (গণনাটি টাইপ কিছু প্রয়োগ-সংজ্ঞায়িত পূর্ণসংখ্যার ধরণের সাথে সামঞ্জস্যপূর্ণ, প্রয়োজনীয়ভাবে নয় int
, তবে এই ক্ষেত্রে প্রকারটি বেনামে যাতে কোনও ব্যাপার না))
int
ভেরিয়েবল (যা সংকলকগুলি করার অনুমতি দেয়) ব্যতীত অন্য কোনও ধরণের কাজ নির্ধারণ করে এবং একজন এই জাতীয় একটি ভেরিয়েবলের জন্য নিযুক্ত করার চেষ্টা করে নিজস্ব গণনার সদস্য। আমি আশা করি মানক কমিটিগুলি নির্দিষ্ট শব্দার্থক দিয়ে পূর্ণসংখ্যার প্রকার ঘোষণার বহনযোগ্য উপায় যুক্ত করবে। যে কোনও প্ল্যাটফর্ম, char
আকার নির্বিশেষে , উদাহরণস্বরূপ এমন কোনও প্রকারের ঘোষণা করতে সক্ষম হওয়া উচিত যা মোড 65536 মোড়বে, এমনকি সংকলকটিতে প্রচুর পরিমাণে AND R0,#0xFFFF
বা সমতুল্য নির্দেশাবলী যুক্ত করতে হবে।
uint16_t
, যদিও এটি অবশ্যই একটি গণনার ধরণ নয়। এটা তোলে ব্যবহারকারী পূর্ণসংখ্যা একটি প্রদত্ত পরিগণনা প্রকার প্রতিনিধিত্ব করতে ব্যবহৃত টাইপ উল্লেখ করা যাক চমৎকার হবে, কিন্তু আপনি একটি সঙ্গে একই প্রভাব অনেক অর্জন করতে পারেন typedef
জন্য uint16_t
এবং একটি সিরিজ #define
পৃথক মানের জন্য গুলি।
2U < -1L
সত্য এবং অন্যকে মিথ্যা হিসাবে মূল্যায়ন করবে এই সত্য নিয়ে আটকে গেছি এবং আমরা এখন এই সত্যটির সাথে আটকেছি যে কিছু প্ল্যাটফর্ম স্বাক্ষরিত uint32_t
এবং int32_t
স্বাক্ষরিত হিসাবে একটি তুলনা কার্যকর করবে এবং কিছু স্বাক্ষরবিহীন হিসাবে, কিন্তু এর অর্থ এই নয় যে কমিটি সি-তে একটি wardর্ধ্ব-সামঞ্জস্যপূর্ণ উত্তরসূরির সংজ্ঞা দিতে পারে না যার মধ্যে এমন ধরণের অন্তর্ভুক্ত রয়েছে যার শব্দার্থকগুলি সমস্ত সংকলকগুলির সাথে সামঞ্জস্যপূর্ণ থাকবে।
একটি সাধারণ পার্থক্য:
প্রাক-প্রসেসিংয়ের সময় ধ্রুবকটিকে তার মান দিয়ে প্রতিস্থাপন করা হয়। সুতরাং আপনি একটি সংজ্ঞায়িত করার জন্য ডেরিফারেন্স অপারেটর প্রয়োগ করতে পারেন নি, তবে আপনি একটি ভেরিয়েবলের জন্য ডেরেফারেন্স অপারেটর প্রয়োগ করতে পারেন।
আপনি যেমন ধরুন, সংজ্ঞায়িত করা স্থায়ী কনস্টের দ্রুততর।
উদাহরণস্বরূপ, থাকা:
#define mymax 100
আপনি করতে পারবেন না printf("address of constant is %p",&mymax);
।
কিন্তু হচ্ছে
const int mymax_var=100
আপনি করতে পারেন printf("address of constant is %p",&mymax_var);
।
আরও স্পষ্ট করে বলতে গেলে, সংজ্ঞাটি প্রাক-প্রক্রিয়াজাতকরণের পর্যায়ে তার মান দ্বারা প্রতিস্থাপিত হয়, সুতরাং আমাদের প্রোগ্রামে কোনও পরিবর্তনশীল নেই stored আমাদের কাছে প্রোগ্রামটির পাঠ্য বিভাগের কেবল কোড রয়েছে যেখানে সংজ্ঞাটি ব্যবহৃত হয়েছিল।
তবে, স্ট্যাটিক কনস্টের জন্য আমাদের একটি ভেরিয়েবল রয়েছে যা কোথাও বরাদ্দ করা হয়েছে। জিসিসির জন্য, স্ট্যাটিক কনস্টামটি প্রোগ্রামের পাঠ্য বিভাগে বরাদ্দ করা হয়।
উপরে, আমি রেফারেন্স অপারেটর সম্পর্কে বলতে চাই তাই রেফারেন্স সহ dereferences প্রতিস্থাপন।
const
কোয়ালিফায়ারের জন্য খুব আলাদা শব্দার্থকতা রয়েছে । সি -তে এনাম-কনস্ট্যান্ট ছাড়া অন্য কোনও প্রতীকিকা ধ্রুবক নেই । ক const int
একটি পরিবর্তনশীল। আপনি ভাষা এবং নির্দিষ্ট প্রয়োগগুলি গুলিয়ে ফেলেন। বস্তুটি কোথায় রাখার কোনও প্রয়োজন নেই। এবং এটি জিসিসির ক্ষেত্রেও সত্য নয়: সাধারণত এটি বিভাগে const
যোগ্য ভেরিয়েবল রাখে .rodata
। তবে এটি নির্ভর করে লক্ষ্য প্ল্যাটফর্মের উপর। এবং আপনি বোঝাচ্ছেন অ্যাড্রেস অফ অপারেটর &
।
আমরা এমবিএফ 16 এক্স-তে উত্পাদিত এসেম্বলারের কোডটির দিকে চেয়েছিলাম ... উভয় রূপগুলি পাটিগণিত ক্রিয়াকলাপের জন্য একই কোডের ফলাফল দেয় (উদাহরণস্বরূপ এডিডি তাত্ক্ষণিক)।
তাই পুরানো স্টাইলের const int
সময় টাইপ চেকের জন্য পছন্দ করা হয় #define
। সম্ভবত এটি সংকলক-নির্দিষ্ট is সুতরাং আপনার উত্পাদিত এসেম্বলারের কোডটি পরীক্ষা করুন।
আমি ঠিক আছি কিনা তা নিশ্চিত নই তবে আমার মতামতটিতে in #define
d মান কল করা অন্য যে কোনও সাধারণভাবে ঘোষিত ভেরিয়েবল (বা কনস্ট মান) কল করার চেয়ে অনেক দ্রুত। এটি কারণ যখন প্রোগ্রাম চলমান থাকে এবং কিছু সাধারণভাবে ঘোষিত ভেরিয়েবল ব্যবহার করা দরকার তখন সেই পরিবর্তনশীলটি পেতে মেমরির যথাযথ স্থানে যেতে হবে।
বিপরীতে যখন এটি #define
ডি মান ব্যবহার করে , প্রোগ্রামটিকে কোনও বরাদ্দকৃত মেমোরিতে ঝাঁপ দেওয়ার প্রয়োজন হয় না, এটি কেবল মান নেয়। যদি #define myValue 7
এবং প্রোগ্রামটি কল করে myValue
, এটি ঠিক যখন ডেকেছে ঠিক একইরকম আচরণ করে 7
।