কমা সহ টর্নারি অপারেটর সত্য ক্ষেত্রে কেবলমাত্র একটি অভিব্যক্তিকে মূল্যায়ন করে?


119

আমি বর্তমানে সি ++ প্রিমার বইটি দিয়ে সি ++ শিখছি এবং বইটির একটি অনুশীলন হ'ল:

নিম্নলিখিত অভিব্যক্তিটি কী তা ব্যাখ্যা করুন: someValue ? ++x, ++y : --x, --y

আমরা কী জানি? আমরা জানি যে কলামা অপারেটরের চেয়ে টের্নারি অপারেটরের উচ্চতর প্রাধান্য রয়েছে। বাইনারি অপারেটরগুলির সাথে এটি বোঝা বেশ সহজ ছিল, তবে টার্নারি অপারেটরের সাথে আমি কিছুটা লড়াই করছি। বাইনারি অপারেটরগুলির সাথে "উচ্চতর প্রাধান্য থাকা" এর অর্থ হ'ল আমরা উচ্চতর প্রাধান্য সহ অভিব্যক্তিটির চারপাশে প্রথম বন্ধনী ব্যবহার করতে পারি এবং এটি কার্যকর করে পরিবর্তন করে না।

টার্নারি অপারেটরের জন্য আমি এটি করব:

(someValue ? ++x, ++y : --x, --y)

কার্যকরভাবে একই কোডটির ফলে ফলাফল তৈরি হয় যা সংকলক কোডটি কীভাবে গ্রুপবদ্ধ করবে তা বুঝতে আমাকে সহায়তা করে না।

তবে, একটি সি ++ সংকলক দিয়ে পরীক্ষা করা থেকে আমি জানি যে এক্সপ্রেশনটি সংকলন করে এবং কোনও :অপারেটর নিজে থেকে কী দাঁড়াতে পারে তা আমি জানি না । সুতরাং সংকলকটি টেরিনারি অপারেটরটিকে সঠিকভাবে ব্যাখ্যা করে বলে মনে হচ্ছে।

তারপরে আমি প্রোগ্রামটি দুটিভাবে সম্পাদন করেছি:

#include <iostream>

int main()
{
    bool someValue = true;
    int x = 10, y = 10;

    someValue ? ++x, ++y : --x, --y;

    std::cout << x << " " << y << std::endl;
    return 0;
}

ফলাফল স্বরূপ:

11 10

অন্যদিকে someValue = falseএটি মুদ্রণ করে:

9 9

সি ++ সংকলক কেন কোড তৈরি করবে যে টের্নারি অপারেটরের সত্যিকারের শাখার জন্য কেবল বৃদ্ধি হয় x, যখন ত্রৈমাসীর মিথ্যা শাখার জন্য এটি উভয়ই হ্রাস পায় xএবং y?

আমি এমনকি সত্য-শাখার চারপাশে প্রথম বন্ধনী স্থাপন করা পর্যন্ত গিয়েছিলাম:

someValue ? (++x, ++y) : --x, --y;

কিন্তু এটি এখনও ফলাফল 11 10


5
"অগ্রাধিকার" সি ++ এ কেবল একটি উদ্ভুত ঘটনা। এটি সরাসরি ভাষার ব্যাকরণটি সরাসরি দেখতে এবং এক্সপ্রেশনগুলি কীভাবে কাজ করে তা দেখতে সহজ হতে পারে।
কেরেক এসবি

26
আমরা পরোয়া করি না যে নীতিগুলো সম্পর্কে অনেক। :-) আপনাকে এখানে জিজ্ঞাসা করতে হবে তা নির্দেশ করে যে কোডটি কখনও আপনার সহকারী প্রোগ্রামারদের দ্বারা কোনও কোড পর্যালোচনা পাস করে না। এটি আসলে কীভাবে দরকারীের চেয়ে কম কাজ করে তা সম্পর্কে জ্ঞান তৈরি করে। আপনি অবাস্তব সি সি প্রতিযোগিতায় অংশ নিতে না চাইলে অবশ্যই।
বো পারসন

5
@ বোপারসন এর কাছ থেকে শিখার মতো উদাহরণ ছাড়াই ভবিষ্যতের পর্যালোচকরা কখনই শিখবেন না কেন তাদের এই উত্পাদন থেকে প্রত্যাখ্যান করা উচিত।
লুশেনকো

8
@ লুশেনকো - সতর্কতা বেলগুলি যেভাবেই বাজানো উচিত। একই বিবৃতিতে একাধিক বৃদ্ধি এবং হ্রাস (ডিঙ, ডিং, ডিং!)। আপনি যদি অন্যথায় (ডিং, ডিং, ডিং!) ব্যবহার করতে পারতেন তখন একটি টার্নারি অপারেটর। অপেক্ষা করুন, এই কমাগুলি কি ভয়ঙ্কর কমা অপারেটর? (ডিং, ডিং, ডিং!) এই সমস্ত অপারেটরের সাথে কি কোনও নজির আছে? (ডিং, ডিং, ডিং!) সুতরাং আমরা কখনই এটি ব্যবহার করতে সক্ষম হব না। তাহলে কেন কিছু হয় তা নির্ধারণে সময় নষ্ট করবেন?
বো পারসন

4
মাইনর নিট: জন্য নাম ?হয় শর্তসাপেক্ষ অপারেটরটেরিনারি অপারেটর শব্দটির অর্থ তিনটি সংযোজনযুক্ত অপারেটর। শর্তসাপেক্ষ অপারেটরটি টেরিনারি অপারেটরের একটি উদাহরণ , তবে কোনও ভাষায় (তাত্ত্বিকভাবে) একাধিক ত্রিনিরি অপারেটর থাকতে পারে।
বিটিএ

উত্তর:


122

@ রাকেট যেমন তাদের দুর্দান্ত উত্তরে বলেছিলেন, এটি কৌশলপূর্ণ। আমি এটি একটি সামান্য যোগ করতে চাই।

টেরিনারি অপারেটরের অবশ্যই ফর্ম থাকতে হবে:

লজিকাল-বা- ? এক্সপ্রেশন : এক্সাইশন-এক্সপ্রেশন

সুতরাং আমরা নিম্নলিখিত ম্যাপিংস আছে:

  • someValue: যৌক্তিক-বা-প্রকাশ
  • ++x, ++y: প্রকাশ
  • ??? হয় নিয়োগ প্রকাশ --x, --y শুধুমাত্র বা --x?

বাস্তবে এটি কেবল --xকারণ একটি অ্যাসাইনমেন্ট এক্সপ্রেশনটি কমা দ্বারা পৃথক দুটি এক্সপ্রেশন হিসাবে পার্স করা যায় না (সি ++ এর ব্যাকরণের নিয়ম অনুসারে), সুতরাং --x, --yএকটি অ্যাসাইনমেন্ট এক্সপ্রেশন হিসাবে বিবেচনা করা যায় না ।

যা এরকম দেখতে দেখতে ত্রৈমাসিক (শর্তসাপেক্ষে) এক্সপ্রেশন অংশে ফলাফল করে:

someValue?++x,++y:--x

এটি পঠনযোগ্যতার স্বার্থে যদি প্রথম বন্ধনী হিসাবে++x,++y গণনা করা বিবেচনা করতে সহায়তা করতে পারে ; এর মধ্যে থাকা এবং যে কোনও কিছুই শর্তাধীন পরে ক্রমযুক্ত করা হবে । (আমি তাদের পোস্টের বাকী অংশের জন্য বন্ধনীরূপে দেব)।(++x,++y)?:

এবং এই ক্রমে মূল্যায়ন:

  1. someValue?
  2. (++x,++y)বা --x( bool1 ফলাফলের উপর নির্ভর করে )

এই অভিব্যক্তিটি তখন কমা অপারেটরের বাম উপ-এক্সপ্রেশন হিসাবে বিবেচিত হবে, ডান সাব-এক্সপ্রেশনটি --yযেমন রয়েছে:

(someValue?(++x,++y):--x), --y;

যার অর্থ বাম দিকটি একটি বাতিল হওয়া মূল্য প্রকাশ , যার অর্থ এটি অবশ্যই মূল্যায়ন করা হয়, তবে তারপরে আমরা ডান দিকটি মূল্যায়ন করি এবং এটি ফিরে পাই।

তাহলে কখন someValueহয় true?

  1. (someValue?(++x,++y):--x)এক্সিকিউট এবং ইনক্রিমেন্ট xএবং yহতে 11এবং11
  2. বাম প্রকাশটি বাতিল করা হয়েছে (যদিও বৃদ্ধির পার্শ্ব প্রতিক্রিয়াগুলি রয়ে গেছে)
  3. আমরা কমা অপারেটরের ডান হাতটি মূল্যায়ন করি: --yযা পরে yফিরে আসে ments10

"ফিক্স" করার আচরণ, আপনাকে গোষ্ঠী পারেন --x, --yপ্রথম বন্ধনী সঙ্গে একটি সেটিকে রুপান্তর প্রাথমিক অভিব্যক্তি যা হয় একটি জন্য একটি বৈধ এন্ট্রি নিয়োগ প্রকাশ *:

someValue?++x,++y:(--x, --y);

* এটি একটি বরং মজাদার দীর্ঘ শৃঙ্খলা যা একটি অ্যাসাইনমেন্ট-এক্সপ্রেশনটিকে প্রাথমিক অভিব্যক্তির সাথে আবার সংযুক্ত করে:

অ্যাসাইনমেন্ট-এক্সপ্রেশন --- (সমন্বিত থাকতে পারে) -> শর্তসাপেক্ষ-এক্সপ্রেশন -> লজিকাল-বা-এক্সপ্রেশন -> যৌক্তিক-এবং-এক্সপ্রেশন -> অন্তর্ভুক্ত-বা-প্রকাশ -> একচেটিয়া-বা-প্রকাশ - -> এবং-প্রকাশ -> সাম্যতা-প্রকাশ -> সম্পর্কযুক্ত-প্রকাশ -> শিফট-এক্সপ্রেশন -> সংযোজন-প্রকাশ -> গুণক-প্রকাশ -> বিকাল-প্রকাশ -> castালাই-প্রকাশ -> unary- এক্সপ্রেশন -> পোস্টফিক্স-এক্সপ্রেশন -> প্রাথমিক-এক্সপ্রেশন


10
ব্যাকরণ নিয়মগুলি উন্মোচনের সমস্যাটি গ্রহণ করার জন্য ধন্যবাদ; এটি করার মাধ্যমে দেখা যায় যে আপনি বেশিরভাগ পাঠ্যপুস্তকগুলিতে খুঁজে পাবেন তার চেয়ে বেশি সি ++ এর ব্যাকরণ রয়েছে।
এসডেনহ্যাম

4
@ এসডেনহ্যাম: লোকেরা যখন জিজ্ঞাসা করে যে "এক্সপ্রেশন ওরিয়েন্টেড ভাষাগুলি" কেন দুর্দান্ত (যেমন কখন { ... }একটি অভিব্যক্তি হিসাবে বিবেচনা করা যেতে পারে), তখন আমার কাছে এখন একটি উত্তর আছে => এটি এমন কৌতুকপূর্ণ আচরণ করে এমন কমা অপারেটরটির পরিচয় করিয়ে দেওয়া এড়ানো উচিত।
ম্যাথিউ এম।

assignment-expressionচেইন সম্পর্কে পড়তে আমাকে একটি লিঙ্ক দিতে পারেন ?
এমআইপি

@ এমআইপি: আমি এটিকে মান থেকে উত্তোলন করেছি, আপনি এটি গ্রাম.এক্সপি
অ্যান্ডি

88

বাহ, এটা কৃপণ।

সংকলকটি আপনার এক্সপ্রেশনটিকে এই হিসাবে দেখবে:

(someValue ? (++x, ++y) : --x), --y;

টেরিনারি অপারেটরের একটি দরকার :, এটি সেই প্রসঙ্গে নিজেই দাঁড়াতে পারে না, তবে এর পরে, কমাটি মিথ্যা মামলার সাথে সম্পর্কিত হওয়ার কোনও কারণ নেই।

আপনি কেন যে আউটপুটটি পান তা এখন এটি আরও বোধগম্য হতে পারে। যদি someValueসত্য হয় তাহলে ++x, ++yএবং --yমৃত্যুদন্ড কার্যকর, যা কার্যকরভাবে পরিবর্তন করে না yকিন্তু এক যোগ x

যদি someValueমিথ্যা হয়, তবে --xএবং --yকার্যকর করা হয়, উভয়কে একে একে হ্রাস করে।


42

সি ++ সংকলক কেন কোড তৈরি করবে যে টের্নারি অপারেটরের সত্যিকারের শাখার জন্য কেবল ইনক্রিমেন্ট রয়েছে x

আপনি যা ঘটেছে তা ভুল ব্যাখ্যা করেছেন। সত্য শাখা বাড়তি উভয় xএবং y। যাইহোক, এর yপরে অবিলম্বে হ্রাস করা হয়, নিঃশর্তভাবে।

এখানে এটি কীভাবে ঘটে: শর্তসাপেক্ষ অপারেটরের সি ++ তে কমা অপারেটরের চেয়ে বেশি অগ্রাধিকার রয়েছে , সংকলক নীচের মত প্রকাশটি পার্স করে:

   (someValue ? ++x, ++y : --x), (--y);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^  ^^^^^

--yকমা পরে "অনাথ" নোট করুন । এটি হ্রাসকে বাড়ে yযা প্রাথমিকভাবে বৃদ্ধি করা হয়েছিল।

আমি এমনকি সত্য-শাখার চারপাশে প্রথম বন্ধনী স্থাপন করা পর্যন্ত গিয়েছিলাম:

someValue ? (++x, ++y) : --x, --y;

আপনি সঠিক পথে ছিলেন, তবে আপনি একটি ভুল শাখাটি প্রথম বন্ধনীভূত করেছেন: আপনি অন্য শাখাটি বন্ধনীরূপে এটি ঠিক করতে পারেন:

someValue ? ++x, ++y : (--x, --y);

ডেমো (11 11 প্রিন্ট)


5

আপনার সমস্যাটি হ'ল ত্রৈমাসিকের অভিব্যক্তিটি আসলেই কমা অপেক্ষা বেশি প্রাধান্য পায় না। প্রকৃতপক্ষে, সি ++ এর সুনির্দিষ্টভাবে প্রাধান্য দ্বারা বর্ণনা করা যায় না - এবং এটি ঠিক ত্রৈমাসিক অপারেটর এবং কমা যেখানে এটি ভেঙে যায় তার মধ্যে মিথস্ক্রিয়া।

a ? b++, c++ : d++

হিসাবে বিবেচনা করা হয়:

a ? (b++, c++) : d++

(কমা এমন আচরণ করে যেমন এর উচ্চতর প্রাধান্য রয়েছে)। অন্য দিকে,

a ? b++ : c++, d++

হিসাবে বিবেচনা করা হয়:

(a ? b++ : c++), d++

এবং টেরিনারি অপারেটর উচ্চতর প্রাধান্য।


আমি মনে করি এটি মধ্যবর্তী লাইনের জন্য কেবলমাত্র একটি বৈধ পার্স আছে, তাই এটি এখনও প্রাধান্যের মধ্যেই রয়েছে? এখনও একটি সহায়ক উদাহরণ
sudo rm -rf স্ল্যাশ

2

উত্তরে এমন একটি বিন্দু যা উপেক্ষা করা হয়েছে (যদিও মন্তব্যগুলিতে স্পর্শ করা হয়েছে) তা হ'ল শর্তসাপেক্ষে অপরিবর্তিতভাবে দুটি ভ্যারিয়েবলের মধ্যে দুটি মান নির্ধারণের জন্য একটি শর্টকাট হিসাবে বাস্তব কোডটিতে নিয়মিত ব্যবহার করা হয় (ডিজাইন দ্বারা উদ্দিষ্ট?)

সুতরাং, বৃহত্তর প্রসঙ্গটি হবে:

whatIreallyWanted = someValue ? ++x, ++y : --x, --y;

যা এটির মুখে অযৌক্তিক, তাই অপরাধগুলি বহুগুণে:

  • ভাষা একটি কার্যক্রমে হাস্যকর পার্শ্ব প্রতিক্রিয়াগুলির অনুমতি দেয়।
  • সংকলক আপনাকে সতর্ক করে দেয়নি যে আপনি উদ্ভট কাজগুলি করছেন।
  • বইটি 'কৌশল' প্রশ্নগুলিতে ফোকাস করছে বলে মনে হচ্ছে। কেউ কেবল এই আশা করতে পারে যে পিছনের উত্তরটি ছিল "এই অভিব্যক্তিটি যা কিছু করে তা প্রত্যাশিত পার্শ্ব প্রতিক্রিয়া তৈরি করার জন্য একটি বিদ্রূপযুক্ত উদাহরণে অদ্ভুত প্রান্তের উপর নির্ভর করে Never এটি কখনও করবেন না do"

1
দুটি ভেরিয়েবলের মধ্যে একটি নির্ধারণ করা হল টেরিনারি অপারেটরের স্বাভাবিক ঘটনা, তবে এমন কিছু অনুষ্ঠান থাকে যখন এর এক্সপ্রেশন ফর্মটি ব্যবহার করা কার্যকর হয় if(উদাহরণস্বরূপ, লুপের জন্য একটি ইনক্রিমেন্ট এক্সপ্রেশন)। বৃহত্তর প্রসঙ্গটি ভালভাবে for (x = 0, y=0; x+y < 100; someValue?(++x, ++y) :( --x, --y))একটি লুপের সাথে থাকতে পারে যা সংশোধন করতে পারে xএবং yস্বাধীনভাবে।
মার্টিন বোনার

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