NULL এ সি পয়েন্টার শুরু করা কি সম্ভব?


90

আমি যেমন জিনিস লিখতে ছিল

char *x=NULL;

অনুমান যে

 char *x=2;

charঠিকানা 2 একটি পয়েন্টার তৈরি করবে ।

তবে, জিএনইউ সি প্রোগ্রামিং টিউটোরিয়ালে এটি বলেছে যে এলোমেলো করার সময় এলোমেলো ঠিকানায় যা থাকে int *my_int_ptr = 2;তার পূর্ণসংখ্যার মান সংরক্ষণ 2করে my_int_ptr

এর থেকে বোঝা যাচ্ছে যে আমার নিজের char *x=NULLকোনও NULLকাস্টের মান যা charকিছু মেমোরির এলোমেলো ঠিকানার কাছে নির্ধারণ করছে।

যখন

#include <stdlib.h>
#include <stdio.h>

int main()
{
    char *x=NULL;

    if (x==NULL)
        printf("is NULL\n");

    return EXIT_SUCCESS;
}

আসলে, মুদ্রণ করে

NULL হয়

আমি যখন এটি সংকলন এবং চালনা করি তখন আমি উদ্বিগ্ন যে আমি অপরিজ্ঞাত আচরণ, বা কমপক্ষে নিম্ন-নির্ধারিত আচরণের উপর নির্ভর করছি এবং আমার লেখা উচিত

char *x;
x=NULL;

পরিবর্তে.


72
কি int *x = whatever;করে এবং কী int *x; *x = whatever;করে তার মধ্যে একটি বিভ্রান্তিকর পার্থক্য রয়েছে । int *x = whatever;আসলে মত আচরণ করে int *x; x = whatever;, না *x = whatever;
ব্যবহারকারী 2357112 মনিকা 6

78
এই টিউটোরিয়ালটি মনে হয়েছে যে বিভ্রান্তিকর পার্থক্যটি ভুল।
ব্যবহারকারী 2357112 মনিকা 6

51
ওয়েবে অনেক ছিটে টিউটোরিয়াল! তাত্ক্ষণিক পড়া বন্ধ করুন। আমাদের সত্যই এমন একটি ব্ল্যাকলিস্ট দরকার যেখানে আমরা প্রকাশ্যে ক্রেডি বইগুলি লজ্জা দিতে পারি ...
লন্ডিন

9
@ এমএম যা 2017 সালে এটি কম কৃপণ করে না
লন্ডিন

13
আমি মনে করি না এই টিউটোরিয়ালটি " দ্য জিএনইউ সি প্রোগ্রামিং টিউটোরিয়াল" হিসাবে যোগ্যতা অর্জন করেছে ...
মার্শাল

উত্তর:


114

NULL এ সি পয়েন্টার শুরু করা কি সম্ভব?

টিএল; ডিআর হ্যাঁ, খুব বেশি।


প্রকৃত পথ প্রদর্শক উপর দাবি মত সার্চ

অন্যদিকে, আপনি যদি কেবল একক প্রাথমিক অ্যাসাইনমেন্ট ব্যবহার করেন int *my_int_ptr = 2;, প্রোগ্রামটি my_int_ptr2 মান দিয়ে চিহ্নিত মেমরির অবস্থানের বিষয়বস্তু পূরণ করার চেষ্টা করবে, যেহেতু my_int_ptrআবর্জনায় ভরাট, এটি কোনও ঠিকানা হতে পারে। [...]

ওয়েল, তারা হয় ভুল, আপনি ঠিক।

বিবৃতিটির জন্য, ( আপাতত উপেক্ষা করে, পূর্ণসংখ্যার রূপান্তরকে নির্দেশকারী একটি বাস্তবায়ন-সংজ্ঞায়িত আচরণ )

int * my_int_ptr = 2;

my_int_ptrএকটি ভেরিয়েবল (টাইপ পয়েন্টার টু টু int), এর নিজস্ব একটি ঠিকানা রয়েছে (টাইপ: ইন্ডিটারের দিকে নির্দেশকের ঠিকানা), আপনি সেই ঠিকানার 2মধ্যে একটি মান সংরক্ষণ করছেন ।

এখন, my_int_ptrএকটি পয়েন্টার টাইপ হচ্ছে, আমরা তা বলতে পারেন, যে স্থানটিকে মেমরির অবস্থানে "টাইপ" -র মান দ্বারা নির্দিষ্ট অনুষ্ঠিত মান my_int_ptr। সুতরাং, আপনি মূলত মান বরাদ্দ করা হয় এর পয়েন্টার ভেরিয়েবল, না মেমরি অবস্থানকে মান পয়েন্টার দ্বারা দিকে ইঙ্গিত করলেন।

সুতরাং, উপসংহার জন্য

 char *x=NULL;

সূচনা পয়েন্টার ভেরিয়েবল xথেকে NULL, না মেমরি অ্যাড্রেস মান পয়েন্টার দ্বারা প্রতি ইঙ্গিত

এই হিসাবে একই

 char *x;
 x = NULL;    

সম্প্রসারণ:

এখন, কঠোরভাবে অনুসরণ করা হচ্ছে, একটি বিবৃতি মত

 int * my_int_ptr = 2;

এটি অবৈধ, কারণ এতে সীমাবদ্ধতা লঙ্ঘন জড়িত। স্পষ্ট করা,

  • my_int_ptr একটি পয়েন্টার ভেরিয়েবল, টাইপ int *
  • সংজ্ঞা অনুসারে একটি পূর্ণসংখ্যা ধ্রুবক 2এর টাইপ থাকে int

এবং সেগুলি "সামঞ্জস্যপূর্ণ" ধরণের নয়, সুতরাং লন্ডিনের উত্তরে বর্ণিত অধ্যায় §6.5.16.1 / পি 1 এ উল্লিখিত সহজ কার্যনির্বাহী বিধি লঙ্ঘন করার কারণে এই সূচনাটি অবৈধ ।

যদি কারও আগ্রহী যে কীভাবে C11সূচনাটি সহজ নিয়োগের সীমাবদ্ধতার সাথে উদ্ধৃত করা হয় , অধ্যায় §6.7.9, পি 11

স্কেলারের জন্য ইনিশিয়ালাইজারটি একটি একক অভিব্যক্তি হবে option অবজেক্টের প্রাথমিক মান হ'ল অভিব্যক্তি (রূপান্তরের পরে); সাধারণ অ্যাসাইনমেন্ট হিসাবে একই ধরণের বাধা এবং রূপান্তরগুলি প্রয়োগ করে, স্কেলারের প্রকারটিকে তার ঘোষিত প্রকারের অযোগ্য সংস্করণ হিসাবে গ্রহণ করে।


@ Random832n তারা হয় ভুল। আমি আমার উত্তরে সম্পর্কিত অংশটি উদ্ধৃত করেছি, অন্যথায় দয়া করে আমাকে সংশোধন করুন। ওহ, এবং ইচ্ছাকৃতভাবে জোর দেওয়া।
সৌরভ ঘোষ

"... এটি অবৈধ, কারণ এতে সীমাবদ্ধতা লঙ্ঘনের সাথে জড়িত ... সমস্যাযুক্ত। মনে হচ্ছে কারণ 2এটি একটি int, অ্যাসাইনমেন্টটি একটি সমস্যা। তবে এটি তার চেয়েও বেশি। NULLএছাড়াও হতে পারে একটি int, একটি int 0। এটা ঠিক যে char *x = 0;সংজ্ঞায়িত হয় এবং char *x = 2;হয় না। .3.৩.২.৩ পয়েন্টার ৩ (বিটিডাব্লু: সি কোনও পূর্ণসংখ্যার আক্ষরিক সংজ্ঞা দেয় না , কেবল স্ট্রিং আক্ষরিক এবং যৌগিক আক্ষরিক0এটি একটি পূর্ণসংখ্যার ধ্রুবক )
chux -

@ চিচস আপনি খুব সঠিক, তবে কি তা char *x = (void *)0;মেনে চলছেন না ? বা এটি কেবলমাত্র অন্যান্য অভিব্যক্তিগুলির সাথে যা মান দেয় 0?
সৌরভ ঘোষ

10
@ সৌরভঘোষ: মান সহ পূর্ণসংখ্যার ধ্রুবক 0বিশেষ: এগুলি স্পষ্টভাবে সাধারণ পূর্ণসংখ্যার এক্সপ্রেশনকে পয়েন্টার প্রকারে স্পষ্টভাবে কাস্ট করার জন্য সাধারণ নিয়ম থেকে পৃথকভাবে নাল পয়েন্টারে রূপান্তরিত করে।
স্টিভ জেসপ

4
1974-এর সি রেফারেন্স ম্যানুয়াল দ্বারা বর্ণিত ভাষা ঘোষণাগুলি সূচনাপ্রকাশের এক্সপ্রেশনগুলি নির্দিষ্ট করতে দেয়নি এবং এই জাতীয় অভিব্যক্তির অভাব "ঘোষণার আয়নাগুলি ব্যবহার করে" অনেক বেশি ব্যবহারিক করে তোলে। সিনট্যাক্সটি int *p = somePtrExpressionআইএমএইচও বরং ভয়ঙ্কর যেহেতু দেখে মনে হচ্ছে এটির মান নির্ধারণ করা হচ্ছে *pতবে এটি আসলে মান নির্ধারণ করছে p
সুপারক্যাট

53

টিউটোরিয়ালটি ভুল। আইএসও সি- int *my_int_ptr = 2;তে একটি ত্রুটি। জিএনইউ সি তে এর অর্থ একই রকম int *my_int_ptr = (int *)2;2সংকলক দ্বারা নির্ধারিত কোনও ফ্যাশনে এটি পূর্ণসংখ্যাকে একটি মেমরি ঠিকানায় রূপান্তর করে ।

এটি ঠিকানার মাধ্যমে ঠিকানাটিতে কোনও কিছু সংরক্ষণ করার চেষ্টা করে না (যদি থাকে)। আপনি যদি লিখতে যান *my_int_ptr = 5;, তবে এটি 5সেই ঠিকানার দ্বারা চিহ্নিত স্থানে নম্বরটি সংরক্ষণ করার চেষ্টা করবে ।


4
আমি জানতাম না যে পূর্ণসংখ্যা থেকে পয়েন্টার রূপান্তরটি বাস্তবায়ন সংজ্ঞায়িত হয়। তথ্যের জন্য ধন্যবাদ.
টাস্কিনুর

4
@ টাসকিনূর দয়া করে মনে রাখবেন যে এই উত্তরে যেমন আপনি নিক্ষিপ্ত দ্বারা জোর করে থাকেন কেবল তেমন রূপান্তর রয়েছে। কাস্টের জন্য না হলে কোডটি সংকলন করা উচিত নয়।
লন্ডিন

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

17

টিউটোরিয়ালটি কেন ভুল, তা পরিষ্কার করতে int *my_int_ptr = 2;একটি "সীমাবদ্ধতা লঙ্ঘন", এটি এমন কোড যা সংকলনের অনুমতি নেই এবং সংকলকটি অবশ্যই এটির মুখোমুখি হওয়ার পরে আপনাকে একটি ডায়াগনস্টিক দিতে হবে।

.5.৫.১6.১ অনুসারে সাধারণ কার্যনির্বাহী:

সীমাবদ্ধতা

নিম্নলিখিতগুলির মধ্যে একটি হ'ল:

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

এই ক্ষেত্রে বাম অপারেন্ডটি একটি অযোগ্য পয়েন্টার। কোথাও এটি উল্লেখ করা হয়নি যে ডান অপারেণ্ডকে একটি পূর্ণসংখ্যা (পাটিগণিত টাইপ) হওয়ার অনুমতি দেওয়া হয়। সুতরাং কোড সি মান লঙ্ঘন করে।

আপনি যদি স্পষ্টভাবে একটি স্ট্যান্ডার্ড সি সংকলক হিসাবে না বলে থাকেন তবে জিসিসি খারাপ আচরণ করতে পারে। আপনি যদি কোডটি কম্পাইল করেন তবে -std=c11 -pedantic-errorsএটি অবশ্যই ডায়াগনস্টিক হিসাবে দেবে অবশ্যই।


4
-পেনডেন্টিক-ত্রুটিগুলির পরামর্শ দেওয়ার জন্য উন্নত। যদিও আমি সম্ভবত সম্পর্কিত-ওয়ার্ডপ্যান্টিক ব্যবহার করব।
fagricipni

4
আপনার বক্তব্যটির একটি ব্যতিক্রম যে ডান অপারেণ্ডটিকে পূর্ণসংখ্যা হিসাবে মঞ্জুরি দেওয়া হচ্ছে না: বিভাগ 6.3.2.3 বলছে, "মান 0 সহ একটি পূর্ণসংখ্যার ধ্রুবক অভিব্যক্তি, বা টাইপের জন্য যেমন একটি এক্সপ্রেশন কাস্ট করা void *হয় তাকে নাল পয়েন্টার ধ্রুবক বলা হয়।" আপনার উদ্ধৃতিতে দ্বিতীয় থেকে শেষ বুলেট পয়েন্টটি লক্ষ্য করুন। সুতরাং, int* p = 0;লেখার একটি আইনী উপায় int* p = NULL;। যদিও আধুনিকটি আরও পরিষ্কার এবং প্রচলিত।
ডেভিস্লোর

4
যা প্যাথলজিকাল অবহেলা int m = 1, n = 2 * 2, * p = 1 - 1, q = 2 - 1;বৈধ করে তোলে ।
ডেভিস্লোর

@ ডেভিস্লার যা এই উত্তরের স্ট্যান্ডার্ড উদ্ধৃতিতে বুলেট পয়েন্ট 5 দ্বারা আচ্ছাদিত রয়েছে (সম্মত হন যে সংক্ষিপ্তসারটি সম্ভবত এটি উল্লেখ করা উচিত)
এমএম

4
@ chux আমি বিশ্বাস করি একটি সুগঠিত প্রোগ্রামের intptr_tডান হাতের অনুমোদিত ধরণের একটিতে স্পষ্টত রূপান্তর করা দরকার । এটি void* a = (void*)(intptr_t)b;4 নং আইন অনুসারে বৈধ, তবে (intptr_t)bএটি কোনও উপযুক্ত নয় , কোনও পয়েন্টার নয় বা একটি void*, বা নাল পয়েন্টার ধ্রুবক void* aনয় এবং এটি একটি গাণিতিক প্রকারও নয় _Bool। স্ট্যান্ডার্ডটি বলেছে যে রূপান্তর আইনী, তবে এটি অন্তর্নিহিত নয়।
ডেভিস্লোর

15

int *my_int_ptr = 2

যখন এটি বরাদ্দ করা হয় তখন my_int_ptr এ র্যান্ডম ঠিকানা যা হয় তার পূর্ণসংখ্যার মান 2 সঞ্চয় করে।

এটি সম্পূর্ণ ভুল। যদি এটি আসলে লিখিত হয় তবে দয়া করে আরও ভাল বই বা টিউটোরিয়াল পান।

int *my_int_ptr = 2একটি পূর্ণসংখ্যার পয়েন্টারটি সংজ্ঞায়িত করে যা কোন ঠিকানায় নির্দেশ করে ২. আপনি ঠিকানাটি অ্যাক্সেস করার চেষ্টা করলে আপনি সম্ভবত একটি ক্র্যাশ পাবেন 2

*my_int_ptr = 2অর্থাত্ intরেখার বিন্দু ব্যতীত, এলোমেলো ঠিকানা my_int_ptrযা দেখায় তাতে দুটি করে মান সংরক্ষণ করে। এটি বলার পরে, আপনি এটি নির্দিষ্ট NULLকরার সময় কোনও পয়েন্টারকে বরাদ্দ করতে পারেন । char *x=NULL;পুরোপুরি বৈধ সি।

সম্পাদনা: এটি লেখার সময় আমি জানতাম না যে পয়েন্টার রূপান্তরটির পূর্ণসংখ্যার বাস্তবায়ন সংজ্ঞায়িত আচরণ। বিশদ জানতে দয়া করে @ এমএম এবং @ সৌরভঘোষের ভাল উত্তর দেখুন।


4
এটি সম্পূর্ণ ভুল কারণ এটি কোনও বাধা লঙ্ঘন, অন্য কোনও কারণে নয়। বিশেষত, এটি ভুল: "int * my_int_ptr = 2 একটি পূর্ণসংখ্যার পয়েন্টার সংজ্ঞায়িত করে যা 2 ঠিকানাটিকে নির্দেশ করে"।
লন্ডিন

@ লন্ডিন: আপনার বাক্যটি "অন্য কোনও কারণে নয়" নিজেই ভুল এবং বিভ্রান্তিকর। আপনি যদি প্রকারের সামঞ্জস্যতা সমস্যাটি ঠিক করেন তবে আপনি এখনও এই সত্যটি রেখে গেছেন যে টিউটোরিয়ালটির লেখক পয়েন্টার ইনিশিয়েশন এবং অ্যাসাইনমেন্টগুলি কীভাবে কাজ করে তা গুরুতরভাবে উপস্থাপন করছে।
অরবিট

14

সি পয়েন্টারগুলি সম্পর্কে প্রচুর বিভ্রান্তি খুব খারাপ পছন্দ থেকে আসে যা মূলত কোডিং শৈলীর বিষয়ে তৈরি হয়েছিল, ভাষাটির বাক্য গঠনে খুব খারাপ পছন্দ দ্বারা সংশ্লেষিত।

int *x = NULL;সঠিক সি, তবে এটি খুব বিভ্রান্তিকর, আমি এমনকি অযৌক্তিকও বলব, এবং এটি অনেক নবজাতকের কাছে ভাষার বোঝার ক্ষেত্রে বাধা সৃষ্টি করেছে। এটি একজনকে ভাবতে বাধ্য করে যে পরে আমরা তা করতে পারি *x = NULL;যা অবশ্যই অসম্ভব। আপনি দেখতে পাচ্ছেন, ভেরিয়েবলের ধরণটি নয় intএবং ভেরিয়েবলের নামও নয় *x, বা *ঘোষণাপত্রে এর সাথে সহযোগিতায় কোনও কার্যকরী ভূমিকা পালন করে না =। এটি নিখুঁতভাবে ঘোষণামূলক। সুতরাং, যা আরও অনেক কিছু বোঝায় তা হ'ল:

int* x = NULL;যা মূল সিটিও সঠিক, যদিও এটি মূল কে ও আর কোডিং শৈলীর সাথে মানায় না। এটি পুরোপুরি স্পষ্ট করে দেয় যে প্রকারটি int*, এবং পয়েন্টার ভেরিয়েবল x, সুতরাং এটি নির্বিঘ্নে এমনকি স্পষ্টভাবে স্পষ্ট হয়ে যায় যে মানটি NULLসংরক্ষণ করা হচ্ছে xযা একটি পয়েন্টার int

তদ্ব্যতীত, কোনও নিয়ম উত্পন্ন করা সহজ করে তোলে: যখন তারাটি পরিবর্তনশীল নাম থেকে দূরে থাকে তখন এটি একটি ঘোষণা হয়, যখন তারাটির সাথে নামের সাথে সংযুক্ত থাকা পয়েন্টার ডিটারফারেন্স হয়।

সুতরাং, এখন এটি আরও অনেক বেশি বোধগম্য হয়ে উঠেছে যে আমরা আরও নীচে করতে পারি x = NULL;বা *x = 2;অন্য কথায় এটি কোনও নবজাতকের পক্ষে কীভাবে variable = expressionবাড়ে pointer-type variable = pointer-expressionএবং তা কীভাবে দেখায় তা সহজ করে তোলে dereferenced-pointer-variable = expression। (দীক্ষিতদের জন্য, 'এক্সপ্রেশন' দ্বারা আমি 'মূল্যবোধ' বুঝি))

ভাষার সিনট্যাক্সে দুর্ভাগ্যজনক পছন্দটি হ'ল স্থানীয় ভেরিয়েবলগুলি ঘোষণার সময় আপনি বলতে পারেন int i, *p;কোনটি একটি পূর্ণসংখ্যা এবং কোনও একটি পূর্ণসংখ্যারকে নির্দেশক হিসাবে ঘোষণা করে, তাই এটি বিশ্বাস করে যে এটি *নামের একটি কার্যকর অংশ। তবে এটি নয় এবং এই বাক্য গঠনটি কেবল একটি উদ্বেগযুক্ত বিশেষ কেস, সুবিধার্থে যুক্ত করা হয়েছে, এবং আমার মতে এটি কখনও হওয়া উচিত ছিল না, কারণ এটি আমার উপরে প্রস্তাবিত বিধিটিকে অকার্যকর করে দেয়। যতদূর আমি জানি, ভাষার আর কোথাও এই বাক্যবিন্যাসটি অর্থবহ নয়, তবে এটি যদি হয় তবে এটি সি এর মধ্যে পয়েন্টার প্রকারগুলি যেভাবে সংজ্ঞায়িত করা হয়েছে তাতে একটি তাত্পর্যকে নির্দেশ করে, অন্য কোথাও, একক-পরিবর্তনশীল ঘোষণায়, পরামিতি তালিকায়, কাঠামোর সদস্য ইত্যাদিতে আপনি type* pointer-variableপরিবর্তে আপনার পয়েন্টারগুলি ঘোষণা করতে পারেন type *pointer-variable; এটি পুরোপুরি আইনী এবং আরও বোধগম্য।


int *x = NULL; is correct C, but it is very misleading, I would even say nonsensical,... আমাকে একমত হতে হবে না It makes one think.... চিন্তাভাবনা বন্ধ করুন, প্রথমে একটি সি বই পড়ুন, কোনও অপরাধ নেই।
সৌরভ ঘোষ

^^ এটি আমার কাছে নিখুঁত ধারণা তৈরি করতে পারে। সুতরাং, আমি মনে করি এটি বিষয়গত হয়।
মাইক নাকিস

4
@ সৌরভঘোষ মতামত হিসাবে আমি মনে করি যে সি ডিজাইন করা উচিত ছিল যাতে int* somePtr, someotherPtrদুটি পয়েন্টার ঘোষিত হয়, আসলে, আমি লিখতাম int* somePtrতবে এটি আপনাকে বর্ণিত বাগের দিকে নিয়ে যায়।
fagricipni

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

4
@ ফ্যাগ্রিসিপনি ওয়েল, আমি যদি স্ক্র্যাচ থেকে লিনাক্স ডিজাইন করতে পারতাম তবে আমি এর createপরিবর্তে ব্যবহার করতে পারতাম creat। :) মুল বক্তব্যটি হ'ল এটি কীভাবে হয় এবং সেটিকে খাপ খাইয়ে নিতে আমাদের নিজেদেরকে moldালাই করা দরকার। এটি সমস্ত দিন শেষে ব্যক্তিগত পছন্দ ফোটে, একমত।
সৌরভ ঘোষ

6

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

int * p = NULL;
...
if (...) {
    p = (int*) malloc(...);
    ...
}
...
free(p);

যেহেতু আইএসও- free আইসিআই অনুসারে 9899 স্ট্যান্ডার্ডটি যখন আর্গুমেন্ট হয় তখন একটি নিষিদ্ধ হয় NULL, উপরের কোডটি (বা একই লাইন বরাবর আরও অর্থপূর্ণ কিছু) বৈধ।


4
সি কোডে সি ++ হিসাবেও সংকলন করা উচিত না হলে সিতে ম্যালোকের ফলাফলটি ফেলে দেওয়া অপ্রয়োজনীয়।
বিড়াল

আপনি ঠিক, void*প্রয়োজন হিসাবে রূপান্তরিত হয়। তবে কোড রয়েছে যা একটি সি এবং সি ++ সংকলক সহ কাজ করে তাতে সুবিধা হতে পারে।
লুকা সিটি

4
@ লুকাসিটি সি এবং সি ++ বিভিন্ন ভাষা। যদি আপনি অন্যের জন্য ডিজাইন করা সংকলক ব্যবহার করে কোনওটির জন্য লিখিত উত্স ফাইলটি সংকলনের চেষ্টা করেন তবে কেবলমাত্র আপনার জন্য অপেক্ষা করা ত্রুটি রয়েছে। এটি সি কোড লেখার চেষ্টা করার মতো যা আপনি পাস্কাল সরঞ্জামগুলি ব্যবহার করে সংকলন করতে পারেন।
এভিল ডগ পাই

4
সদুপদেশ. আমি (সর্বদা চেষ্টা করি) সর্বদা আমার পয়েন্টার ধ্রুবককে কিছুতে আরম্ভ করি। আধুনিক সি-তে এটি সাধারণত তাদের চূড়ান্ত মান হতে পারে এবং এগুলি মিডিয়াসconst রেজে ঘোষিত পয়েন্টার হতে পারে , তবে যখন পয়েন্টারটিকে পরিবর্তনযোগ্য (যেমন একটি লুপে বা ব্যবহৃত হিসাবে ব্যবহৃত হয় ) প্রয়োজন হয়, তখন এটি বাগগুলি ধরা হয় যেখানে এটি আগে ব্যবহৃত হয় ches এটি এর আসল মান দিয়ে সেট করা আছে। বেশিরভাগ সিস্টেমে, ডেরেফারেন্সিং ব্যর্থতার মুহূর্তে সেগফোল্টের কারণ হয়ে থাকে (যদিও ব্যতিক্রমগুলি রয়েছে), অন্যদিকে অবিচ্ছিন্ন পয়েন্টারে আবর্জনা থাকে এবং এতে লেখার ফলে স্বেচ্ছাসেবী স্মৃতি কলুষিত হয়। realloc()NULLNULL
ডেভিস্লোর

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


1

এটা সঠিক।

int main()
{
    char * x = NULL;

    if (x==NULL)
        printf("is NULL\n");

    return EXIT_SUCCESS;
}

এই ফাংশনটি যা করে তার জন্য এটি সঠিক। এটি 0 এর ঠিকানাটি চার পয়েন্টার x এর জন্য বরাদ্দ করে। এটি, এটি পয়েন্টারটি x মেমোরি ঠিকানা 0 তে নির্দেশ করে।

বিকল্প:

int main()
{
    char* x = 0;

    if ( !x )
        printf(" x points to NULL\n");

    return EXIT_SUCCESS;
}

আপনি যা চেয়েছিলেন তা সম্পর্কে আমার অনুমান:

int main()
{
    char* x = NULL;
    x = alloc( sizeof( char ));
    *x = '2';

    if ( *x == '2' )
        printf(" x points to an address/location that contains a '2' \n");

    return EXIT_SUCCESS;
}

x is the street address of a house. *x examines the contents of that house.

"এটি চরের পয়েন্টার x কে 0 এর ঠিকানা বরাদ্দ করে" " -> হতে পারে। সি পয়েন্টারের মান নির্দিষ্ট করে না , কেবলমাত্র এটি char* x = 0; if (x == 0)সত্য। পয়েন্টারগুলি অগত্যা পূর্ণসংখ্যার হয় না।
chux

এটি 'মেমোরি ঠিকানার দিকে পয়েন্টার x নির্দেশ করে না' point এটি পয়েন্টার মানটিকে একটি অনির্ধারিত অবৈধ মানকে সেট করে যা এটি 0 বা NUL এর সাথে তুলনা করে পরীক্ষা করা যেতে পারে । প্রকৃত অপারেশন বাস্তবায়ন সংজ্ঞায়িত হয়। এখানে আসল প্রশ্নের উত্তর দেয় এমন কিছুই নেই।
মার্কুইস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.