কেন একটি +++++ বি কাজ করে না?


89

এই কোডটি নিম্নলিখিত ত্রুটি দেয়:

ত্রুটি: ইনক্রিমেন্ট অপারেন্ড হিসাবে মূল্যমানের প্রয়োজন

তবে আমি যদি পুরো জায়গা জুড়ে রাখি a++ +এবং ++bএটি ঠিক আছে works

প্রথম উদাহরণে ত্রুটিটির অর্থ কী?


4
এতক্ষণ পরও অবাক করা বিষয় যে কেউ আবিষ্কার করেননি যে আপনি যে সঠিক অভিব্যক্তিটির বিষয়ে জিজ্ঞাসা করছেন সেটিকে C99 এবং C11 মানের উদাহরণ হিসাবে ব্যবহার করা হয়েছে। এটি পাশাপাশি একটি ভাল ব্যাখ্যা দেয়। আমার উত্তরটিতে আমি তা অন্তর্ভুক্ত করেছি।
শফিক ইয়াহমুর

@ শফিকিক ইয়াঘমুর - এটি সি 11 -6.4 লেক্সিক্যাল এলিমেন্টস -6 এর 'উদাহরণ 2' । এটিতে বলা হয়েছে "প্রোগ্রামের খণ্ডটি x+++++yপার্স হিসাবে করা হয়েছে x ++ ++ + y, যা বর্ধিত অপারেটরগুলির উপর একটি বাধা লঙ্ঘন করে, যদিও পার্সটি x ++ + ++ yসঠিকভাবে প্রকাশ করতে পারে।"
জোনাথন লেফলার

উত্তর:


98

printf("%d",a+++++b);(a++)++ + bসর্বাধিক মাম্প বিধি অনুসারে ব্যাখ্যা করা হয় !

++(পোস্টফিক্স) একটিকে মূল্যায়ন করে না lvalueতবে এটির জন্য এটির অপরেন্ড প্রয়োজন lvalue

! 6.4 / 4 বলেছে যে পরবর্তী প্রিপ্রোসেসিং টোকন হ'ল অক্ষরের দীর্ঘতম ক্রম যা প্রিপ্রোসেসিং টোকেন গঠন করতে পারে "


181

সংকলক পর্যায়ে লেখা হয়। প্রথম পর্যায়ে লেক্সার বলা হয় এবং অক্ষরগুলিকে প্রতীকী কাঠামোতে পরিণত করে। সুতরাং "++" এর মতো কিছু হয়ে যায় enum SYMBOL_PLUSPLUS। পরে, পার্সার স্টেজ এটিকে একটি বিমূর্ত সিনট্যাক্স ট্রিে রূপান্তরিত করে, তবে এটি প্রতীকগুলি পরিবর্তন করতে পারে না। আপনি ফাঁকাগুলি সন্নিবেশ করে লেক্সারকে প্রভাবিত করতে পারেন (শেষ চিহ্নগুলির মধ্যে কোটগুলি না থাকলে)।

সাধারণ লেজাররা লোভী (কিছু ব্যতিক্রম সহ), তাই আপনার কোডটি ব্যাখ্যা করা হচ্ছে

পার্সারের ইনপুটটি প্রতীকগুলির একটি স্ট্রিম, তাই আপনার কোডটি এমন কিছু হবে:

যা পার্সার মনে করে সিন্টেক্সিকভাবে ভুল incor (মন্তব্যের উপর ভিত্তি করে সম্পাদনা করুন: শব্দার্থগতভাবে ভুল কারণ আপনি একটি আর-মানটিতে ++ প্রয়োগ করতে পারবেন না, যার ফলে +++ ফলাফল আসে)

হয়

যা ঠিক আছে। আপনার অন্যান্য উদাহরণ।


27
+1 ভাল ব্যাখ্যা। যদিও আমাকে নিটপিক করতে হবে: এটি সিনট্যাক্টিক্যালি সঠিক, এটিতে একটি অর্থগত ত্রুটি রয়েছে (যার ফলে লভালুকে বাড়ানোর চেষ্টা করা হয়েছে a++)।

7
a++একটি মূল্যায়ন ফলাফল।
Femaref

9
লেক্সারদের প্রসঙ্গে 'লোভী' অ্যালগরিদমকে সাধারণত ম্যাক্সিমাল মাঞ্চ ( en.wikedia.org/wiki/Maximal_munch ) বলা হয়।
জোজি

14
ভাল লাগল লোভী লেক্সিংয়ের জন্য অনেক ভাষায় একই রকম উদ্ভট কোণে মামলা রয়েছে। এখানে একটি অদ্ভুত বিষয় যেখানে অভিব্যক্তিটি দীর্ঘায়িত করা আরও ভাল করে তোলে: x = 10&987&&654&&321ভিবিএস স্ক্রিপ্টে অবৈধ, তবে উদ্ভটভাবে যথেষ্ট x = 10&987&&654&&&321আইনী।
এরিক লিপার্ট

4
এটি লোভের সাথে কিছুই করার নেই এবং এটির সাথে শৃঙ্খলা এবং প্রাধান্য দেওয়া। ++ এর পরে বেশি + তাই দুই ++ প্রথমে করা হবে। +++++ বি +++++ বিও হবে এবং ++ ++ + বি হবে না। লিঙ্কটির জন্য @ এমবিআইডি তে জমা দিন।

30

টোকেনগুলি তৈরি করতে সাধারণভাবে "সর্বাধিক বাঘ" অ্যালগরিদম যা বলা হয় তা ব্যবহার করে x এর অর্থ এটি অক্ষরগুলি যেমন পড়ছে, ততক্ষণ অক্ষরগুলি পড়া চালিয়ে যায় যতক্ষণ না এটি এমন কিছু মুখোমুখি হয় যা এটি ইতিমধ্যে যা আছে তেমন টোকেনের অংশ হতে পারে না (যেমন, যদি এটি অঙ্কগুলি পড়তে থাকে তবে এটির সংখ্যার যদি এটির মুখোমুখি হয়, একটি A, এটা জানেন। যে সংখ্যা অংশ হতে পারে না, তাই এটি স্টপ এবং পাতা Aপরের টোকেন শুরুতে হিসাবে ব্যবহার করার জন্য ইনপুট বাফারে)। এরপরে পার্সারে সেই টোকেনটি ফেরত দেয়।

এই ক্ষেত্রে, তার মানে +++++হিসাবে লেকসড হয় a ++ ++ + b। যেহেতু প্রথম পোস্ট-ইনক্রিমেন্টটি একটি মূল্য দেয়, দ্বিতীয়টি এটি প্রয়োগ করা যায় না এবং সংকলক একটি ত্রুটি দেয়।

কেবল এফডাব্লুআইডাব্লু, সি ++ এ আপনি operator++একটি লভালিউ অর্জন করতে ওভারলোড করতে পারেন , এটি এটিকে কাজ করতে দেয় allows উদাহরণ স্বরূপ:

আমার হাতে থাকা সি ++ কম্পাইলারের সাথে সংকলনগুলি এবং রান (যদিও এটি কিছুই করে না) (ভিসি ++, জি ++, কমউ)।


4
"উদাহরণস্বরূপ, যদি এটি অঙ্কগুলি পড়তে থাকে তবে এটির সংখ্যার সংখ্যাটি কী, যদি এটি একটি এ এর ​​মুখোমুখি হয়, তবে এটি জানে যে সংখ্যার অংশ হতে পারে না" 16FAএকটি পুরোপুরি সূক্ষ্ম হেক্সাডেসিমাল সংখ্যা যা একটি এ।
অর্পাল

4
@ নাইটক্র্যাকার: হ্যাঁ, তবে 0xশুরুতে এটি ছাড়া এখনও এটি একক হেক্সাডেসিমাল সংখ্যা নয় বরং 16অনুসরণ করবে FA
জেরি কফিন

@ জেরি কফিন: আপনি বলেন নি যে 0xসংখ্যার অংশ ছিল না।
orp

@ নাইটক্র্যাকার: না, আমি তা করি নি - বেশিরভাগ লোকেরা xএকটি সংখ্যা বিবেচনা করে না বলে মনে হয় এটি বেশ অপ্রয়োজনীয় বলে মনে হয়।
জেরি কফিন

14

এই সঠিক উদাহরণটি খসড়া সি 99 স্ট্যান্ডার্ড ( সি 11 তে একই বিবরণ ) বিভাগে is াকা হয়েছে 4.4 লেজিক্যাল এলিমেন্টের অনুচ্ছেদে 4 যা বলেছে:

যদি ইনপুট স্ট্রিম কোনও প্রদত্ত চরিত্রের প্রিপ্রোসেসিং টোকনে বিভক্ত করা হয়, তবে পরবর্তী প্রিপ্রোসেসিং টোকন হ'ল অক্ষরের দীর্ঘতম ক্রম যা প্রিপ্রোসেসিং টোকেন গঠন করতে পারে। [...]

যা সর্বাধিক মামুনের নিয়ম হিসাবেও পরিচিত যা অস্পষ্টতাগুলি এড়ানোর জন্য লেজিকাল বিশ্লেষণে ব্যবহৃত হয় এবং একটি বৈধ টোকেন গঠনের জন্য যতগুলি উপাদান গ্রহণ করে কাজ করে।

অনুচ্ছেদে দুটি উদাহরণ রয়েছে যা দ্বিতীয়টি আপনার প্রশ্নের সঠিক মিল এবং এটি নিম্নরূপ:

উদাহরণ 2 প্রোগ্রামের খণ্ড x +++++ y কে x +++++ y হিসাবে পার্স করা হয়েছে, যা ইনক্রিমেন্ট অপারেটরগুলির একটি সীমাবদ্ধতা লঙ্ঘন করে, যদিও পার্স x ++ + ++ y একটি সঠিক ভাব প্রকাশ করতে পারে।

যা আমাদের বলে:

হিসাবে বিশ্লেষণ করা হবে:

যা প্রথম পোস্টের ইনক্রিমেন্টের ফলাফল একটি মূল্যায়ন এবং পোস্ট বৃদ্ধি বৃদ্ধির জন্য লভ্যালু দরকার বলে পোস্ট বর্ধনের ক্ষেত্রে সীমাবদ্ধতা লঙ্ঘন করে। এটি বিভাগে 6.5.2.4 পোস্টফিক্স ইনক্রিমেন্ট এবং হ্রাস অপারেটরগুলির মধ্যে আচ্ছাদিত রয়েছে যা বলে ( জোর দেওয়া খনি ):

পোস্টফিক্স ইনক্রিমেন্ট বা হ্রাস অপারেটরের অপারেন্ডের যোগ্য বা অযোগ্য রিয়েল বা পয়েন্টার টাইপ থাকতে হবে এবং এটি একটি পরিবর্তনযোগ্য মূল্য হতে হবে।

এবং

পোস্টফিক্স ++ অপারেটরের ফলাফল অপারেন্ডের মান।

বই সি ++ Gotchas এছাড়াও এই ক্ষেত্রে কভার Gotcha #17 সর্বধিক মুখ না খুলিয়া চিবানো সমস্যা এটা একই সমস্যা সি ++ পাশাপাশি এবং এটি কিছু উদাহরণ দেয়। এটি ব্যাখ্যা করে যে নিম্নলিখিত অক্ষরগুলির সেট নিয়ে কাজ করার সময়:

লেজিকাল বিশ্লেষক তিনটি জিনিসের মধ্যে একটি করতে পারেন:

  • তিন টোকেন যেমন আচরণ: -, >এবং*
  • এটি দুটি টোকেন হিসাবে বিবেচনা করুন: ->এবং*
  • এটি একটি টোকেন হিসাবে বিবেচনা করুন: ->*

সর্বাধিক মুখ না খুলিয়া চিবানো নিয়ম এই অস্পষ্টতা এড়াতে পারেন। লেখক উল্লেখ করেছেন যে এটি ( সি ++ প্রসঙ্গে ):

এটি তৈরির চেয়ে অনেক বেশি সমস্যার সমাধান করে তবে দুটি সাধারণ পরিস্থিতিতে এটি বিরক্ত হয়।

প্রথম উদাহরণটি টেমপ্লেটগুলি হবে যার টেম্পলেট আর্গুমেন্টগুলিও টেমপ্লেট ( যা সি ++ 11 এ সমাধান করা হয়েছিল ), উদাহরণস্বরূপ:

যা সমাপনকারী কোণ বন্ধনীগুলিকে শিফট অপারেটর হিসাবে ব্যাখ্যা করে এবং তাই বিশৃঙ্খলার জন্য একটি স্থান প্রয়োজন:

দ্বিতীয় ক্ষেত্রে পয়েন্টারগুলির জন্য ডিফল্ট যুক্তি জড়িত থাকে, উদাহরণস্বরূপ:

*=এসাইনমেন্ট অপারেটর হিসাবে ব্যাখ্যা করা হবে , এই ক্ষেত্রে সমাধানটি ঘোষণার পরামিতিগুলির নামকরণ করা।


আপনি কি জানেন যে সি ++ 11 এর কোন অংশটি সর্বাধিক মঞ্চিং বিধি বলে? 2.2.3, 2.5.3 চিত্তাকর্ষক, কিন্তু সি দ্য যত স্পষ্ট না >>নিয়ম জিজ্ঞাসা করা হয়: stackoverflow.com/questions/15785496/...
সিরো Santilli郝海东冠状病六四事件法轮功

4
@ সিরোসন্তিলি 巴拿馬 文件 六四 事件 this এই উত্তরটি এখানে দেখুন
শফিক ইয়াঘমোর

সুন্দর ধন্যবাদ, এটি আমি যে অংশগুলিকে নির্দেশ করেছি সেগুলির মধ্যে একটি। আগামীকাল আমার ক্যাপটি বন্ধ হয়ে গেলে আমি আপনাকে
উজ্জীবিত করব

12

আপনার সংকলকটি মরিয়াভাবে পার্স করার চেষ্টা করে a+++++bএবং এর ব্যাখ্যা দেয় (a++)++ +b। এখন, পোস্ট-ইনক্রিমেন্টের ফলাফল ( a++) কোনও মূল্যমান নয় , অর্থাত্ এটি আবার পোস্ট-ইনক্রিমেন্ট করা যায় না।

উত্পাদন মানের প্রোগ্রামগুলিতে কখনও এ জাতীয় কোড লিখবেন না। আপনার পরে আসা দরিদ্র সহকর্মীর কথা চিন্তা করুন যাকে আপনার কোডটি ব্যাখ্যা করা দরকার।


10

a ++ পূর্ববর্তী মান, একটি মূল্য দেয়। আপনি এই বৃদ্ধি করতে পারবেন না।


7

কারণ এটি অনির্ধারিত আচরণের কারণ হয়।

এটা কোনটা?

হ্যাঁ, আপনি বা সংকলক এটি জানেন না।

সম্পাদনা:

আসল কারণ হ'ল অন্যরা যা বলেছিল:

এটি ব্যাখ্যা করা হয় (a++)++ + b

তবে পোস্ট ইনক্রিমেন্টের জন্য একটি লভ্যালু প্রয়োজন (যা নামের সাথে একটি পরিবর্তনশীল) তবে (a ++) একটি মূল্য প্রদান করে যা বাড়ানো যায় না ফলে আপনি যে ত্রুটি বার্তা পান তার দিকে বাড়ে।

এটি নির্দেশ করার জন্য অন্যদের কাছে THX।


4
আপনি একটি +++ বি এর জন্য একই কথা বলতে পারেন - (এ ++) + বি এবং একটি + (++ বি) এর বিভিন্ন ফলাফল থাকতে পারে।
মাইকেল চিনেন

4
প্রকৃতপক্ষে পোস্টফিক্স ++ এর উপসর্গ ++ এর চেয়ে বেশি অগ্রাধিকার রয়েছে, তাই a+++bসর্বদা হয়a++ + b
এমবিডিডি

4
আমি মনে করি না এটি সঠিক উত্তর, তবে আমি ভুল হতে পারি। আমি মনে করি লেক্সার এটি এমনটি সংজ্ঞা দেয় a++ ++ +bযা পার্স করা যায় না।
লু ফ্রাঙ্কো

4
আমি এই উত্তরের সাথে একমত নই। 'অপরিজ্ঞাত আচরণ' টোকনাইজেশন অস্পষ্টতার থেকে একেবারে পৃথক; এবং আমি সমস্যাটি হয় বলে মনে করি না।
জিম ব্ল্যাকার

4
এখনই ... আমার দৃশ্য "অন্যথায় একটি +++++ বি ((A ++) ++,) + + বি মূল্যায়ন করবেন" হয় a+++++b না মূল্যায়ন (a++)++)+b। অবশ্যই আপনি যদি সেই বন্ধনীগুলি সন্নিবেশ করান এবং পুনর্নির্মাণ করেন তবে জিসিসির সাথে ত্রুটি বার্তাটি পরিবর্তন হয় না।
জিম ব্ল্যাকার 13

5

আমার মনে হয় সংকলকটি এটিকে দেখে

সি = ((একটি ++) ++) + খ

++অপারেন্ড হিসাবে একটি মান থাকতে হবে যা পরিবর্তিত হতে পারে। a এমন একটি মান যা পরিবর্তিত হতে পারে। a++তবে এটি 'মূল্যায়ন', এটি সংশোধন করা যায় না।

যাইহোক ত্রুটি জিসিসি সি তে আমি দেখতে একই, কিন্তু ভিন্নভাবে-ভাষায়: lvalue required as increment operand


0

এই precesion ক্রম অনুসরণ করুন

1। ++ (প্রাক বৃদ্ধি)

2. + - (যোগ বা বিয়োগ)

3. "x" + "y" উভয় ক্রম যুক্ত করুন

int a = 5,b = 2; printf("%d",a++ + ++b); //a is 5 since it is post increment b is 3 pre increment return 0; //it is 5+3=8

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