উত্তর:
এগুলি হুবহু সমতুল্য। তবে, ইন
int *myVariable, myVariable2;
এটি সুস্পষ্ট myVariable আছে টাইপ মনে হয় int- * , যখন myVariable2 টাইপ হয়েছে int- এ । ভিতরে
int* myVariable, myVariable2;
এটি উভয়ই টাইপ ইন্ট * এর মতো বলে সুস্পষ্ট বলে মনে হতে পারে তবে myVariable2
টাইপ ইন্টের মতো এটি সঠিক নয় ।
অতএব, প্রথম প্রোগ্রামিং শৈলী আরও স্বজ্ঞাত।
int* someVar
ব্যক্তিগত প্রকল্পগুলির সাথে যুক্ত আছি । এটি আরও বোধগম্য হয়।
int[10] x
। এটি কেবল সি এর বাক্য গঠন নয়। ব্যাকরণটি স্পষ্টভাবে পার্স করে:: int (*x)
এবং হিসাবে নয় (int *) x
, তাই বামদিকে তারকাচিহ্ন স্থাপন করা কেবল বিভ্রান্তিকর এবং সি ডিক্লেয়ারেশন সিনট্যাক্সের একটি ভুল বোঝাবুঝির উপর ভিত্তি করে।
int* myVariable; int myVariable2;
পরিবর্তে করেন তবে একেবারেই কোনও বিভ্রান্তি নেই ।
আপনি যদি এটি অন্য কোনও উপায়ে দেখে থাকেন তবে তা *myVariable
টাইপের int
, যা কিছুটা বোধগম্য।
myVariable
NULL হতে পারে, *myVariable
এক্ষেত্রে সেগমেন্টেশন ত্রুটি সৃষ্টি করে তবে কোনও প্রকার NULL নেই।
int x = 5; int *pointer = &x;
কারণ এটি সুপারিশ করে যে আমরা *pointer
কিছুটা মান নির্ধারণ করি না, pointer
নিজেই।
কারণ সেই লাইনের * প্রকারের চেয়ে চলকটির সাথে আরও ঘনিষ্ঠভাবে আবদ্ধ হয়:
int* varA, varB; // This is misleading
@ লন্ডিন নীচে উল্লেখ করেছেন, কনস্ট আরও কিছু সূক্ষ্মতা যুক্ত করেছে। আপনি প্রতি লাইন প্রতি একটি ভেরিয়েবল ঘোষণা করে এটি পুরোপুরি পাশ কাটাতে পারেন, যা কখনই অস্পষ্ট নয়:
int* varA;
int varB;
স্পষ্ট কোড এবং সংক্ষিপ্ত কোডের মধ্যে ভারসাম্য রোধ করা শক্ত - এক ডজন অপ্রয়োজনীয় লাইন এর লাইনও int a;
ভাল নয়। তবুও, আমি প্রতি লাইনে একটি ঘোষণায় ডিফল্ট এবং পরে কোড সংমিশ্রণ করার বিষয়ে চিন্তা করি।
int *const a, b;
। * "বাঁধাই" কোথায়? প্রকারটি a
হ'ল int* const
, সুতরাং আপনি কীভাবে বলতে পারেন যে * যখন এটি টাইপের অংশ হয় তখন এটি ভেরিয়েবলের হয়?
এখনও অবধি এখানে কেউ কিছু উল্লেখ করেনি তা হ'ল এই নক্ষত্রটি আসলে সি এর " ডিরিফারেন্স অপারেটর " is
*a = 10;
উপরের লাইনটির অর্থ এই নয় যে আমি বরাদ্দ 10
করতে চাই a
, এর অর্থ 10
মেমরির অবস্থান যা নির্দিষ্ট করে তা আমি নির্ধারণ করতে চাই a
। আর কাউকে লিখতে দেখিনি
* a = 10;
তোমার আছে? সুতরাং ডেরেফারেন্স অপারেটর প্রায় সবসময় একটি স্থান ছাড়া লেখা হয়। এটি সম্ভবত এটি একাধিক লাইনে বিভক্ত একটি গুণ থেকে আলাদা করতে পারে:
x = a * b * c * d
* e * f * g;
এখানে *e
বিভ্রান্তিকর হবে, তাই না?
ঠিক আছে, এখন নীচের লাইনের আসলে কী বোঝায়:
int *a;
বেশিরভাগ লোক বলতেন:
এর অর্থ হ'ল এটি a
একটি int
মানের পয়েন্টার ।
এটি প্রযুক্তিগতভাবে সঠিক, বেশিরভাগ লোকেরা এটি দেখতে / পড়তে পছন্দ করে এবং এটি আধুনিক সি স্ট্যান্ডার্ডগুলি কীভাবে এটি সংজ্ঞায়িত করবে (নোট করুন যে ভাষা সি নিজেই সমস্ত এএনএসআই এবং আইএসও মানকে পূর্বাভাস দেয়)। তবে এটি দেখার একমাত্র উপায় এটি নয়। আপনি এই লাইনটি নিম্নরূপ পড়তে পারেন:
এর dereferencesd মান a
টাইপ হয় int
।
সুতরাং প্রকৃতপক্ষে এই ঘোষণাপত্রে নক্ষত্রটিকে একটি অবৈধ অপারেটর হিসাবেও দেখা যেতে পারে, যা এর স্থান নির্ধারণের ব্যাখ্যাও দেয়। এবং এটি a
হ'ল একটি পয়েন্টারটি আসলেই ঘোষিত হয় না, এটি প্রকৃতপক্ষে ঘোষিত হয় যে আপনি কেবলমাত্র অবলম্বন করতে পারেন কেবলমাত্র পয়েন্টার।
সি স্ট্যান্ডার্ড *
অপারেটরের কাছে কেবল দুটি অর্থ সংজ্ঞা দেয় :
এবং নির্দেশনা কেবল একটি একক অর্থ, পয়েন্টার ঘোষণার জন্য কোনও অতিরিক্ত অর্থ নেই, কেবলমাত্র নির্দেশনা রয়েছে, যা ডেরেফারেন্স অপারেশনটি করে, এটি একটি পরোক্ষ অ্যাক্সেস সম্পাদন করে, সুতরাং int *a;
এই জাতীয় বিবৃতিতেও একটি পরোক্ষ প্রবেশাধিকার ( *
মানে অপ্রত্যক্ষ অ্যাক্সেস) এবং সুতরাং উপরের দ্বিতীয় বিবৃতিটি মানটির তুলনায় প্রথমটির তুলনায় অনেক বেশি কাছাকাছি।
int a, *b, (*c)();
"নীচের বিষয়গুলি যেমন ঘোষণা করুন int
: অবজেক্ট a
, অবজেক্টটি ইশারা করে b
এবং অবজেক্টটি ফাংশন দ্বারা নির্দেশিত c
" দ্বারা এমন কিছু হিসাবে পড়ি ।
*
মধ্যে int *a;
একটি অপারেটর নয়, এবং এটি dereferencing করা হয় না a
(যা এমনকি এখনো সংজ্ঞায়িত করা হয় না)
*
(এটা না, মোট অভিব্যক্তি একমাত্র একটি অর্থ দেয় *
অভিব্যক্তি মধ্যে!)। এটি বলে যে "int a;" একটি পয়েন্টার, যা এটা আছে, অন্যথায় না বলে দাবি করেন, কিন্তু একটি অর্থ দেওয়া ছাড়া ঘোষণা *
, যেমন * এর dereferenced মান এটা পড়া a
কোন int , যে একই তথ্যসংক্রান্ত অর্থ এখনও সম্পূর্ণভাবে বৈধ। কিছুই নয়, 6..7..6.১ তে লিখিত কিছু কিছুই এই বক্তব্যের বিরোধিতা করবে না।
int *a;
একটি ঘোষণা, একটি অভিব্যক্তি নয়। a
দ্বারা dereferences হয় না int *a;
। a
এমনকি *
প্রক্রিয়াটি হচ্ছে পয়েন্টে এখনও উপস্থিত নেই । আপনি কি মনে করেন যে int *a = NULL;
এটি একটি বাগ কারণ এটি একটি নাল পয়েন্টারকে অবজ্ঞা করে?
আমি এখানে অবয়ব বেরিয়ে যান এবং বলে যে যাচ্ছি এই প্রশ্নের সোজা উত্তর হল সেখানে পরিবর্তনশীল ঘোষণা এবং পরামিতি এবং বিনিময়ে ধরনের জন্য উভয়, যা যে তারকাচিহ্ন নামের পাশে যেতে হবে: int *myVariable;
। কেন তা বোঝার জন্য, আপনি কীভাবে সিতে অন্যান্য ধরণের প্রতীক ঘোষণা করেন তা দেখুন:
int my_function(int arg);
একটি ফাংশন জন্য;
float my_array[3]
একটি অ্যারের জন্য।
সাধারণ প্যাটার্ন, যা ঘোষণাপত্র হিসাবে ব্যবহারের অনুসরণ হিসাবে উল্লেখ করা হয় তা হ'ল একটি চিহ্নের প্রকারটি নামের আগে অংশ এবং নামের আশেপাশের অংশগুলিতে বিভক্ত হয় এবং নামের আশেপাশের এই অংশগুলি সিনট্যাক্সের নকল করে যা আপনি ব্যবহার করতে চান বাম দিকে টাইপের মান:
int a_return_value = my_function(729);
float an_element = my_array[2];
এবং: int copy_of_value = *myVariable;
।
সি ++ রেফারেন্স সহ কাজগুলিতে একটি স্প্যানার ছুড়ে দেয় কারণ আপনি যে বিন্দুতে রেফারেন্স ব্যবহার করেন সেই বিন্দুটি মান ধরণের ধরণের সমতুল্য, তাই আপনি যুক্তি দিতে পারেন যে সি ++ সি এর জন্য আলাদা পদ্ধতির গ্রহণ করে অন্যদিকে, সি ++ একই বজায় রাখে পয়েন্টারগুলির ক্ষেত্রে সি এর আচরণ, সুতরাং উল্লেখগুলি সত্যই এই সম্মানের ক্ষেত্রে বিজোড় হিসাবে দাঁড়িয়েছে।
এটি কেবল পছন্দের বিষয়।
আপনি যখন কোডটি পড়েন তখন দ্বিতীয় ক্ষেত্রে ভেরিয়েবল এবং পয়েন্টারগুলির মধ্যে পার্থক্য করা সহজ, তবে আপনি যখন কোনও একক লাইনে ভেরিয়েবল এবং একটি সাধারণ ধরণের পয়েন্টার উভয়ই রাখেন তখন বিভ্রান্তির সৃষ্টি হতে পারে (যা প্রায়শই প্রকল্পের নির্দেশিকা দ্বারা নিরুৎসাহিত হয়, কারণ পাঠযোগ্যতা হ্রাস পায়)।
আমি সংখ্যার সাথে টাইপ নামের সাথে সম্পর্কিত সংকেত দিয়ে পয়েন্টারগুলি ঘোষণা করতে পছন্দ করি
int* pMyPointer;
একজন মহান গুরু একবার বলেছিলেন "এটি সংকলকের উপায়টি পড়ুন, আপনার অবশ্যই হবে।"
http://www.drdobbs.com/conversationsa-midsummer-nights-madness/184403835
মঞ্জুরি দেওয়া হয়েছে এটি কনস্ট প্লেসমেন্টের বিষয়টিতে ছিল তবে এখানে একই বিধি প্রযোজ্য।
সংকলক এটি পড়েন:
int (*a);
যেমন না:
(int*) a;
আপনি যদি ভেরিয়েবলের পাশে তারকা রাখার অভ্যাসে পড়ে থাকেন তবে এটি আপনার ঘোষণাগুলি পড়তে সহজ করে তুলবে। এটি চোখের পাতাকে এড়ানো যেমন:
int* a[10];
- সম্পাদনা করুন -
ঠিক ব্যাখ্যা আমি কি বলতে চাচ্ছি যখন আমি বলতে এটা পার্স এর int (*a)
, তার মানে যে *
আরও অনেক কিছু শক্তভাবে বেঁধে a
চেয়ে এটা আছে করার int
, খুব পদ্ধতিতে যে এক্সপ্রেশনে 4 + 3 * 7
3
আরও অনেক কিছু শক্তভাবে বেঁধে 7
চেয়ে এটা আছে করার 4
উচ্চতর প্রাধান্য কারণে *
।
এসকি শিল্পের জন্য ক্ষমা চেয়ে, পার্সিংয়ের জন্য এএসটির একটি সংক্ষিপ্ত বিবরণ int *a
মোটামুটি এরকম দেখাচ্ছে:
Declaration
/ \
/ \
Declaration- Init-
Secifiers Declarator-
| List
| |
| ...
"int" |
Declarator
/ \
/ ...
Pointer \
| Identifier
| |
"*" |
"a"
যেমনটি পরিষ্কারভাবে দেখানো হয়েছে, তাদের সাধারণ পূর্বপুরুষ যেহেতু *
আরও দৃly়ভাবে বাঁধেন , আপনি যখন জড়িত তখন একটি সাধারণ পূর্বপুরুষের সন্ধানের জন্য গাছের উপরে যেতে হবে ।a
Declarator
Declaration
int
(int*) a
।
int
এক্ষেত্রে. পদক্ষেপ 2. কোনও প্রকার সজ্জা সহ একটি ঘোষণা পড়ুন। *a
এক্ষেত্রে. পদক্ষেপ 3 পরবর্তী অক্ষর পড়ুন। যদি কমা হয় তবে এটি গ্রহণ করুন এবং ২ য় ধাপে ফিরে যান se যদি সেমিকোলন বন্ধ হয়ে যায়। অন্য কিছু যদি একটি সিনট্যাক্স ত্রুটি নিক্ষেপ করে। ...
int* a, b;
এবং পয়েন্টারগুলির একটি জোড়া পেতে সক্ষম হব । আমি যে বিন্দুটি তৈরি করছি তা হ'ল *
ভেরিয়েবলের সাথে বাঁধাই এবং এটি দিয়ে পার্স করা হয়, ঘোষণার "বেস টাইপ" গঠনের ধরণের সাথে নয়। এটি বেশ typedef int *iptr;
iptr a, b;
কয়েকটি পয়েন্টার তৈরি করতে টাইপেইফগুলি চালু করার কারণটিরও একটি অংশ । একটি typedef ব্যবহার করে আপনি করতে পারেন বাঁধে *
করতে int
।
Declaration-Specifier
"সজ্জা" সহ বেস টাইপটিকে "সংযুক্ত" করে Declarator
। তবে এটি সজ্জাটিকে ঘোষণাপত্রের স্পেসিফায়ারে "সরানো" না করে অন্যথায় int a[10], b;
সম্পূর্ণ হাস্যকর ফলাফল আনবে, এটি পার্স int *a, b[10];
করে int
*a
,
b[10]
;
। এটি বোঝার জন্য অন্য কোনও উপায় নেই that
int*a
শেষের ধরণটি সংকলক দ্বারা শেষ পর্যন্ত পড়তে হবে: " a
টাইপ আছে int*
"। আমার আসল মন্তব্যে এটাই বোঝা গেল।
কারণ আপনার যখন ঘোষণাগুলি থাকে তখন এটি আরও অর্থবোধ করে:
int *a, *b;
int* a, b;
প্রণীত b
একটি পয়েন্টার int
। কিন্তু তারা তা করেনি। এবং সঙ্গত কারণ সঙ্গে। আপনার প্রস্তাবিত ব্যবস্থায় ধরণ কি b
নিম্নলিখিত ঘোষণায়: int* a[10], b;
?
এক লাইনে একাধিক পয়েন্টার ঘোষণার জন্য, আমি পছন্দ করি int* a, * b;
কোনটি আরও স্বজ্ঞাতভাবে একটি পূর্ণসংখ্যার পয়েন্টার হিসাবে "a" ঘোষণা করে এবং একইভাবে "বি" ঘোষণা করার সাথে শৈলীর মিশ্রণ হয় না। যেমন কেউ বলেছেন, আমি একই বিবৃতিতে যাইহোক দুটি ভিন্ন ধরণের ঘোষণা করব না।
যে সমস্ত ব্যক্তিরা পছন্দ করেন int* x;
তারা তাদের কোডটি একটি কাল্পনিক বিশ্বে জোর করার চেষ্টা করছেন যেখানে টাইপটি বাম দিকে রয়েছে এবং সনাক্তকারী (নাম) ডানদিকে রয়েছে।
আমি "কাল্পনিক" বলি কারণ:
সি এবং সি ++ এ, সাধারণ ক্ষেত্রে, ঘোষিত শনাক্তকারী ধরণের তথ্য দ্বারা ঘিরে থাকে।
এটি পাগল মনে হতে পারে, তবে আপনি এটি সত্য জানেন। এখানে কিছু উদাহরন:
int main(int argc, char *argv[])
মানে " main
এমন একটি ফাংশন যা int
একটিতে পয়েন্টারগুলির একটি অ্যারে নিয়ে যায় char
এবং একটিকে ফেরত দেয় int
" " অন্য কথায়, বেশিরভাগ টাইপের তথ্য ডানদিকে থাকে। কিছু লোক মনে করে যে ফাংশন ঘোষণাগুলি গণনা করা হয় না কারণ তারা কোনওভাবে "বিশেষ"। ঠিক আছে, আসুন একটি ভেরিয়েবল চেষ্টা করি।
void (*fn)(int)
মানে fn
এমন কোনও ফাংশনের পয়েন্টার যা একটি নেয় int
এবং কিছুই দেয় না।
int a[10]
10 এ int
এর অ্যারে হিসাবে 'এ' ঘোষণা করে ।
pixel bitmap[height][width]
।
স্পষ্টতই, আমি চেরি-বাছাই করা উদাহরণগুলি পেয়েছি যেগুলিতে আমার বক্তব্যটি বানাতে ডানদিকে প্রচুর তথ্য রয়েছে। এমন অনেকগুলি ঘোষণা রয়েছে যেখানে বেশিরভাগ - যদি না হয় তবে - টাইপটি বাম দিকে থাকে, যেমন struct { int x; int y; } center
।
এই ঘোষণার বাক্য গঠনটি কে ও আর-এর ঘোষণাগুলির ব্যবহারের প্রতিফলনের আকাঙ্ক্ষার কারণে বেড়েছে। সাধারণ ঘোষণাপত্রগুলি পড়া স্বজ্ঞাত, এবং আরও জটিলগুলি পড়া ডান-বাম-ডান নিয়ম শিখার মাধ্যমে আয়ত্ত করা যায় (কখনও কখনও সর্পিল নিয়ম বা ডান-বাম নিয়মকে কল করুন)।
সি যথেষ্ট সহজ যে অনেক সি প্রোগ্রামাররা এই স্টাইলটি আলিঙ্গন করে এবং হিসাবে সাধারণ ঘোষণাপত্র লেখেন int *p
।
সি ++ তে সিনট্যাক্সটি আরও কিছুটা জটিল হয়ে উঠল (ক্লাস, রেফারেন্স, টেম্পলেট, এনাম ক্লাস সহ) এবং সেই জটিলতার প্রতিক্রিয়া হিসাবে আপনি অনেক ঘোষণাপত্রে শনাক্তকারী থেকে প্রকারটি আলাদা করতে আরও প্রচেষ্টা দেখতে পাবেন। অন্য কথায়, আপনি int* p
যদি সি ++ কোডের একটি বৃহত সোয়াথ পরীক্ষা করে দেখে থাকেন তবে স্টাইলের আরও ঘোষণা দেখতে পাবেন ।
পারেন ভাষা, আপনি করতে পারেন সবসময় বামদিকে প্রকার থাকা পরিবর্তনশীল দ্বারা ঘোষণা (1) কখনও একই বিবৃতিতে একাধিক ভেরিয়েবল ঘোষণা, এবং (2) ব্যবহার করে typedef
গুলি (বা ওরফে ঘোষণা, যা, ব্যঙ্গ করে ওরফে করা প্রকারের বামে শনাক্তকারী)। উদাহরণ স্বরূপ:
typedef int array_of_10_ints[10];
array_of_10_ints a;
(*fn)
পয়েন্টারটি fn
রিটার্নের ধরণের পরিবর্তে যুক্ত রাখে ।
আমি ইতিমধ্যে সিপিতে অনুরূপ প্রশ্নের জবাব দিয়েছি, এবং, কারণ এটির কথা কেউ উল্লেখ করেনি, এখানেও আমাকে এখানে উল্লেখ করতে হবে যে সি একটি মুক্ত বিন্যাসের ভাষা , আপনি যে স্টাইলটি বেছে নিচ্ছেন যখন পার্সার প্রতিটি টোকেনের পার্থক্য করতে পারে। সি এর এই অদ্ভুততা একটি খুব বিশেষ ধরণের প্রতিযোগিতার দিকে নিয়ে যায় যা সি অবফসেশন প্রতিযোগিতা বলে ।
এই বিষয়টিতে প্রচুর যুক্তি সরল বিষয়গত এবং "তারাটি পরিবর্তনশীল নামের সাথে বাঁধা" সম্পর্কে যুক্তিটি নিষ্পাপ na এখানে কয়েকটি যুক্তি যা কেবল মতামত নয়:
ভুলে যাওয়া পয়েন্টার ধরণের যোগ্যতা
আনুষ্ঠানিকভাবে, "তারা" না কোনও প্রকারের বা ভেরিয়েবল নামের সাথে সম্পর্কিত, এটি পয়েন্টার নামক নিজস্ব ব্যাকরণগত আইটেমের অংশ । আনুষ্ঠানিক সি সিনট্যাক্স (আইএসও 9899: 2018) হ'ল:
(7.7) ঘোষণা:
ঘোষণাপত্র-সুনির্দিষ্ট সূচনা-ঘোষক-তালিকার বিকল্প;
যেখানে ডিক্লেয়ারেশন-স্পেসিফায়ারে টাইপ (এবং স্টোরেজ) থাকে এবং আরআর-ডিক্লেয়ার-তালিকায় পয়েন্টার এবং ভেরিয়েবলের নাম থাকে। আমরা যদি দেখি যে আমরা এই ঘোষণাকারী তালিকার সিনট্যাক্সটি আরও ছড়িয়ে দিই:
(7.7..6) ঘোষক:
পয়েন্টার অপ্ট সরাসরি-ঘোষক
...
(7.7.ter) পয়েন্টার:
*
টাইপ-কোয়ালিফায়ার-তালিকা অপ্ট
*
টাইপ-কোয়ালিফায়ার-তালিকা অপ্ট পয়েন্টার
যেখানে কোনও ঘোষক পুরো ঘোষণা, সরাসরি ঘোষক হ'ল শনাক্তকারী (পরিবর্তনশীল নাম) এবং পয়েন্টারটি তারা হয় তারপরে পয়েন্টারের সাথে সম্পর্কিত একটি alচ্ছিক ধরণের যোগ্যতা অর্জনকারী তালিকা।
"তারকাটি চলকটির সাথে সম্পর্কিত" সম্পর্কে বিভিন্ন স্টাইলের যুক্তিগুলি কী অসামঞ্জস্য করে তোলে তা হ'ল তারা এই পয়েন্টার ধরণের যোগ্যতা সম্পর্কে ভুলে গেছেন। int* const x
, int *const x
বা int*const x
?
বিবেচনা করুন int *const a, b;
, প্রকার ও কি কি a
এবং b
? "তারকাটি ভেরিয়েবলের অন্তর্ভুক্ত" এতটা স্পষ্ট নয় " পরিবর্তে, এক যেখানে বিবেচনা করতে শুরু করবে const
।
আপনি অবশ্যই একটি দৃ argument় আর্গুমেন্ট তৈরি করতে পারেন যে তারকাটি পয়েন্টার ধরণের কোয়ালিফায়ার সম্পর্কিত, তবে এর বেশি নয়।
পয়েন্টারের জন্য টাইপ যোগ্যতা অর্জনকারী তালিকাটি int *a
শৈলী ব্যবহার করে তাদের জন্য সমস্যা তৈরি করতে পারে । যারা একটি typedef
(যা আমাদের খুব খারাপ অনুশীলন করা উচিত নয়!) এর ভিতরে পয়েন্টার ব্যবহার করে এবং "তারাটি পরিবর্তনশীল নামের সাথে সম্পর্কিত" বলে মনে করে তারা খুব সূক্ষ্ম বাগটি লিখতে ঝোঁক:
/*** bad code, don't do this ***/
typedef int *bad_idea_t;
...
void func (const bad_idea_t *foo);
এটি পরিষ্কারভাবে সংকলন করে। এখন আপনার মনে হতে পারে কোডটি সঠিকভাবে করা হয়েছে। তাই না! এই কোডটি দুর্ঘটনাক্রমে একটি নকল দৃ const়তা।
প্রকারটি foo
আসলে int*const*
- বাইরের সর্বাধিক পয়েন্টারটি কেবল পঠনযোগ্য তৈরি হয়েছিল, ডেটা এট পয়েন্ট নয়। সুতরাং এই ফাংশনের ভিতরে আমরা করতে পারি **foo = n;
এবং এটি কলারের পরিবর্তনশীল মান পরিবর্তন করবে।
এর কারণ হল অভিব্যক্তিতে const bad_idea_t *foo
, *
এখানে পরিবর্তনশীল নামের সাথে সম্পর্কিত নয়! সিউডো কোডে, এই পরামিতি ঘোষণাটি পড়তে হয় const (bad_idea_t *) foo
এবং হিসাবে হয় না(const bad_idea_t) *foo
। তারকা জন্যে এই ক্ষেত্রে গোপন পয়েন্টার টাইপ - টাইপ একটি পয়েন্টার এবং একটি const-যোগ্যতাসম্পন্ন পয়েন্টার হিসেবে লেখা হয় *const
।
কিন্তু তারপর উপরোক্ত উদাহরণের সমস্যার মূল একটি পিছনে লুকিয়ে পয়েন্টার অভ্যাস typedef
এবং *
শৈলী।
একক লাইনে একাধিক ভেরিয়েবল ঘোষণার বিষয়ে
একক লাইনে একাধিক ভেরিয়েবল ঘোষণা করা খারাপ অভ্যাস 1) হিসাবে ব্যাপকভাবে স্বীকৃত । সিইআরটি-সি এটিকে সুন্দরভাবে যোগ করে:
DCL04-সি। ঘোষণাপত্রে একাধিক ভেরিয়েবল ঘোষণা করবেন না
শুধু পড়া ইংরেজি, তারপর সাধারণ জ্ঞান সম্মত হয় যে একটি ঘোষণা হওয়া উচিত এক ঘোষণা।
এবং ভেরিয়েবলগুলি পয়েন্টার হয় কিনা তা বিবেচ্য নয়। একক লাইনে প্রতিটি ভেরিয়েবল ঘোষণা করা কোডকে প্রায় প্রতিটি ক্ষেত্রেই পরিষ্কার করে দেয়।
সুতরাং প্রোগ্রামার সম্পর্কে বিভ্রান্ত হওয়ার int* a, b
বিষয়ে তর্কটি খারাপ। সমস্যার মূলটি হ'ল একাধিক ডিক্লেয়ারার ব্যবহার, এর স্থান নির্ধারণ নয় *
। শৈলী নির্বিশেষে, আপনি পরিবর্তে এটি লিখতে হবে:
int* a; // or int *a
int b;
আর একটি শব্দযুক্ত কিন্তু বিষয়গত যুক্তিটি হ'ল int* a
যে ধরণের প্রকারটি a
প্রশ্নবিদ্ধ নয় int*
এবং তাই তারা এই টাইপের বাছাইয়ের সাথে সম্পর্কিত।
তবে মূলত আমার উপসংহারটি হ'ল এখানে পোস্ট করা যুক্তিগুলির অনেকগুলি কেবল বিষয়গত এবং নিষ্পাপ। আপনি উভয় শৈলীর জন্য সত্যই একটি বৈধ তর্ক করতে পারবেন না - এটি সত্যই বিষয়গত ব্যক্তিগত পছন্দের বিষয়।
typedef int *bad_idea_t;
void func(const bad_idea_t bar);
তবে মহান নবী ড্যান সাকস শেখানোর বিষয়টির একটি সংক্ষিপ্ত বিভাগ রয়েছে "যদি আপনি const
শব্দার্থক অর্থ পরিবর্তন না করে সর্বদা যথাসম্ভব ডানদিকে রাখেন" এটি সম্পূর্ণভাবে বন্ধ হয়ে যায় একটি ইস্যু হতে। এটি আপনার const
ঘোষণাগুলি পড়ার ক্ষেত্রে আরও সুসংগত করে তোলে । "কনস্ট শব্দের ডানদিকের সমস্ত কিছু যা কনস্টেন্ট, বামে সমস্ত কিছু তার টাইপ।" এটি একটি ঘোষণায় সমস্ত কনসেটের জন্য প্রযোজ্য। এটি ব্যবহার করে দেখুনint const * * const x;
বিবেচনা
int *x = new int();
এটি অনুবাদ করে না
int *x;
*x = new int();
এটি আসলে অনুবাদ করে
int *x;
x = new int();
এটি int *x
স্বরলিপি কিছুটা বেমানান করে তোলে ।
new
একটি সি ++ অপারেটর। তাঁর প্রশ্নটিকে "সি" ট্যাগ করা হয়েছে, "সি ++" নয়।
typedefs
তবে এটি অপ্রয়োজনীয় জটিলতা যুক্ত করবে, আইএমএইচও।