সি (+ +--) এর প্রকাশ সি


9

আমি এই প্রশ্নটি একটি পরীক্ষায় দেখেছি যাতে আমাদের নীচের কোডটির আউটপুট বলতে হবে।

#include<stdio.h>

int main(){
    int k = 0;
    while(+(+k--)!=0)
    k=k++;
    printf("%d\n", k);  
    return 0;
}

আউটপুট হয় -1। যদিও এই উত্তরটি আমি কেন জানি না।

+(+k--)সিতে অভিব্যক্তিটির অর্থ কী?


4
এটি কি এভাবে বিন্যাসিত হয়েছিল? এর অর্থ ;-)
পিটার - মনিকা পুনরায়

3
ইঙ্গিত: বাস্তব জীবনে কখনই বিএস কোডটি লিখবেন না।
জ্যাবারওয়কি

5
এটি ইউবি নয় । আমার উত্তর দেখুন।
dbush

@ পিটার-রেইনস্টেটমোনিকা হ্যাঁ এটি এর মতো ফর্ম্যাট হয়েছিল।
অঙ্কুর গৌতম

2
এর স্বতঃস্ফূর্ত প্রকৃতির এবং উদ্ভট মোচড়ের কারণে - k=k++এটি অপরিজ্ঞাপিত, তবে এটি অপরিজ্ঞাত নয় কারণ এটি কোনও অচল অবস্থায় থাকার কারণে কখনই কার্যকর করা হয় না - আমি এই প্রশ্নের নকল হিসাবে বন্ধ করার পক্ষে ভোট দিচ্ছি ।
স্টিভ সামিট

উত্তর:


10

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

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

কোডটির দুটি বিভ্রান্তিকর দিক রয়েছে, আজব অবস্থা:

while(+(+k--)!=0)

এবং এটি নিয়ন্ত্রিত বিবৃত বিবৃতি:

k=k++;

আমি প্রথম দ্বিতীয় অংশটি কভার করতে যাচ্ছি।

যদি আপনার মতো ভেরিয়েবল থাকে kতবে আপনি 1 দ্বারা বর্ধন করতে চান, সি আপনাকে একটি নয়, দুটি নয়, তিন নয়, চারটি ভিন্ন উপায় এটি করার জন্য:

  1. k = k + 1
  2. k += 1
  3. ++k
  4. k++

এই অনুগ্রহ সত্ত্বেও (বা সম্ভবত এটি কারণে), কিছু প্রোগ্রামার বিভ্রান্ত হয়ে পড়ে এবং পছন্দ মতো কনফারেন্সগুলি কাশি করে

k = k++;

এইটি করার কথাটি যদি আপনি বুঝতে না পারেন তবে চিন্তা করবেন না: কেউ পারে না। এই অভিব্যক্তি পরিবর্তন করতে দুটি ভিন্ন প্রচেষ্টা রয়েছে kএর মান ( k =অংশ, এবং k++অংশ), এবং কারণ সি কোন নিয়ম বলতে এর চেষ্টা পরিবর্তন "জয়", ভালো একটি অভিব্যক্তি আনুষ্ঠানিকভাবে হয় যা অনির্দিষ্ট , শুধু তাই নয়, যার অর্থ এর কোনও নির্ধারিত অর্থ নেই, তবে এটি রয়েছে এমন পুরো প্রোগ্রামটি সন্দেহজনক।

এখন, আপনি যদি খুব মনোযোগ দিয়ে দেখুন, আপনি দেখতে পাবেন যে এই বিশেষ প্রোগ্রামে, লাইনটি k = k++আসলে কার্যকর হয় না, কারণ (আমরা যেমন দেখতে চলেছি) নিয়ন্ত্রণকারী অবস্থা প্রাথমিকভাবে মিথ্যা, সুতরাং লুপটি 0 বার চলে । তাই এই বিশেষ প্রোগ্রাম নাও করতে পারে আসলে অনির্ধারিত হতে - কিন্তু এটি এখনও pathologically বিভ্রান্তিকর হচ্ছে।

এই প্রকারের অনির্ধারিত আচরণ সম্পর্কিত সমস্ত প্রশ্নের উত্তরগুলিও এই দেখুন ।

কিন্তু আপনি k=k++অংশ সম্পর্কে জিজ্ঞাসা করেন নি । আপনি প্রথম বিভ্রান্তিকর অংশ, +(+k--)!=0অবস্থা সম্পর্কে জিজ্ঞাসা করেছিলেন । এই অদ্ভুত দেখায়, কারণ এটি হয় অদ্ভুত। কেউ কখনও কখনও আসল প্রোগ্রামে এ জাতীয় কোড লিখবে না। সুতরাং এটি কীভাবে বুঝতে হয় তা শেখার কোনও কারণ নেই। (হ্যাঁ, এটি সত্য, কোনও সিস্টেমের সীমানা অন্বেষণ করা আপনাকে এর সূক্ষ্ম বিষয়গুলি সম্পর্কে জানতে সাহায্য করতে পারে, তবে আমার বইতে কল্পিত, চিন্তা-চিত্তাকর্ষক অনুসন্ধান বনাম ডেনারহেড, অবমাননাকর অন্বেষণের মধ্যে একটি সুন্দর স্পষ্ট লাইন রয়েছে এবং এই অভিব্যক্তিটি খুব স্পষ্টভাবে এই লাইনের ভুল দিক।)

যাইহোক, আসুন পরীক্ষা করা যাক +(+k--)!=0। (এবং এটি করার পরে, আসুন এটি সম্পর্কে সমস্ত কিছু ভুলে যাওয়া উচিত)) এর মতো কোনও অভিব্যক্তিটি ভিতর থেকে বুঝতে হবে। আমি অনুমান করি আপনি কি জানেন

k--

আছে। এটির kবর্তমান মানটি নেয় এবং বাকী বাক্যটিতে এটি "রিটার্ন" দেয় এবং এটি আরও বা কম সময়ে একসাথে হ্রাস পায় k, এটি পরিমাণটি k-1ফিরিয়ে দেয় k

কিন্তু তাহলে কি করবে +? এটি অ্যানারি প্লাস, বাইনারি প্লাস নয়। এটি ঠিক একাকার বিয়োগের মতো। আপনি জানেন যে বাইনারি বিয়োগ বিয়োগ করে: প্রকাশ

a - b

a থেকে বি বিয়োগ করে। এবং আপনি জানেন যে অযৌক্ত বিয়োগ জিনিসগুলিকে অবজ্ঞা করে: প্রকাশ expression

-a

আপনি একটি এর নেতিবাচক দেয়। অযৌক্তিকর +কাজটি হ'ল ... মূলত কিছুই নয়। +aদেয় আপনি aএর মান, নেতিবাচক ইতিবাচক ও নেতিবাচক মান ধনাত্মক মান পরিবর্তন করার পর। তাই প্রকাশ

+k--

আপনাকে যা k--দিয়েছে তা দেয় , kএটির পুরানো মান।

কিন্তু আমরা শেষ করিনি, কারণ আমাদের রয়েছে

+(+k--)

এটি +k--আপনাকে যা দিয়েছে তা কেবল গ্রহণ করে এবং +এটিতে আবার অকার্যকর প্রয়োগ করে । সুতরাং এটি আপনাকে যা দেয় তাই দেয় +k--যা k--যা আপনাকে দিয়েছিল যা kপুরানো মূল্য ছিল old

সুতরাং শেষ পর্যন্ত, অবস্থা

while(+(+k--)!=0)

আরও সাধারণ অবস্থা হিসাবে ঠিক একই জিনিস

while(k-- != 0)

করে ফেলতাম. (এটি আরও জটিল-দৃষ্টিকোণ অবস্থা যেমন while(+(+(+(+k--)))!=0)করত তেমনই কাজ করে And এবং এই প্রথম বন্ধনীগুলি সত্যই প্রয়োজনীয় নয়; এটিও একই কাজ করে while(+ + + +k--!=0)done

এমনকি "সাধারণ" অবস্থাটি কী তা নির্ধারণ করা হচ্ছে

while(k-- != 0)

নাটক এক ধরণের। এই লুপটিতে দুটি ধরণের জিনিস চলছে: লুপটি সম্ভাব্য একাধিকবার চলার সাথে সাথে আমরা যাচ্ছি:

  1. আরও ছোট এবং আরও ছোট k--করতে, চালিয়ে যানk
  2. লুপের বডিটি চালিয়ে যান, যা কিছু তা করে।

তবে আমরা k--লুপটি দিয়ে অন্য কোনও ট্রিপ নেব কিনা তা সিদ্ধান্ত নেওয়ার আগে (বা প্রক্রিয়াধীন) এখনই অংশটি ঠিক করি । এবং মনে রাখবেন যে এটি হ্রাস করার আগে k--তার পুরানো মানটিকে "ফিরিয়ে দেয়" k। এই প্রোগ্রামে, প্রাথমিক মান k0 হয় তাই k--পুরানো মান 0 "ফিরে" যাচ্ছে, তারপরে k-1 এ আপডেট করুন। তবে বাকি শর্তটি হল != 0- তবে আমরা যেমনটি দেখেছি, প্রথমবার শর্তটি পরীক্ষা করার সময় আমরা একটি 0 পেয়েছিলাম। সুতরাং আমরা লুপের মাধ্যমে কোনও ট্রিপ করব না, তাই আমরা কার্যকর করার চেষ্টা করব না সমস্যাযুক্ত বিবৃতি k=k++এ সব।

অন্য কথায়, এই বিশেষ লুপে, যদিও আমি বলেছিলাম যে "এখানে দুটি ধরণের জিনিস চলছে", এটি প্রমাণিত হয় যে জিনিসটি 1 একবার ঘটে, তবে জিনিসটি শূন্য বার ঘটে।

যে কোনও হারে, আমি আশা করি এটি এখন পর্যাপ্তরূপে পরিষ্কার হয়ে গেছে যে কোনও প্রোগ্রামের এই দরিদ্র অজুহাতটি প্রিন্টিং -১ এর চূড়ান্ত মান হিসাবে শেষ হয় না k। সাধারণত, আমি এই জাতীয় কুইজের প্রশ্নের উত্তর দিতে পছন্দ করি না - এটি প্রতারণার মতো বলে মনে হয় - তবে এই ক্ষেত্রে, যেহেতু আমি কৌতূহলের সাথে মহড়ার পুরো বিষয়টিটির সাথে একমত নই, তাতে আমার আপত্তি নেই।


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

4
@Scott আছে কল্পিত, এবং তারপর সেখানে কল্পিত । মনে করুন আপনি একজন ড্রাইভার প্রশিক্ষণ প্রশিক্ষক। মনে করুন আপনি আপনার ছাত্রকে বেসবল ব্যাট দিয়ে মাথা পিটিয়ে তাকে ভারী ডাউনটাউন ট্র্যাফিক দিয়ে গাড়ি চালিয়ে যেতে বলুন। যুক্তিযুক্তভাবে, শিক্ষার্থী একটি সম্ভাব্য-দরকারী দক্ষতা শিখবে। তবে আমি এই অপব্যবহার বলেছি। এবং আমি আমার মতে দাঁড়িয়েছি যে এই প্রশ্নের কোডটি আপত্তিজনক, নেতিবাচক শিক্ষাগত মান সহ।
স্টিভ সামিট

1
"আমি আমার মতামত দিয়ে দাঁড়াচ্ছি" এটি ন্যায্য, তবে এখানে মূলশব্দটি "মতামত"। স্ট্যাকওভারফ্লো উত্তরটি কারও মতামত প্রকাশের অনুকূল জায়গা নয়। :)
স্কট

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

11

প্রথম নজরে দেখে মনে হচ্ছে এই কোডটি অনির্ধারিত আচরণের দিকে আহ্বান করে তবে এটি ক্ষেত্রে নেই।

প্রথমে কোডটি সঠিকভাবে ফর্ম্যাট করা যাক:

#include<stdio.h>

int main(){
    int k = 0;
    while(+(+k--)!=0)
        k=k++;
    printf("%d\n", k);  
    return 0;
}

সুতরাং এখন আমরা দেখতে পাচ্ছি যে স্টেটমেন্টটি k=k++;লুপের ভিতরে রয়েছে।

এখন প্রোগ্রামটি ট্রেস করা যাক:

যখন লুপ শর্ত প্রথম মূল্যায়ন করা হয়, kমূল্য আছে 0. অভিব্যক্তি k--রয়েছে বর্তমান মান k, যা 0, এবং kএকটি পার্শ্ব প্রতিক্রিয়া হিসেবে decremented করা হয়। সুতরাং এই বিবৃতিটির পরে মান k-1 হয়।

+এই অভিব্যক্তিটির শীর্ষস্থানীয় মানটির কোনও প্রভাব নেই, সুতরাং +k--0 এবং একইভাবে মূল্যায়ন করা হয়+(+k--) 0 তে মূল্যায়ন করা হয়।

তারপরে !=অপারেটরটি মূল্যায়ন করা হয়। যেহেতু 0!=0মিথ্যা তাই লুপের শরীরে প্রবেশ করা যায় না । যদি শরীরে প্রবেশ করানো হয়, আপনি অনির্ধারিত আচরণের জন্য আবেদন করেছিলেন কারণ k=k++উভয়ই kঅনুক্রম বিন্দু ছাড়াই পড়ে এবং লেখেন । তবে লুপটি প্রবেশ করা হয়নি, সুতরাং কোনও ইউবি নেই।

শেষ পর্যন্ত kমুদ্রিত হয় যা -1 হয়।


1
এটি একটি খোলামেলা, অস্তিত্বহীন, দার্শনিক, প্রভাবশালী প্রশ্ন যা বাস্তবায়িত হয়নি এমন অপরিজ্ঞাত আচরণ অপরিজ্ঞাত নয় কিনা whether এটি কি সংজ্ঞায়িত নয়? আমি তাই মনে করি না.
স্টিভ সামিট

2
পছন্দ করেছেন if (x != NULL) *x = 42;এটি কখন অপরিবর্তিত x == NULL? অবশ্যই না. কোডের কিছু অংশে নির্ধারিত আচরণ ঘটে না যা কার্যকর হয় না ef শব্দ আচরণ আচরণ একটি ইঙ্গিত। কার্যকর করা হয় না এমন কোডের কোনও আচরণ নেই, অপরিজ্ঞাত বা অন্যথায়।
এন। 'সর্বনাম' মি।

1
@ স্টিভসমিট যদি নির্ধারিত অপরিজ্ঞাত আচরণটি পুরো প্রোগ্রামটিকে অকার্যকর করে দেয় তবে কোনও সি প্রোগ্রামের আচরণের সংজ্ঞা দেওয়া হত না। কারণ সি প্রোগ্রামগুলি সর্বদা কেবল একটি লুপ হয় / যদি শর্তটি ইউবি চালানো থেকে দূরে থাকে। একটি উদাহরণের জন্য একটি সাধারণ অ্যারে পুনরাবৃত্তি নিন: সীমাবদ্ধ চেকটি ব্যর্থ হওয়া অবধি এটি পুনরাবৃত্তি করে। পরবর্তী লুপ পুনরাবৃত্তি কার্যকর করা হবে সংজ্ঞায়িত আচরণ, তবে কারণ এটি কখনই কার্যকর হয় না, সবকিছু ঠিক আছে।
মাস্টার -

3
আমি এটি নিয়ে তর্ক করব না, কারণ আমি ভাষার উকিল করি না। তবে আমি বাজি ধরছি যদি আপনি এই প্রশ্নটি জিজ্ঞাসা করেন এবং এটিকে ভাষা-আইনজীবী ট্যাগ করেন তবে আপনি উত্সাহী বিতর্ক পেতে পারেন। নোট যে k=k++তুলনায় গুণগতভাবে পৃথক *x=42xবৈধ পয়েন্টার হলে পরবর্তীটি সঠিকভাবে সংজ্ঞায়িত করা হয় তবে পূর্ববর্তীটি নির্ধারিত হয় তা যাই হোক না কেন। (আমি স্বীকার করি আপনি ঠিক থাকতেই পারেন, তবে আবারও আমি এ নিয়ে তর্ক করতে যাচ্ছি না, এবং আমরা ক্রমশ উদ্বিগ্ন হয়েছি যে আমরা মাস্টারলি ট্রলড হয়েছি))
স্টিভ সামিট

1
"এক্সটি যদি একটি বৈধ পয়েন্টার হয় তবে পরবর্তীটি ভালভাবে সংজ্ঞায়িত করা হয়েছে, তবে পূর্ববর্তীটি নির্ধারিত হয় তা যাই হোক না কেন"। কেবলমাত্র পুরো প্রোগ্রামগুলিরই নির্ধারিত আচরণ থাকতে পারে। এই ধারণাটি বিচ্ছিন্নভাবে নেওয়া কোড টুকরাগুলির জন্য প্রযোজ্য নয়।
এন। 'সর্বনাম' মি।

3

এখানে এটির একটি সংস্করণ যা অপারেটরের অগ্রাধিকার দেখায়:

+(+(k--))

দুটি ইউনিারি +অপারেটর কিছুই করেন না, সুতরাং এই এক্সপ্রেশনটি হুবহু সমান k--। যিনি সম্ভবত এটি লিখেছেন তিনি আপনার মনের সাথে গোলমাল করার চেষ্টা করছেন।

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