কেন "মাপের (একটি? সত্য: মিথ্যা)" চারটি বাইটের আউটপুট দেয়?


133

sizeofটার্নারি অপারেটরের সাথে অপারেটর সম্পর্কে আমার কাছে কোডের একটি ছোট অংশ রয়েছে :

#include <stdio.h>
#include <stdbool.h>

int main()
{
    bool a = true;
    printf("%zu\n", sizeof(bool));  // Ok
    printf("%zu\n", sizeof(a));     // Ok
    printf("%zu\n", sizeof(a ? true : false)); // Why 4?
    return 0;
}

আউটপুট ( জিসিসি ):

1
1
4 // Why 4?

কিন্তু এখানে,

printf("%zu\n", sizeof(a ? true : false)); // Why 4?

টেরিনারি অপারেটর রিটার্নের booleanধরণ এবং আকারের boolধরণ সিতে 1বাইট হয়

তাহলে কেন sizeof(a ? true : false)চারটি বাইটের আউটপুট দেয় ?


39
sizeof(true)এবং sizeof(false)এটিও 4: আদর্শ. geeksforgeeks.org/O5jvuN
tkausl

7
এখানে আরও আকর্ষণীয় প্রশ্নটি হ'ল কেন এই বাস্তবায়নটি "বেমানান" কারণ এটি স্পষ্টতই _Boolআকার 1 এর সংজ্ঞা দেয় তবে তা নয় trueএবং false। তবে যতদূর আমি বলতে পারি স্ট্যান্ডার্ডটির বিষয়ে কিছু বলার নেই।

12
@ ফেলিক্সপ্যালম্যান একই কারণে char a; sizeof(a) == 1এবং কেন sizeof('a') == sizeof(int)(সি তে)। এটি বাস্তবায়নের বিষয়ে নয়, ভাষা সম্পর্কে।
এন। 'সর্বনাম' মি।

10
আপনি কি মুদ্রণের চেষ্টা করেছেন sizeof(true)? সম্ভবত এটি পাতলাগুলি আরও কিছুটা স্পষ্ট করে তুলবে (বিশেষত, এটি স্পষ্ট হয়ে উঠবে যে টের্নারি অপারেটর একটি লাল রঙের হারিং)।
এন। 'সর্বনাম' মি।

4
@FelixPalmen trueহয় #define1 ঘ হতে stdbool.hতাই হ্যাঁ, এই আক্ষরিক সংজ্ঞা।
এন। 'সর্বনাম' মি।

উত্তর:


223

এটা কারণ আপনার আছে #include <stdbool.h>। যে হেডার সংজ্ঞায়িত ম্যাক্রো true এবং falseহতে 1এবং 0, তাই এই মত আপনার বিবৃতি দেখায়:

printf("%zu\n", sizeof(a ? 1 : 0)); // Why 4?

sizeof(int) আপনার প্ল্যাটফর্মে 4 হয়


21
"এটি কারণ আপনার # অন্তর্ভুক্ত <stdbool.h>" না, তা নয়। sizeof(a ? (uint8_t)1 : (uint8_t)0);৪. এর ফলাফলও দেবে the ?:অপারেন্ডগুলির পূর্ণসংখ্যা প্রচার এখানে গুরুত্বপূর্ণ অংশ, আকার trueএবং এর আকার নয় false
লুন্ডিন

9
@ লন্ডিন: দুটোই গুরুত্বপূর্ণ। লিখিত হিসাবে, প্রকারটি ইতিমধ্যে intকোনও প্রচার ছাড়াই রয়েছে। আপনি "ফিক্স" করতে না পারার কারণ এটি ডিফল্ট প্রচারগুলি।
আর .. গিটহাব বন্ধ হেল্পিং আইসিসি

5
@ পিটারস্কিনিডার এটি সি ++ নয়। এই সি সি ++ হয়, trueএবং falseহয় না ম্যাক্রো; তারা কীওয়ার্ড হয়। তারা হতে সংজ্ঞায়িত না হয় 1এবং 0কিন্তু সত্য এবং মিথ্যা মান হতে boolপ্রকার।
জাস্টিন

5
@ পিটারস্কিনিডার না, আপনি আজ সি সম্পর্কে কিছু শিখলেন। দুটি ভাষা বিভ্রান্ত করবেন না। সি ++ এ, sizeof(true)1 ডেমো
Rakete1111

1
সত্য, এটি মিশ্রিত। মনোযোগ সহকারে পড়েনি এবং cppreferences- লিঙ্ক দ্বারা মিস করা হয়েছিল। আমার দোষ, ধন্যবাদ। তবে যাইহোক আমার কাছে সি ++ সম্পর্কে এই অনুভূতি রয়েছে।
পিটার স্নাইডার

66

এখানে, টার্নারি অপারেটর রিটার্ন booleanটাইপ,

ঠিক আছে, আরও কিছু আছে!

সি তে, এই টেরিনারি অপারেশনের ফলাফল টাইপযুক্ত int[নীচের নোটগুলি (1,2)]

সুতরাং ফলটি sizeof(int)আপনার প্ল্যাটফর্মে প্রকাশের মতোই ।


দ্রষ্টব্য 1: উদ্ধৃতি C11, অধ্যায় §7.18,Boolean type and values <stdbool.h>

[....] বাকি তিনটি ম্যাক্রো #ifপ্রিপ্রোসেসিং নির্দেশিকা ব্যবহারের জন্য উপযুক্ত । তারা হয়

true

যা পূর্ণসংখ্যার ধ্রুবক 1 এ প্রসারিত হয়,

false

যা পূর্ণসংখ্যার ধ্রুবক 0, প্রসারিত হয় [....]

দ্রষ্টব্য 2: শর্তসাপেক্ষ অপারেটরের জন্য, অধ্যায় §6.5.15, ( আমার উপর চাপ দেওয়া )

প্রথম অপারেন্ড মূল্যায়ন করা হয়; এর মূল্যায়ন এবং দ্বিতীয় বা তৃতীয় অপারেন্ডের মূল্যায়ন (যেটি মূল্যায়ন করা হয়) এর মধ্যে একটি ক্রম বিন্দু রয়েছে। দ্বিতীয় অপারেন্ডটি কেবল তখনই মূল্যায়ন করা হয় যদি প্রথমটি 0 টির সাথে অসম তুলনা করে; তৃতীয় অপারেন্ড কেবল তখনই মূল্যায়ন করা হয় যদি প্রথম 0 টির সমান তুলনা করা হয়; ফলাফলটি হ'ল দ্বিতীয় বা তৃতীয় অপারেন্ডের মান (যার মূল্যায়ন করা হয়), [...]

এবং

যদি দ্বিতীয় এবং তৃতীয় উভয় অপারেন্ডের গাণিতিক টাইপ থাকে তবে ফলাফলের ধরণ যা সাধারণ গাণিতিক রূপান্তর দ্বারা নির্ধারিত হবে, যদি সেগুলি দুটি অপারেন্ডের জন্য প্রয়োগ করা হয়, তবে ফলাফলের ধরণটি। [....]

অতএব, ফলাফল টাইপ পূর্ণসংখ্যার হবে এবং মান পরিসরের কারণে ধ্রুবকগুলি হুবহু টাইপের হয় int

এটি বলেছিল, একটি জেনেরিক পরামর্শ, সত্যই মানসম্মত-অনুসারী int main()হওয়া উচিত int main (void)


@ ইউজার 694733 উম্ম..আমি না কেন? ম্যাক্রোসকে <stdbool.h>টাইপ হতে সংজ্ঞায়িত করে int..এটা ভুল?
সৌরভ ঘোষ

@ বাসাইলস্টারিঙ্কেভিচ ঠিক আছে, আমি দেখতে পাচ্ছি যে এটি এখন সত্যই ভুল, এখন আপডেট হয়েছে।
সৌরভ ঘোষ

58

টেরিনারি অপারেটর একটি লাল হেরিং।

    printf("%zu\n", sizeof(true));

প্রিন্ট 4 (বা sizeof(int)আপনার প্ল্যাটফর্মের যা কিছু আছে)।

নিম্নলিখিত ধরে নেয় যে boolজন্য একটি প্রতিশব্দ হয় charবা আকার 1 একটি অনুরূপ প্রকার, এবং intথেকে বড় char

কারণ sizeof(true) != sizeof(bool)এবং sizeof(true) == sizeof(int)কেবল কারণ trueহয় না টাইপ একটি অভিব্যক্তি bool। এটি টাইপের একটি অভিব্যক্তি int। এটা তোলে হয় #defineযেমন ঘ 1মধ্যে stdbool.h

boolসি তে টাইপের কোনও মূল্য নেই । intযুক্তি হিসাবে ব্যবহৃত হলেও এমনকি এই জাতীয় প্রতিটি মূল্যায়ন অবিলম্বে উন্নীত হয় sizeofসম্পাদনা করুন: এই অনুচ্ছেদটি সত্য নয়, যুক্তি হিসাবে sizeofপ্রচারিত হবে না int। এটি যদিও কোনও সিদ্ধান্তকে প্রভাবিত করে না।


চমৎকার উত্তর. আমি বর্তমানে সর্বাধিক উর্ধ্বমুখী উত্তরটি পড়ার পরে, আমি ভাবছিলাম সমস্ত বিবৃতি 4 টিতে মূল্যায়ন করা উচিত This এটি পরিষ্কার হয়ে গেছে things +1
পেড্রো এ

5
নয় (bool)1প্রকারের একটি rvalue bool?
বেন ভয়েগট

printf("%u\n", sizeof((char) 1));কপি করে প্রিন্ট 1যেহেতু আমার প্ল্যাটফর্মের উপর printf("%u\n", sizeof(1));কপি করে প্রিন্ট 4। এর অর্থ কি এই নয় যে আপনার "বিবৃতিটি আকারের যুক্তি হিসাবে ব্যবহৃত হলেও" এই জাতীয় প্রতিটি তত্ক্ষণাত অবিলম্বে ইনট হিসাবে প্রচার করা হবে "?
জোনাটান

এটি আসলে প্রশ্নের উত্তর দেয় না। trueইত্যাদির আকার এবং প্রকারের ক্ষেত্রে ?:এটি কোনও ক্ষেত্রে গুরুত্বপূর্ণ নয়, যেহেতু এটি intকোনওভাবেই সংখ্যায় প্রচারিত হয় । এটি হ'ল, কেন ?: একটি লাল রঙের হেরিং হয় তার উত্তরে উত্তর দেওয়া উচিত ।
লন্ডিন

6
আমি মনে করি উত্তরটি সর্বোত্তম উপায়ে সমস্যার সমাধান করেছে। আপনি ডাউনওয়েট বা উন্নত করতে আপনাকে স্বাগতম।
এন। 'সর্বনাম' মি।

31

সি তে বুলিয়ান টাইপ সম্পর্কিত

১৯৯৯ সালে, সি ভাষায় বেশ কিছুটা দেরিতে একটি বুলিয়ান প্রকার চালু করা হয়েছিল। তার আগে, সি তে কোনও বুলিয়ান টাইপ ছিল না তবে পরিবর্তে intসমস্ত বুলিয়ান অভিব্যক্তির জন্য ব্যবহৃত হত । সুতরাং সমস্ত লজিকাল অপারেটর যেমন > == !ইত্যাদির intমান 1বা একটি ফেরত 0

অ্যাপ্লিকেশনগুলিতে বাড়িতে তৈরি জাতীয় ধরণের ব্যবহারের জন্য এটি রীতি ছিল typedef enum { FALSE, TRUE } BOOL;যা intএগুলি আকারের আকার থেকেও ফোটায়।

সি ++ এর মধ্যে আরও ভাল এবং স্পষ্টত বুলিয়ান প্রকার boolছিল, যা 1 বাইটের চেয়ে বড় নয়। সিতে বুলিয়ান প্রকার বা এক্সপ্রেশনগুলি সবচেয়ে খারাপ ক্ষেত্রে 4 বাইট হিসাবে শেষ হবে। সি ++ এর সাথে সামঞ্জস্যের কিছু পদ্ধতি সি -৯ স্ট্যান্ডার্ডের সাথে সিতে প্রবর্তিত হয়েছিল। সি এর পরে একটি বুলিয়ান টাইপ _Boolএবং শিরোনামও পেল stdbool.h

stdbool.hসি ++ এর সাথে কিছু সামঞ্জস্যতা সরবরাহ করে। এই শিরোনামটি ম্যাক্রো bool(সি ++ কীওয়ার্ডের মতো একই বানান) সংজ্ঞা দেয় যা প্রসারিত হয় _Bool, একটি প্রকার যা একটি ছোট পূর্ণসংখ্যার প্রকার, সম্ভবত 1 বাইট বৃহত্তর। একইভাবে, শিরোনামটি দুটি ম্যাক্রো trueএবং false, সি ++ কীওয়ার্ড হিসাবে একই বানান সরবরাহ করে তবে পুরানো সি প্রোগ্রামগুলিতে পশ্চাদপটে সামঞ্জস্যের সাথে । অতএব trueএবং falseপ্রসারিত 1এবং 0সি এবং তাদের প্রকার int। এই ম্যাক্রোগুলি আসলে বুলিয়ান ধরণের নয় যা সম্পর্কিত সি ++ কীওয়ার্ডগুলির মতো হবে।

একইভাবে, পশ্চাদপটে সামঞ্জস্যের উদ্দেশ্যে, সি-তে লজিকাল অপারেটররা আজও এটি ফিরিয়ে দেয় int, যদিও সি আজকাল বুলিয়ান টাইপ পেয়েছিল। সি ++ এ থাকাকালীন, লজিকাল অপারেটররা a bool। সুতরাং একটি অভিব্যক্তি যেমন sizeof(a == b)একটি intসি এর মধ্যে একটি আকার দিতে হবে , কিন্তু একটি সি এর আকার bool++।

শর্তসাপেক্ষ অপারেটর সম্পর্কিত ?:

শর্তসাপেক্ষ অপারেটর ?:একটি অদ্ভুত অপারেটর যার সাথে দু'পক্ষের কৌতুক হয়। এটি 100% এর সমতুল্য তা বিশ্বাস করা একটি সাধারণ ভুল if() { } else {}। বেশ না।

1 ম এবং 2 য় বা 3 য় অপরেন্ডের মূল্যায়নের মধ্যে একটি সিকোয়েন্স পয়েন্ট রয়েছে। ?:অপারেটর কেবল ২ য় বা ৩ য় অপরেন্ডকে মূল্যায়ন করার গ্যারান্টিযুক্ত, সুতরাং এটি অপারেন্ডের কোনও পার্শ্ব-প্রতিক্রিয়া কার্যকর করতে পারে না যা মূল্যায়ন করা হয় না। কোড যেমন true? func1() : func2()কার্যকর হবে না func2()। এ পর্যন্ত সব ঠিকই.

তবে , একটি বিশেষ নিয়ম জানায় যে 2nd এবং 3rd প্রতীক পরোক্ষভাবে উন্নীত ধরনের পাওয়া হবে এবং সঙ্গে একে অপরের বিরুদ্ধে সামঞ্জস্যপূর্ণ হয় স্বাভাবিক গাণিতিক ধর্মান্তর । ( সি তে অন্তর্ভুক্ত প্রকারের প্রচারের বিধিগুলি এখানে ব্যাখ্যা করা হয়েছে )। এর অর্থ দ্বিতীয় বা তৃতীয় অপারেন্ড সর্বদা কমপক্ষে একটি হিসাবে বৃহত্তর থাকবে int

সুতরাং এটা কোন ব্যাপার না যে trueএবং falseঘটতে ধরনের হতে intসি কারণ অভিব্যক্তি সবসময় অন্তত একটি আকার দিতে হবে intকোন ব্যাপার।

এমনকি যদি আপনি এটিতে আবার নতুন করে লিখতে চান তবে এটি একটি আকারটি ফিরিয়ে দেবে !sizeof(a ? (bool)true : (bool)false) int

এটি সাধারণ গাণিতিক রূপান্তরগুলির মাধ্যমে অন্তর্নিহিত ধরণের প্রচারের কারণে।


1
সি ++ আসলে গ্যারান্টি দেয় না sizeof(bool)==1
aschepler

1
@ এস্পেল্পার নন, তবে সি ++ স্ট্যান্ডার্ডের বাইরের আসল বিশ্বে এটির গ্যারান্টি নেই। একটি সংকলক নাম দিন যেখানে এটি 1 নয়
লন্ডিন

ওহে. আমি মনে করি এই উত্তরটির প্রথম অংশটি ছাড়াই ভাল হবে । দ্বিতীয় অংশটি প্রশ্নের উত্তর দেয়। বাকিটি, যদিও আকর্ষণীয়, কেবল শব্দ মাত্র।
YSC

@ ওয়াইএসসি এটিকে মূলত সি এবং সি ++ উভয়ই ট্যাগ করা হয়েছিল, সুতরাং তাদের বিভিন্ন বিলের ধরণের এবং তাদের পিছনের ইতিহাসের মধ্যে একটি তুলনা করা প্রয়োজনীয় ছিল। আমি সন্দেহ করি আমি সি ++ ট্যাগের জন্য না থাকলে প্রথম অংশটি লিখতাম। যাইহোক, একটি বুঝতে হবে কেন মাপের (বুল) 1 হয় তবে মাপ (মিথ্যা) 4
ডিগ্রি সেন্টিগ্রেডে

21

দ্রুত উত্তর:

  • sizeof(a ? true : false)মূল্যায়ণ 4কারণ trueএবং falseএ সংজ্ঞায়িত করা হয় <stdbool.h>যেমন 1এবং 0যথাক্রমে তাই অভিব্যক্তি বিস্তৃতি করার sizeof(a ? 1 : 0)কোন ধরনের সঙ্গে একটি পূর্ণসংখ্যা অভিব্যক্তি int, যে আপনার প্ল্যাটফর্মে 4 বাইট দখল করে। একই কারণে, আপনার সিস্টেমে sizeof(true)মূল্যায়নও করবে 4

তবে নোট করুন যে:

  • sizeof(a ? a : a)এছাড়াও এটিও মূল্যায়ন করে 4কারণ টের্নারি অপারেটর যদি দ্বিতীয় এবং তৃতীয় অপারেটরে পূর্ণসংখ্যা প্রচার করে তবে এটি যদি পূর্ণসংখ্যার প্রকাশ হয়। অবশ্যই একই জন্য ঘটে sizeof(a ? true : false)এবং sizeof(a ? (bool)true : (bool)false), কিন্তু পুরো অভিব্যক্তি ভোটদান boolআচরণ করবে আশানুরূপ: sizeof((bool)(a ? true : false)) -> 1

  • এও নোট করুন যে তুলনা অপারেটরদের বুলিয়ান মান নির্ণয় করা 1বা 0, কিন্তু আছে intটাইপ: sizeof(a == a) -> 4

কেবলমাত্র অপারেটরগুলি যা বুলিয়ান প্রকৃতি রাখে তা হ'ল a:

  • কমা অপারেটর: সংকলন সময় উভয় sizeof(a, a)এবং sizeof(true, a)মূল্যায়ন 1

  • নিয়োগ অপারেটরদের: উভয় sizeof(a = a)এবং sizeof(a = true)একটি মূল্য আছে 1

  • ইনক্রিমেন্ট অপারেটর: sizeof(a++) -> 1

পরিশেষে, উপরের সমস্তটি কেবলমাত্র সিটির ক্ষেত্রে প্রযোজ্য: সি ++ এর boolধরন, বুলিয়ান মান trueএবং falseতুলনা অপারেটর এবং টেরিনারি অপারেটর সম্পর্কিত বিভিন্ন শব্দার্থক রয়েছে : এই সমস্ত sizeof()অভিব্যক্তি 1সি ++ তে মূল্যায়ন করে ।


2
উত্তম উত্তর যা প্রকৃতপক্ষে এটি উল্লেখ করতে পরিচালিত করে যে এটি কী ধরণের trueএবং কী তা আসলেই গুরুত্বপূর্ণ নয় false, কারণ ?:অপারেটসগুলি intকোনওভাবেই পূর্ণসংখ্যার প্রচারিত হবে । সুতরাং sizeof(a ? (uint8_t)true : (uint8_t)false)ফলস্বরূপ 4 উত্পাদন করবে।
লন্ডিন

এই উত্তরটি মুখ্য গুরুত্বপূর্ণ পয়েন্টটি কভার করে, মূল্য প্রচার করা হচ্ছেint
চিন্নি

1

উত্সের অন্তর্ভুক্তটি হ'ল এটির একটি স্নিপেট

#ifndef __cplusplus

#define bool    _Bool
#define true    1
#define false   0

#else /* __cplusplus */

সেখানে ম্যাক্রো রয়েছে trueএবং falseযথাক্রমে 1 এবং 0 হিসাবে ঘোষিত হয়।

তবে এই ক্ষেত্রে টাইপটি আক্ষরিক ধ্রুবকগুলির ধরণ। 0 এবং 1 উভয়ই পূর্ণসংখ্যার ধ্রুবক যা কোনও ইনট্রে ফিট করে, তাই তাদের প্রকারটি ইনট হয়।

এবং sizeof(int)আপনার ক্ষেত্রে 4 হয়।


-3

সি তে কোনও বুলিয়ান ডেটাটাইপ নেই, পরিবর্তে লজিক্যাল এক্সপ্রেশনগুলি 1অন্যথায় যদি সত্য হয় তখন পূর্ণসংখ্যার মানগুলির মূল্যায়ন করে 0

শর্তসাপেক্ষ এক্সপ্রেশন পছন্দ if, for, while, অথবা c ? a : bএকটি পূর্ণসংখ্যা আশা, যদি সংখ্যা নন-জিরো এটা বিবেচনা হল trueকিছু বিশেষ ক্ষেত্রে ছাড়া, এখানে একটি recursive সমষ্টি ফাংশন যা তিন-অপারেটর মূল্যায়ন হবে trueযতক্ষণ না nনাগালের 0

int sum (int n) { return n ? n+sum(n-1) : n ;

এটি NULLপয়েন্টারটি পরীক্ষা করতেও ব্যবহার করা যেতে পারে , এখানে একটি পুনরাবৃত্ত ফাংশন যা এককভাবে সংযুক্ত-তালিকার সামগ্রীটি মুদ্রণ করে।

void print(sll * n){ printf("%d -> ",n->val); if(n->next)print(n->next); }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.