চর s [] এবং চর * এর মধ্যে পার্থক্য কী?


506

সি-তে, কোনও এই জাতীয় ঘোষণায় স্ট্রিং আক্ষরিক ব্যবহার করতে পারে:

char s[] = "hello";

বা এই মত:

char *s = "hello";

তাহলে পার্থক্য টা কি? সংকলন এবং রান সময় উভয় সময়ে সঞ্চয়স্থানের সময়কালের ক্ষেত্রে আসলে কী ঘটে তা আমি জানতে চাই।



8
চর * এস = "হ্যালো", এখানে রান সময় সময়ে অন্য কোনও স্ট্রিং নির্দেশ করতে পারে আমার অর্থ এটি ধ্রুবক পয়েন্টার নয় যা আপনি রান সময় পি = "নিশান্ত" এ অন্য কোনও মান নির্ধারণ করতে পারেন, যখন এস [] এখানে এস ধ্রুবক পয়েন্টার .. ..একটি স্ট্রিং পুনরায় সাইন ইন করা যায় না তবে আমরা এস [সূচক] এ অন্য একটি চরিত্রের মান নির্ধারণ করতে পারি।
নিশান্ত কুমার

উত্তর:


540

পার্থক্য এখানে

char *s = "Hello world";

স্থাপন করবে "Hello world"মধ্যে মেমরি শুধুমাত্র পাঠযোগ্য অংশের , এবং উপার্জন sএকটি পয়েন্টার যে এই মেমরিতে কোনো লেখা অপারেশন অবৈধ তোলে।

করার সময়:

char s[] = "Hello world";

আক্ষরিক স্ট্রিংটি কেবল পঠনযোগ্য মেমরিতে রাখে এবং স্ট্রিকে নতুন বরাদ্দকৃত মেমরিতে স্ট্রিংটি অনুলিপি করে। এইভাবে তৈরি

s[0] = 'J';

আইনগত।


22
আক্ষরিক স্ট্রিং "Hello world"উভয় উদাহরণে "মেমরির কেবল পঠনযোগ্য অংশগুলিতে" রয়েছে। সেখানে অ্যারে পয়েন্টগুলির সাথে উদাহরণটি, অ্যারের সাথে উদাহরণটি অ্যারে উপাদানগুলিতে অক্ষরগুলি অনুলিপি করে।
pmg

28
পিএমজি: দ্বিতীয় ক্ষেত্রে আক্ষরিক স্ট্রিংটি অবিচ্ছিন্নভাবে কোনও একক অক্ষরযুক্ত বস্তু হিসাবে স্মৃতিতে উপস্থিত হয় না - এটি কেবলমাত্র একটি সূচনাশৈলীর, সংকলকটি "লোড অবিলম্বে বাইট" নির্দেশের একটি ধারাবাহিকভাবে যথেষ্ট পরিমাণে অনুরোধ করতে পারে যার মধ্যে অক্ষরটির মান এম্বেড করা থাকে contain তাদের।
ক্যাফে

10
চর অ্যারের উদাহরণ অগত্যা স্ট্যাকের উপর স্ট্রিং রাখে না - যদি এটি ফাইল স্তরে উপস্থিত হয়, তবে সম্ভবত এটি পরিবর্তে কোনও প্রারম্ভিক ডেটা বিভাগে থাকবে।
ক্যাফে

9
আমি যে বাতলান গৃহস্থালির কাজ গুলি = "xx" না চাই আছে -অনলি মেমোরি করা (কিছু বাস্তবায়নের উদাহরণস্বরূপ, কোন MMUs থাকে)। N1362 সি 1 এক্স খসড়াটি সহজভাবে জানিয়েছে যে এই জাতীয় অ্যারে সংশোধন করা অনির্ধারিত আচরণের কারণ। তবে +1 যাইহোক, যেহেতু সেই আচরণের উপর নির্ভর করা একটি কর্কশ জিনিস।
paxdiablo

3
আমি স্ট্রাইসটি char msg[] = "hello, world!"; প্রাথমিক পর্যায়ে থাকা বিভাগে শেষ হয়ে একটি ফাইলের একটি পরিষ্কার সংকলন পেয়েছি । যখন char * constকেবলমাত্র পঠনযোগ্য ডেটা বিভাগে শেষ হওয়ার ঘোষণা দেওয়া হয়। gcc-4.5.3
gcbenison

152

প্রথম প্রথম, ফাংশন আর্গুমেন্ট এ, তারা ঠিক সমতুল্য:

void foo(char *x);
void foo(char x[]); // exactly the same in all respects

অন্যান্য প্রসঙ্গে, একটি বিন্যাস বরাদ্দ করার char *সময় একটি পয়েন্টার char []বরাদ্দ করে। আগের ক্ষেত্রে স্ট্রিংটি কোথায় যায়, আপনি জিজ্ঞাসা করেন? সংকলকটি গোপনে স্ট্রিং আক্ষরিক ধরে রাখতে স্থির বেনামে অ্যারে বরাদ্দ করে। তাই:

char *x = "Foo";
// is approximately equivalent to:
static const char __secret_anonymous_array[] = "Foo";
char *x = (char *) __secret_anonymous_array;

মনে রাখবেন যে আপনাকে এই বেনামে অ্যারের সামগ্রীগুলি এই পয়েন্টারটির মাধ্যমে কখনও পরিবর্তন করার চেষ্টা করতে হবে না; প্রভাবগুলি অপরিশোধিত (প্রায়শই ক্রাশের অর্থ):

x[1] = 'O'; // BAD. DON'T DO THIS.

অ্যারে সিনট্যাক্স ব্যবহার করে এটি সরাসরি নতুন স্মৃতিতে বরাদ্দ করে। সুতরাং পরিবর্তনটি নিরাপদ:

char x[] = "Foo";
x[1] = 'O'; // No problem.

তবে অ্যারে কেবল তার সংশ্লেষের সুযোগ হিসাবে দীর্ঘকাল বেঁচে থাকে, সুতরাং আপনি যদি কোনও ফাংশনে এটি করেন তবে ফিরে বা এই অ্যারেটিতে কোনও পয়েন্টার ফাঁস করবেন না - এর পরিবর্তে strdup()বা অনুরূপ একটি অনুলিপি তৈরি করুন । অ্যারেটি যদি বিশ্বব্যাপী সুযোগে বরাদ্দ করা হয় তবে অবশ্যই কোনও সমস্যা নেই।


72

এই ঘোষণা:

char s[] = "hello";

একটি অবজেক্ট তৈরি করে - charsize আকারের অ্যারে, বলা হয়s হয় মানগুলির সাথে আরম্ভ করা 'h', 'e', 'l', 'l', 'o', '\0'। এই অ্যারেটি কোথায় মেমোরিতে বরাদ্দ করা হয় এবং এটি কতক্ষণ বাঁচে তা নির্ভর করে যেখানে ঘোষণাটি প্রদর্শিত হবে appears যদি ঘোষণাটি কোনও ফাংশনের মধ্যে থাকে তবে এটি যে ব্লকটিতে ঘোষণা করা হয়েছে তার শেষ অবধি এটি বেঁচে থাকবে এবং প্রায় অবশ্যই স্ট্যাকের জন্য বরাদ্দ দেওয়া হবে; যদি এটি কোনও ফাংশনের বাইরে থাকে তবে সম্ভবত এটি একটি "আরম্ভিত ডেটা বিভাগ" এর মধ্যে সংরক্ষণ করা হবে যা প্রোগ্রামটি চালিত হওয়ার পরে এক্সিকিউটেবল ফাইল থেকে লেখার যোগ্য মেমরিতে লোড করা হয়।

অন্যদিকে, এই ঘোষণা:

char *s ="hello";

তৈরি করা হয় দুটি বস্তু করে:

  • একটি শুধুমাত্র পাঠযোগ্য 6 অ্যারে charমানগুলি রয়েছে গুলি 'h', 'e', 'l', 'l', 'o', '\0', যা কোন নাম আছে এবং আছে স্থিতিশীল স্টোরেজ সময়কাল (অর্থাত্ এটি প্রোগ্রামের পুরো জীবন ধরে বেঁচে থাকে); এবং
  • টাইপ পয়েন্টার-টু-চরের একটি পরিবর্তনশীল, যাকে বলা হয় s , যা নামবিহীন, কেবল পঠনযোগ্য অ্যারেতে প্রথম অক্ষরের অবস্থানের সাথে সূচনা করা হয়।

নামবিহীন পঠনযোগ্য কেবল অ্যারে সাধারণত প্রোগ্রামটির "পাঠ্য" বিভাগে অবস্থিত, যার অর্থ এটি কোডের সাথে ডিস্ক থেকে কেবল পঠনযোগ্য মেমরিতে লোড হয়। sমেমোরিতে পয়েন্টার ভেরিয়েবলের অবস্থান নির্ভর করে যেখানে ঘোষণাটি প্রদর্শিত হবে (ঠিক প্রথম উদাহরণের মতো)।


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

2
@ নিশান্ট: সেক্ষেত্রে char s[] = "hello", এটি "hello"কেবলমাত্র একটি আরম্ভকারী যা সংকলককে বলছে অ্যারে কীভাবে আরম্ভ করা উচিত। এটি পাঠ্য বিভাগে সংশ্লিষ্ট স্ট্রিংয়ের ফলস্বরূপ বা নাও হতে পারে - উদাহরণস্বরূপ, যদি sস্ট্যাটিক স্টোরেজ সময়কাল থাকে তবে সম্ভবত এটির একমাত্র উদাহরণটি "hello"আরম্ভকৃত ডেটা বিভাগে থাকবে - অবজেক্টটি sনিজেই। এমনকি যদি sস্বয়ংক্রিয় স্টোরেজ সময়কাল থাকে, তবে এটি অনুলিপি (উদাহরণস্বরূপ movl $1819043176, -6(%ebp); movw $111, -2(%ebp)) পরিবর্তে আক্ষরিক স্টোরের ক্রম দ্বারা সূচনা করা যেতে পারে ।
ক্যাফে

আরও সুনির্দিষ্টভাবে, জিসিসি 4.8 এটিকে রাখে .rodata, যা লিঙ্কার স্ক্রিপ্টটি একই বিভাগে ফেলে দেয় .textআমার উত্তর দেখুন ।
সিরো সান্তিলি 郝海东 冠状 病 六四 事件 法轮功

@ কেএফ রিকার্ডের প্রথম উত্তরে এটি লেখা হয়েছে যে char s[] = "Hello world";আক্ষরিক স্ট্রিংটি কেবল পঠনযোগ্য মেমরিতে রাখে এবং স্ট্রিকে নতুন বরাদ্দ মেমরিতে স্ট্রিংটি অনুলিপি করে। কিন্তু আপনার উত্তর শুধুমাত্র শুধুমাত্র পাঠযোগ্য মেমরি আক্ষরিক স্ট্রিং করা সম্পর্কে কথা বলে এবং বাক্য যা বলে দ্বিতীয় অংশ অগ্রাহ্য: copies the string to newly allocated memory on the stack। সুতরাং, আপনার উত্তরটি দ্বিতীয় অংশটি নির্দিষ্ট না করার জন্য অসম্পূর্ণ?
কেপিএমজি

1
@ অজয়সিংহ নেগী: যেমন আমি অন্যান্য মন্তব্যে বলেছি (এই উত্তরটি, এবং রিকার্ডের উত্তরে), স্ট্রিংটি char s[] = "Hellow world";কেবলমাত্র একটি আরম্ভকারী এবং এটি পৃথক পঠনযোগ্য কেবল অনুলিপি হিসাবে সংরক্ষণ করা হয় না। যদি sস্ট্যাটিক স্টোরেজ সময়কাল থাকে তবে স্ট্রিংয়ের একমাত্র অনুলিপিটি সম্ভবত অবস্থানে অবস্থিত একটি পঠন-লেখার অংশে থাকতে sপারে এবং তা না হলেও সংকলক অনুলিপি না করে লোড-তাত্ক্ষণিক নির্দেশাবলী বা অনুরূপের সাথে অ্যারে আরম্ভ করতে বেছে নিতে পারে কেবল পঠনযোগ্য স্ট্রিং থেকে। মুল বক্তব্যটি এই ক্ষেত্রে, আরম্ভকারী স্ট্রিংয়ের নিজেই কোনও রানটাইম উপস্থিতি নেই।
ক্যাফে

60

ঘোষণা দেওয়া

char *s0 = "hello world";
char s1[] = "hello world";

নিম্নলিখিত অনুমানের মেমরি মানচিত্র ধরুন:

                    0x01 0x02 0x03 0x04
        0x00008000: 'এইচ' 'ই' 'ল' 'এল'
        0x00008004: 'ও' '' 'ডাব্লু' 'ও'
        0x00008008: 'r' 'l' 'd' 0x00
        ...
s0: 0x00010000: 0x00 0x00 0x80 0x00
এস 1: 0x00010004: 'এইচ' 'ই' 'ল' 'এল'
        0x00010008: 'ও' '' 'ডাব্লু' 'ও'
        0x0001000C: 'r' 'l' 'd' 0x00

স্ট্রিং আক্ষরিক "hello world"একটি 12-উপাদান অ্যারের char( const charসি ++ এ) স্থির স্টোরেজ সময়কাল সহ, যখন প্রোগ্রামটি শুরু হয় এবং প্রোগ্রামটি শেষ না হওয়া অবধি বরাদ্দ থাকে তখন এর জন্য মেমরি বরাদ্দ করা হয়। একটি স্ট্রিং আক্ষরিক বিষয়বস্তু সংশোধন করার চেষ্টা অনির্ধারিত আচরণ ডাকে।

লাইন

char *s0 = "hello world";

অটো স্টোরেজ সময়কাল সহ s0একটি পয়েন্টার হিসাবে সংজ্ঞায়িত করে char(যার অর্থ পরিবর্তনশীল s0কেবলমাত্র এটি ঘোষিত স্কোপের জন্য বিদ্যমান) এবং এতে স্ট্রিংয়ের ঠিকানাটি ( 0x00008000এই উদাহরণে) অনুলিপি করে । নোট যে যেহেতু s0একটি স্ট্রিং আক্ষরিক পয়েন্ট, এটা (যেমন, কোনো ফাংশন যা এটি পরিবর্তন করার চেষ্টা করবে একটি আর্গুমেন্ট হিসাবে ব্যবহার করা উচিত নয় strtok(), strcat(), strcpy(), ইত্যাদি)।

লাইন

char s1[] = "hello world";

অটো স্টোরেজ সময়কাল সহ s112-উপাদান অ্যারের char(দৈর্ঘ্যটি স্ট্রিং আক্ষরিক থেকে নেওয়া হয়) হিসাবে সংজ্ঞায়িত করে এবং আক্ষরিকের সামগ্রীগুলি অ্যারেতে অনুলিপি করে । আপনি মেমরির মানচিত্র থেকে দেখতে পাচ্ছেন, আমাদের কাছে স্ট্রিংয়ের দুটি অনুলিপি রয়েছে "hello world"; পার্থক্যটি হ'ল আপনি এতে থাকা স্ট্রিংটি সংশোধন করতে পারেন s1

s0এবং s1বেশিরভাগ প্রসঙ্গেই বিনিময়যোগ্য; ব্যতিক্রম এখানে:

sizeof s0 == sizeof (char*)
sizeof s1 == 12

type of &s0 == char **
type of &s1 == char (*)[12] // pointer to a 12-element array of char

আপনি ভেরিয়েবলটিকে আবার s0ভিন্ন ভিন্ন স্ট্রিংকে আক্ষরিক বা অন্য ভেরিয়েবলের দিকে নির্দেশ করতে পারেন। আপনি s1ভিন্ন অ্যারেতে নির্দেশ করতে ভেরিয়েবলটি পুনরায় নিয়োগ করতে পারবেন না ।


2
আমি মনে করি অনুমানের মেমরি মানচিত্রটি বুঝতে সহজ করে তোলে!
মধ্যরাত

32

C99 N1256 খসড়া

অক্ষর স্ট্রিং আক্ষরিক দুটি ভিন্ন ব্যবহার আছে:

  1. আরম্ভ করুন char[]:

    char c[] = "abc";      

    এটি "আরও যাদু" এবং 6..7.৮ / ১৪ "ইনিশিয়ালাইজেশন" এ বর্ণিত:

    অক্ষর ধরণের একটি অ্যারে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে অক্ষরে সংক্ষেপিত বন্ধনী দ্বারা আরম্ভ করা যেতে পারে। অক্ষরের স্ট্রিং আক্ষরিকের ধারাবাহিক অক্ষর (ঘর থাকলে অবিরাম আকারে টার্মিনেটিং নাল চরিত্র সহ) অ্যারের উপাদানগুলির সূচনা করে।

    সুতরাং এটি কেবল একটি শর্টকাট:

    char c[] = {'a', 'b', 'c', '\0'};

    অন্য কোনও নিয়মিত অ্যারের মতো, cপরিবর্তন করা যেতে পারে।

  2. অন্য যে কোনও জায়গায়: এটি একটি উত্পন্ন করে:

    সুতরাং আপনি যখন লিখুন:

    char *c = "abc";

    এটি এর অনুরূপ:

    /* __unnamed is magic because modifying it gives UB. */
    static char __unnamed[] = "abc";
    char *c = __unnamed;

    নোট থেকে অন্তর্নিহিত ঢালাই char[]করার char *, যা সবসময় বৈধ।

    তারপরে আপনি যদি সংশোধন করেন c[0], __unnamedআপনিও সংশোধন করুন , যা ইউবি।

    এটি 6.4.5 "স্ট্রিং লিটারালস" এ নথিভুক্ত করা হয়েছে:

    5 অনুবাদ পর্বে 7 এ, বাইট বা মান শূন্যের কোডটি প্রতিটি মাল্টবাইট চরিত্রের অনুক্রমের সাথে যুক্ত হয় যা স্ট্রিং আক্ষরিক বা আক্ষরিক থেকে ফলাফল। মাল্টিবাইট চরিত্রের সিক্যুয়েন্সটি পরে স্থির স্টোরেজ সময়কাল এবং সিক্যুয়েন্সটি পর্যাপ্ত রাখার জন্য যথেষ্ট দৈর্ঘ্যের একটি অ্যারে শুরু করতে ব্যবহৃত হয়। চরিত্রের স্ট্রিং লিটারালগুলির জন্য, অ্যারের উপাদানগুলিতে টাইপ চর থাকে এবং মাল্টিবাইট অক্ষর ক্রমের পৃথক বাইটগুলির সাথে আরম্ভ করা হয় [...]

    These এই অ্যারেগুলি পৃথক পৃথক কিনা তাদের উপাদানগুলির উপযুক্ত মান রয়েছে কিনা তা অনির্দিষ্ট। প্রোগ্রামটি যদি এমন অ্যারে সংশোধন করার চেষ্টা করে তবে আচরণটি সংজ্ঞায়িত।

Initial.7.৮ / 32 "ইনিশিয়ালাইজেশন" এর প্রত্যক্ষ উদাহরণ দেয়:

উদাহরণ 8: ঘোষণা

char s[] = "abc", t[3] = "abc";

"প্লেইন" চর অ্যারে অবজেক্টগুলি সংজ্ঞায়িত করে sএবং tযার উপাদানগুলি অক্ষর স্ট্রিং ল্যাটারাল দিয়ে শুরু করা হয়।

এই ঘোষণাটি সমান

char s[] = { 'a', 'b', 'c', '\0' },
t[] = { 'a', 'b', 'c' };

অ্যারের সামগ্রীগুলি পরিবর্তনযোগ্য if অন্যদিকে, ঘোষণা

char *p = "abc";

p"পয়েন্টার টু চর" টাইপ দিয়ে সংজ্ঞায়িত করে এবং এটি দৈর্ঘ্য 4 দিয়ে "চরের অ্যারে" টাইপযুক্ত কোনও বস্তুর দিকে নির্দেশ করতে ইনিশিয়ালাইজ করে যার উপাদানগুলি একটি অক্ষর স্ট্রিং আক্ষরিক দিয়ে প্রাথমিক হয়। pঅ্যারের বিষয়বস্তুগুলি সংশোধন করার জন্য যদি চেষ্টা করা হয় , তবে আচরণটি সংজ্ঞায়িত।

জিসিসি 4.8 x86-64 ELF বাস্তবায়ন

কার্যক্রম:

#include <stdio.h>

int main(void) {
    char *s = "abc";
    printf("%s\n", s);
    return 0;
}

সংকলন এবং পচনশীল:

gcc -ggdb -std=c99 -c main.c
objdump -Sr main.o

আউটপুট রয়েছে:

 char *s = "abc";
8:  48 c7 45 f8 00 00 00    movq   $0x0,-0x8(%rbp)
f:  00 
        c: R_X86_64_32S .rodata

উপসংহার: জিসিসি char*এটিকে .rodataবিভাগে রাখে, না .text

তবে খেয়াল করুন যে ডিফল্ট লিঙ্কার স্ক্রিপ্টটি একই বিভাগে রাখে .rodataএবং এতে লেখার অনুমতি নেই। এটি দিয়ে পর্যবেক্ষণ করা যেতে পারে:.text

readelf -l a.out

যেটা বহন করে:

 Section to Segment mapping:
  Segment Sections...
   02     .text .rodata

আমরা যদি এর জন্য একই করি char[]:

 char s[] = "abc";

আমরা প্রাপ্ত:

17:   c7 45 f0 61 62 63 00    movl   $0x636261,-0x10(%rbp)

সুতরাং এটি স্ট্যাকের মধ্যে (আপেক্ষিক %rbp) সংরক্ষণ করা হয়।


15
char s[] = "hello";

প্রাথমিকের (5 + 1 গুলি) ধরে রাখার জন্য যথেষ্ট দীর্ঘ sএবং একটি অ্যারে হিসাবে ঘোষিত হয় এবং প্রদত্ত স্ট্রিংয়ের সদস্যদের অ্যারেতে অনুলিপি করে অ্যারে আরম্ভ করে।charchar

char *s = "hello";

sএক বা একাধিক (এই ক্ষেত্রে আরও) charএর পয়েন্টার হিসাবে ঘোষণা করে এবং এটি সরাসরি আক্ষরিক সমন্বিত একটি নির্দিষ্ট (কেবলমাত্র পঠনযোগ্য) অবস্থানের দিকে নির্দেশ করে "hello"


1
কোন পদ্ধতিটি ফাংশনগুলিতে ব্যবহার করা পছন্দনীয়, যদি সেগুলি পরিবর্তন করা হয় না, চ (কনস্ট্রেট চর এস []) বা এফ (কনস্ট্যান্ট চর * গুলি)?
সিএসহোডেলিয়া

1
@ পিএসহোডেলিয়া: একটি ফাংশন ঘোষণায় কোনও পার্থক্য নেই। উভয় ক্ষেত্রেই sএকটি পয়েন্টার const char
সিবি বেইলি

4
char s[] = "Hello world";

এখানে sএকটি অক্ষরের অ্যারে রয়েছে, যা আমরা চাইলে ওভাররাইট করা যেতে পারে।

char *s = "hello";

এই পয়েন্টারটি sনির্দেশ করে মেমরির কোথাও এই অক্ষর ব্লক তৈরি করতে একটি স্ট্রিং আক্ষরিক ব্যবহৃত হয়। আমরা এখানে এটি পরিবর্তন করে অবজেক্টের দিকে নির্দেশ করতে পারি, তবে যতক্ষণ না এটি একটি স্ট্রিংকে আক্ষরিক অর্থে অক্ষরের ব্লকটি চিহ্নিত করা যেতে পারে যা এটি পরিবর্তন করতে পারে না।


@bo পারসসন কেন দ্বিতীয় ক্ষেত্রে চরিত্রের ব্লক পরিবর্তন করা যায় না?
পঙ্কজ মাহাতো

3

সংযোজন হিসাবে, বিবেচনা করুন যে, কেবলমাত্র পঠনের উদ্দেশ্যে উভয়ের ব্যবহার একরকম, আপনি উভয়কে ফর্ম্যাট করে []বা *(<var> + <index>)ফর্ম্যাট করে একটি চর অ্যাক্সেস করতে পারেন :

printf("%c", x[1]);     //Prints r

এবং:

printf("%c", *(x + 1)); //Prints r

স্পষ্টতই, আপনি যদি চেষ্টা করার চেষ্টা করেন

*(x + 1) = 'a';

আপনি কেবলমাত্র পঠনযোগ্য মেমরিটিতে অ্যাক্সেস করার চেষ্টা করছেন আপনি সম্ভবত সেগমেন্টেশন ফল্ট পাবেন।


এটি x[1] = 'a';কোনওভাবেই সেগফল্ট হিসাবে পৃথক হবে না (প্ল্যাটফর্মের উপর নির্ভর করে অবশ্যই)।
glglgl

3

কেবল যোগ করতে: আপনি তাদের আকারগুলির জন্য বিভিন্ন মানও পাবেন।

printf("sizeof s[] = %zu\n", sizeof(s));  //6
printf("sizeof *s  = %zu\n", sizeof(s));  //4 or 8

উপরে উল্লিখিত হিসাবে, একটি অ্যারের জন্য '\0'চূড়ান্ত উপাদান হিসাবে বরাদ্দ করা হবে।


2
char *str = "Hello";

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

char str[] = "Hello";

স্ট্যাকের নতুন বরাদ্দ হওয়া মেমরিতে স্ট্রিংটি অনুলিপি করে। সুতরাং এতে কোনও পরিবর্তন আনার অনুমতি এবং আইনী is

means str[0] = 'M';

আরআরটি "মেলো" তে পরিবর্তন করবে।

আরও তথ্যের জন্য, অনুরূপ প্রশ্নের মাধ্যমে যান:

"চর * এস" দিয়ে শুরু করে "চর এস []" না দিয়ে স্ট্রিংয়ে লেখার সময় কেন আমি সেগমেন্টেশন ত্রুটি পেতে পারি?


0

এর ব্যাপারে:

char *x = "fred";

এক্স হল একটি মূল্যবান - এটি নির্ধারিত হতে পারে। তবে এর ক্ষেত্রে:

char x[] = "fred";

এক্স কোনও মূল্য নয়, এটি একটি মূল্য - আপনি এটি বরাদ্দ করতে পারবেন না assign


3
প্রযুক্তিগতভাবে, xএটি একটি অ-সংশোধনযোগ্য লভ্যালু। যদিও প্রায় সমস্ত প্রসঙ্গে, এটি তার প্রথম উপাদানটির একটি পয়েন্টারকে মূল্যায়ন করবে এবং সেই মানটি একটি মূল্য val
ক্যাফে

0
char *s1 = "Hello world"; // Points to fixed character string which is not allowed to modify
char s2[] = "Hello world"; // As good as fixed array of characters in string so allowed to modify

// s1[0] = 'J'; // Illegal
s2[0] = 'J'; // Legal

-1

এখানে মন্তব্যের আলোকে এটি সুস্পষ্ট হওয়া উচিত: চর * এস = "হ্যালো"; একটি খারাপ ধারণা, এবং খুব সংকীর্ণ সুযোগে ব্যবহার করা উচিত।

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

পর্যাপ্ত মেলোড্রামা, "কনস্ট" এর সাথে শোভাকর পয়েন্টারগুলি যখন কেউ অর্জন করতে পারে তা এখানে। (দ্রষ্টব্য: একজনকে ডান থেকে বামে পয়েন্টার ঘোষণাগুলি পড়তে হবে)) পয়েন্টারগুলির সাথে খেললে নিজেকে রক্ষা করার জন্য এখানে 3 টি ভিন্ন উপায়:

const DBJ* p means "p points to a DBJ that is const" 

- অর্থাৎ, ডিবিজে অবজেক্টটি পি এর মাধ্যমে পরিবর্তন করা যায় না।

DBJ* const p means "p is a const pointer to a DBJ" 

- অর্থাৎ, আপনি পি এর মাধ্যমে ডিবিজে অবজেক্ট পরিবর্তন করতে পারেন, তবে আপনি পয়েন্টার পি নিজেই পরিবর্তন করতে পারবেন না।

const DBJ* const p means "p is a const pointer to a const DBJ" 

- অর্থাৎ, আপনি পয়েন্টার পি নিজেই পরিবর্তন করতে পারবেন না, আপনি পি এর মাধ্যমে ডিবিজে অবজেক্টও পরিবর্তন করতে পারবেন না।

চেষ্টা করা কনস্ট-পিঁপড়া পরিবর্তনের সাথে সম্পর্কিত ত্রুটিগুলি সংকলন সময়ে ধরা পড়ে। কনস্টের জন্য কোনও রানটাইম স্পেস বা স্পিড পেনাল্টি নেই।

(অনুমান যে আপনি অবশ্যই সি ++ সংকলক ব্যবহার করছেন?)

--DBJ


এটি সবই সঠিক, তবে প্রশ্নের সাথে এর কোনও যোগসূত্র নেই। এবং আপনার সি ++ কম্পাইলার সম্পর্কে যতক্ষণ অনুমান করা যায়, প্রশ্নটি সি হিসাবে ট্যাগ করা হয়েছে, সি ++ হিসাবে নয়।
ফ্যাবিও বলছেন মনিকা

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