চর * এবং কনস্ট চর * এর মধ্যে পার্থক্য?


176

এর মধ্যে পার্থক্য কী

char* name

যা একটি ধ্রুব স্ট্রিং আক্ষরিক নির্দেশ করে, এবং

const char* name

সিতে " ধ্রুব স্ট্রিং আক্ষরিক" বলতে কী বোঝায় (সি ++ নয়)
গলবারার

1
... চর * নামটি একটি ধ্রুব স্ট্রিং আক্ষরিকের দিকে ইঙ্গিত করার জন্য করা যেতে পারে
আইসম্যান

"ধ্রুব স্ট্রিং আক্ষরিক" এর ধ্রুবকটি রিন্ডান্ট্যান্ট, যেহেতু সমস্ত স্ট্রিং লিটারালগুলি তত্ত্বীয় ধ্রুবক সত্তা ities এটি ভেরিয়েবলের বিষয়বস্তু যা ধ্রুবক বা পরিবর্তিত হতে পারে। "কনস্ট" ঘোষণাটি কেবল একটি সংকলন সময় ত্রুটি ছুঁড়ে ফেলবে যদি আপনি "নাম" দ্বারা নির্দেশিত চরিত্রের বিষয়বস্তু পরিবর্তন করার চেষ্টা করেন
কাপকেক

সরল: "চর * নাম" নামটি চরের পয়েন্টার, অর্থাৎ উভয়ই এখানে পরিবর্তন হতে পারে। "কনস্ট চর * নাম" নামটি কনট চরের পয়েন্টার অর্থাৎ পয়েন্টার পরিবর্তন হতে পারে তবে চর নয়।
একেডি

ডান থেকে বামে এই জিনিসগুলি পড়ুন।
জিয়াপেং ঝাং

উত্তর:


405

char*একটি হল চপল একটি পয়েন্টার চপল চরিত্র / পংক্তি।

const char*একটি হল চপল একটি পয়েন্টার অপরিবর্তনীয় চরিত্র / পংক্তি। আপনি এই পয়েন্টারটি যে অবস্থানটির (গুলি) নির্দেশ করেছেন সেগুলির সামগ্রী পরিবর্তন করতে পারবেন না। এছাড়াও, সংকলকগণ যখন আপনি এটি করার চেষ্টা করছেন ত্রুটি বার্তা দিতে হবে। একই কারণে, থেকে রুপান্তরের const char *জন্য char*অসমর্থিত হয়েছে।

char* constএকটি অপরিবর্তনীয় পয়েন্টার (এটি অন্য কোনও জায়গায় নির্দেশ করতে পারে না) তবে অবস্থানের বিষয়বস্তু যেখানে এটি নির্দেশ করে তা পরিবর্তনীয়

const char* constঅপরিবর্তনীয় চরিত্র / স্ট্রিংয়ের এক অপরিবর্তনীয় পয়েন্টার ।


4
উপরে উল্লিখিত বিবৃতিগুলির পরে এবং সেই ভেরিয়েবলটিকে রেফারেন্স দিয়ে ভেরিয়েবল ব্যবহারের সাথে বিভ্রান্তি পরিষ্কার হয়ে যেতে পারে।
ankit.karwasra

3
@ অঙ্কিত.কারওয়াসরা, আপনি আরও একটি মিস করেছেন:char const *
পেসারিয়ার

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

1
মিউটেশন char *চলমান অবস্থায় বিভাগকে ত্রুটি দেবে না ?
দিব্যংশু মাইথানি

1
তাই আমি constযদি আমি কম্পাইলারটি ত্রুটি দিতে চাই তা ভুল করে ডেটা ভুলে গিয়ে পরিবর্তন করি, তাই না?
হিসাবরক্ষক Ap

43
char *name

আপনি যে nameবিন্দুতে চরটি পরিবর্তন করতে পারেন এবং এটি যে বিন্দুতে ইঙ্গিত করেছে তাও পরিবর্তন করতে পারবেন ।

const char* name

আপনি চরকে কোন nameপয়েন্টে পরিবর্তন করতে পারেন, তবে আপনি যে চরকে এটি নির্দেশ করেছেন তা পরিবর্তন করতে পারবেন না।
সংশোধন: আপনি পয়েন্টার পরিবর্তন করতে পারেন কিন্তু না গৃহস্থালির কাজ যা nameপয়েন্ট ( https://msdn.microsoft.com/en-us/library/vstudio/whkd4k6a(v=vs.100).aspx দেখুন "উদাহরণ" )। এই ক্ষেত্রে, constনির্দিষ্টকারকটি প্রয়োগ হয় char, নক্ষত্রের উপরে নয়।

এমএসডিএন পৃষ্ঠা এবং http://en.cppreferences.com/w/cpp/language/declations অনুসারে , এর constআগে *ডেসেল-স্পেসিফায়ার ক্রমের অংশ , যখন constপরে *ঘোষণাকারীর অংশ।
একটি ঘোষণাপত্রের স্পেসিফায়ার ক্রমটি একাধিক ডিক্লেয়ারের দ্বারা অনুসরণ করা যেতে পারে, এজন্যই হিসাবে এবং হিসাবে const char * c1, c2ঘোষণা c1করা হয় ।const char *c2const char

সম্পাদনা করুন:

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

যে ক্ষেত্রে, আপনি করা উচিত নয় যা গৃহস্থালির কাজ সংশোধন name, পয়েন্ট যেমন হতে পারে অনির্ধারিত আচরণ । স্ট্রিং লিটারালগুলি কেবল পঠনযোগ্য মেমরি অঞ্চলে বরাদ্দ করা যেতে পারে (বাস্তবায়িত সংজ্ঞায়িত) এবং কোনও ব্যবহারকারী প্রোগ্রাম কোনওভাবেই এটি পরিবর্তন করতে হবে না। এটি করার যে কোনও প্রয়াসই ফলাফলহীন আচরণের ফলাফল in

সুতরাং ক্ষেত্রে একমাত্র পার্থক্য (স্ট্রিং আক্ষরিক সাথে ব্যবহারের) দ্বিতীয় ঘোষণাটি আপনাকে সামান্য সুবিধা দেয়। আপনি দ্বিতীয় ক্ষেত্রে স্ট্রিংকে আক্ষরিক সংশোধন করার চেষ্টা করার ক্ষেত্রে কমপাইলাররা সাধারণত আপনাকে একটি সতর্কতা দেয়।

অনলাইন নমুনার উদাহরণ:

#include <string.h>
int main()
{
    char *str1 = "string Literal";
    const char *str2 = "string Literal";
    char source[] = "Sample string";

    strcpy(str1,source);    //No warning or error, just Undefined Behavior
    strcpy(str2,source);    //Compiler issues a warning

    return 0;
}

আউটপুট:

সিসি 1: সতর্কতাগুলি ত্রুটিগুলি
প্রগ হিসাবে বিবেচিত হবে :
ফাংশনটিতে 'প্রধান': প্রগ্যাক: 9: ত্রুটি: ' স্ট্রাইকপি'-র 1 টি আর্গুমেন্ট পয়েন্টার টার্গেট টাইপ থেকে বাছাইয়ের যোগ্যতা ছাড়বে

লক্ষ্য করুন যে সংকলকটি দ্বিতীয় ক্ষেত্রে সাবধান করে তবে প্রথমটির জন্য নয়।


ধন্যবাদ .. আমি ধ্রুব স্ট্রিং আক্ষরিকের সাথে মেশছিলাম, যা সংজ্ঞায়িত: চর * নাম = "স্ট্রিং লিটারাল"; "স্ট্রিং লিটারাল" পরিবর্তন অনির্ধারিত ..
আইসম্যান

@ ব্যবহারকারী 1279782: এরর, অপেক্ষা করুন! আপনি এখানে স্ট্রিং লিটারালগুলিতে নির্দেশিত পয়েন্টগুলির কথা বলছেন? যে ক্ষেত্রে আপনি করা উচিত নয় গৃহস্থালির কাজ যা সংশোধন nameপারেন case.It পয়েন্ট UB হতে পারে।
অলোক

হ্যাঁ, বিষয়টি ছিল। তাহলে সেই ক্ষেত্রে চর * নাম এবং কনস্ট চর * নামটি একই রকম আচরণ করে, তাই না?
আইসম্যান

4
এই উত্তরটি হয় অত্যন্ত অস্পষ্ট বা কেবল সাধারণ ভুল। আমি ব্যাখ্যা করব "আপনি কোন নামটি পয়েন্টটি পরিবর্তন করতে পারবেন না তবে আপনি যে চরকে এটি নির্দেশ করেছেন সেটি আপনি পরিবর্তন করতে পারবেন।" : মেমরি অবস্থানকে ব্যবহার করার প্রচেষ্টা পয়েন্ট, যা ভুল সংশোধন করতে সক্ষম হচ্ছে পয়েন্টার নিজেই সংশোধন করতে সক্ষম হচ্ছে, কিন্তু ideone.com/6lUY9s : বিশুদ্ধ সি জন্য অন্যথায় ideone.com/x3PcTP
shroudednight

1
@ শ্রাবিত রাত: অপরিজ্ঞাত আচরণগুলি সম্পর্কে আপনাকে আরও কিছু শিখতে হবে এবং এর মধ্যে পার্থক্য করা দরকার: অনুমোদিত এবং করা উচিত নয়। :)
অলোক

16
char mystring[101] = "My sample string";
const char * constcharp = mystring; // (1)
char const * charconstp = mystring; // (2) the same as (1)
char * const charpconst = mystring; // (3)

constcharp++; // ok
charconstp++; // ok
charpconst++; // compile error

constcharp[3] = '\0'; // compile error
charconstp[3] = '\0'; // compile error
charpconst[3] = '\0'; // ok

// String literals
char * lcharp = "My string literal";
const char * lconstcharp = "My string literal";

lcharp[0] = 'X';      // Segmentation fault (crash) during run-time
lconstcharp[0] = 'X'; // compile error

// *not* a string literal
const char astr[101] = "My mutable string";
astr[0] = 'X';          // compile error
((char*)astr)[0] = 'X'; // ok

1
আপনার পয়েন্টারগুলির কোনওটিই প্রশ্ন অনুসারে "ধ্রুব স্ট্রিং আক্ষরিক" নির্দেশ করে না।
ক্যাফে

এটি লক্ষণীয় যে char *মানটি পরিবর্তনের ফলে বিভাগকে ত্রুটি দেওয়া যায় যেহেতু আমরা একটি স্ট্রিং আক্ষরিক (যা কেবলমাত্র পঠনযোগ্য স্মৃতিতে উপস্থিত রয়েছে) সংশোধন করার চেষ্টা করছি
দিব্যংশু মাইথানী

10

তন্ন তন্ন যদি আপনি স্ট্রিং আক্ষরিক পয়েন্টার হিসেবে ঘোষণা করা আছে কিনা নির্বিশেষে একটি স্ট্রিং আক্ষরিক পরিবর্তন করতে পারেন, char *বা const char *

তবে পার্থক্যটি হ'ল যদি পয়েন্টারটি হয় const char *তবে সংকলককে অবশ্যই একটি ডায়াগনস্টিক দিতে হবে যদি আপনি পয়েন্ট-টু মানটি সংশোধন করার চেষ্টা করেন তবে পয়েন্টারটি যদি হয় char *তবে তা হয় না।


1
"উভয় ক্ষেত্রেই আপনি স্ট্রিং আক্ষরিক সংশোধন করতে পারবেন না, ... [এটি] চর * বা কনস্ট চর হিসাবে ঘোষণা করা হোক না কেন" "আমি সম্মত হই যে প্রোগ্রামারটি চেষ্টা করা উচিত নয়, তবে আপনি কি প্রতিটি সি সংকলক প্রতিটিতেই বলছেন? প্ল্যাটফর্মটি কোডটি প্রত্যাখ্যান করবে, রান টাইমে কোডটি ব্যর্থ হওয়ার ব্যবস্থা করবে, না অন্য কিছু? আমি বিশ্বাস করি, একটি ফাইলের সংজ্ঞা এবং সূচনা হতে পারে extern ... nameএবং অন্য একটি ফাইল থাকতে পারে এবং থাকতে পারে *name = 'X';। 'যথাযথ অপারেটিং সিস্টেম'-এ, এটি ব্যর্থ হতে পারে তবে এম্বেড হওয়া সিস্টেমে আমি প্ল্যাটফর্ম / সংকলকটি নির্দিষ্ট কিছু আশা করব।
গলবারার

@ গাবলুমার: আপনি সঠিক সি প্রোগ্রামে একটি স্ট্রিং আক্ষরিক পরিবর্তন করতে পারবেন না। কোন ভুল সি প্রোগ্রামের ফলে যা চেষ্টা করে তা এখানে বা সেখানেই নেই।
ক্যাফে

@ গবুলার: একটি দরকারী সংজ্ঞা হ'ল একটি প্রোগ্রাম যা সি ভাষার মান দ্বারা নির্দিষ্ট কোনও প্রতিবন্ধকতা ভঙ্গ করে না। অন্য কথায়, একটি প্রোগ্রাম যা একটি স্ট্রিং আক্ষরিক সংশোধন করে সেইভাবে ভুল যে কোনও নাল পয়েন্টারকে অবজ্ঞা করে বা 0 দ্বারা একটি বিভাগ সম্পাদন করে তা ভুল incor
ক্যাফে

ক্যাফে - আমি ভেবেছিলাম যে আপনি যা বলতে চাইছেন তা হতে পারে। তারপরে "উভয় ক্ষেত্রেই আপনি একটি স্ট্রিং আক্ষরিক সংশোধন করতে পারবেন না " এটি উল্লেখ করার চেয়ে বেশি। এটি বলা ঠিক হবে "উভয় ক্ষেত্রেই সি ভাষার মান দ্বারা নির্ধারিত প্রতিবন্ধকতাগুলি ভেঙে গেছে, নির্বিশেষে .... সংকলক বা রান টাইম সিস্টেমের পক্ষে সব ক্ষেত্রেই মান লঙ্ঘন সনাক্ত করা সম্ভব নয়।" আমি ধরে নিই যে স্ট্যান্ডার্ডটি এমন অবস্থান নেয় যে প্রভাবটি অপরিবর্তিত?
গবলার

1
যখন কোনও স্ট্যান্ডার্ড কোনও উপায়ে কিছু জোর করতে পারে না, তখন আমার মনে হয় যে আচরণকে 'অপরিজ্ঞাত' হিসাবে সংজ্ঞায়িত করা হ'ল মনে হয় ঠিক সঠিক সীমানা এবং সহায়ক বলে মনে হচ্ছে। সম্পর্কটি দৃsert় করার জন্য একটি 'সঠিক সি প্রোগ্রাম' ' থামানো সমস্যা প্রমাণের সমতুল্য একটি নাল পয়েন্টারকে অবজ্ঞা করতে পারে না । তবে আমার আপত্তি নেই। আমি এটি করব না এবং এটি দিয়ে 'স্কট ফ্রি' :-)
গাবলমার

4

মামলা 1:

char *str = "Hello";
str[0] = 'M'  //Warning may be issued by compiler, and will cause segmentation fault upon running the programme

উপরের সেটগুলি অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে চিহ্নিত করা হয়েছে যা এই স্ট্রিং আক্ষরিক কোনও পরিবর্তন অবৈধ এবং এর ফলে বিভাজন ত্রুটি ঘটবে।

CASE 2:

const char *str = "Hello";
str[0] = 'M'  //Compile time error

মামলা 3:

char str[] = "Hello";
str[0] = 'M'; // legal and change the str = "Mello".

2

আপনি চাইলে প্রথমে আপনি আসলে পরিবর্তন করতে পারবেন, দ্বিতীয়টি আপনি পারবেন না। constনির্ভুলতা সম্পর্কে পড়ুন (পার্থক্য সম্পর্কে কিছু চমৎকার গাইড আছে)। এমন একটি জায়গা রয়েছে char const * nameযেখানে আপনি এটিকে পুনরায় দমন করতে পারবেন না।


ঠিক কী পরিবর্তন হতে পারে?
অ্যান্টি হাপালা

2

প্রশ্ন এর মধ্যে পার্থক্য কি

char *name

যা একটি ধ্রুব স্ট্রিং আক্ষরিক নির্দেশ করে, এবং

const char *cname

আই

char *name = "foo";

এবং

const char *cname = "foo";

2 এর মধ্যে খুব বেশি পার্থক্য নেই এবং উভয়ই সঠিক হিসাবে দেখা যেতে পারে। সি কোডের দীর্ঘ উত্তরাধিকারের কারণে, স্ট্রিং লিটারালগুলির একটি ধরণের ছিল char[], না const char[], এবং প্রচুর পুরানো কোড রয়েছে যা একইভাবে char *পরিবর্তে স্বীকার করে const char *, এমনকি তারা যুক্তি পরিবর্তন না করে।

সাধারণভাবে 2 এর প্রধান পার্থক্য হ'ল *cnameবা cname[n]প্রকারের মূল্যকে মূল্যায়ন করবে const char, যেখানে *nameবা name[n]প্রকারের মূল্যকে মূল্যায়ন করবে char, যা পরিবর্তনযোগ্য লভ্যগুলি । যদি একটি কার্যনির্বাহী সংকলক প্রয়োজন হয় যদি ডায়াগনস্টিকস বার্তা তৈরি করতে হয় যদি অ্যাসাইনমেন্টের লক্ষ্যমাত্রা পরিবর্তনযোগ্য লভ্যালু না হয় ; এটিকে বিভিন্ন ধরণের অ্যাসাইনমেন্ট সম্পর্কে কোনও সতর্কতা তৈরি করার দরকার নেই char:

name[0] = 'x'; // no diagnostics *needed*
cname[0] = 'x'; // a conforming compiler *must* produce a diagnostics message

কম্পাইলার হয় না প্রয়োজন উভয় ক্ষেত্রে সংকলন বন্ধ করে দেবেন | এটি যথেষ্ট যে এটি কার্যভারের জন্য একটি সতর্কতা তৈরি করে cname[0]। ফলস্বরূপ প্রোগ্রামটি একটি সঠিক প্রোগ্রাম নয়। কনস্ট্রাক্ট আচরণ করা হয় অনির্দিষ্ট । এটি ক্রাশ হতে পারে, বা আরও খারাপ এটি ক্রাশ নাও হতে পারে এবং স্মৃতিতে স্ট্রিংকে আক্ষরিক পরিবর্তিত করতে পারে।


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