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




সি++ প্রোগ্রামিং বই (4)

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

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

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

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

কমা পরে "অনাথ" নোট করুন। এটি হ'ল কমার দিকে পরিচালিত করে যা প্রাথমিকভাবে বৃদ্ধি করা হয়েছিল।

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

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

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

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

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

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

নিম্নলিখিত অভিব্যক্তিটি কী তা ব্যাখ্যা করুন: কিছু someValue ? ++x, ++y : --x, --y 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 ফলাফল।


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

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

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

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

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

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

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

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

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


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

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

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

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

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

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


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

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

যৌক্তিক-বা অভিব্যক্তি ? এক্সপ্রেশন : অ্যাসাইনমেন্ট-এক্সপ্রেশন

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

  • someValue : যৌক্তিক-বা-এক্সপ্রেশন
  • ++x, ++y : প্রকাশ
  • ??? এসাইনমেন্ট-এক্সপ্রেশন --x, --y বা কেবল --x ?

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

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

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

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

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

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

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

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

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

সুতরাং যখন কিছু someValue true হয় তখন কী ঘটে?

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

আচরণটি "সংশোধন" করতে, আপনি --x, --y কে --x, --y সাথে একটি প্রাথমিক অভিব্যক্তিতে রূপান্তর করতে পারেন যা একটি অ্যাসাইনমেন্ট-এক্সপ্রেশন * এর বৈধ এন্ট্রি:

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

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

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





conditional-operator