সাক্ষাত্কারের প্রশ্ন: কোনটি দ্রুত সম্পাদন করবে, if (flag==0)
বা if (0==flag)
? কেন?
if(flag = 0)
কিছুটা পঠনযোগ্যতার দামের মতো বাগগুলির বিরুদ্ধে বীমা হয়ে উঠছেন।
সাক্ষাত্কারের প্রশ্ন: কোনটি দ্রুত সম্পাদন করবে, if (flag==0)
বা if (0==flag)
? কেন?
if(flag = 0)
কিছুটা পঠনযোগ্যতার দামের মতো বাগগুলির বিরুদ্ধে বীমা হয়ে উঠছেন।
উত্তর:
আমি এখনও কোনও সঠিক উত্তর দেখতে পাইনি (এবং ইতিমধ্যে কিছু রয়েছে) সতর্কতা: নওয়াজ ব্যবহারকারী-সংজ্ঞায়িত ফাঁদটি নির্দেশ করেছেন । এবং আমি আমার তাড়াহুড়োয় "বোকামি প্রশ্ন" -এর উপরে উত্সাহিত হওয়ার জন্য আফসোস করছি কারণ মনে হচ্ছে যে অনেকেই এটি সঠিকভাবে পায় নি এবং এটি সংকলক অপ্টিমাইজেশনে একটি সুন্দর আলোচনার সুযোগ দেয় :)
উত্তরটা হচ্ছে:
কি
flag
'র ধরনের?
ক্ষেত্রে যেখানে flag
প্রকৃতপক্ষে একটি ব্যবহারকারী সংজ্ঞায়িত টাইপ। তারপরে এটি নির্ভর করে যে কোনটির ওভারলোড operator==
নির্বাচন করা হয়েছে। অবশ্যই এটি নির্বোধ বলে মনে হতে পারে যে তারা প্রতিসম হবে না, তবে এটি অবশ্যই অনুমোদিত, এবং আমি অন্য গালিগুলি ইতিমধ্যে দেখেছি।
যদি flag
অন্তর্নির্মিত হয় তবে উভয়ের একই গতি নেওয়া উচিত।
থেকে Wikipedia নিবন্ধটি উপর x86
, আমি একটি জন্য বাজি ধরে বলতে পারি চাই Jxx
জন্য নির্দেশ if
বিবৃতি: সম্ভবত একটি JNZ
(ঝাঁপ দাও যদি না জিরো) অথবা কিছু সমতুল্য।
আমি সন্দেহ করি যে সংকলকটি যেমন অপটিমাইজেশন বন্ধ করেও এমন একটি সুস্পষ্ট অপ্টিমাইজেশন মিস করে। এটি সেই ধরণের জিনিস যার জন্য পিফোল অপটিমাইজেশন ডিজাইন করা হয়েছে।
সম্পাদনা করুন: আবার প্রসারিত হোন, তাই আসুন কিছু সমাবেশ যুক্ত করুন (এলএলভিএম ২.7 আইআর)
int regular(int c) {
if (c == 0) { return 0; }
return 1;
}
int yoda(int c) {
if (0 == c) { return 0; }
return 1;
}
define i32 @regular(i32 %c) nounwind readnone {
entry:
%not. = icmp ne i32 %c, 0 ; <i1> [#uses=1]
%.0 = zext i1 %not. to i32 ; <i32> [#uses=1]
ret i32 %.0
}
define i32 @yoda(i32 %c) nounwind readnone {
entry:
%not. = icmp ne i32 %c, 0 ; <i1> [#uses=1]
%.0 = zext i1 %not. to i32 ; <i32> [#uses=1]
ret i32 %.0
}
এমনকি যদি কেউ আইআর পড়তে না জানে তবে আমি মনে করি এটি স্ব-বর্ণনামূলক।
flag
অবশ্যই পূর্ণসংখ্যা বা বুলিয়ান হতে হবে। ওটিওএইচ, flag
ব্যবহারকারী-সংজ্ঞায়িত টাইপের একটি ভেরিয়েবল থাকা নিজের পক্ষে একেবারেই ভুল, আইএমএইচও
#include
নির্দেশ ছাড়াই উপলব্ধ । সরলতা দোহাই জন্য, এটি সাধারণত পরিমাণ int
, char
, bool
কথা বলা ইত্যাদি। অন্যান্য সমস্ত ধরনের, ব্যবহারকারী-সংজ্ঞায়িত হতে বলেন হয় যে, তারা কোন অস্তিত্ব কারণ তারা তাদের ঘোষণা কিছু ব্যবহারকারী ফল: typedef
, enum
, struct
, class
। উদাহরণস্বরূপ, std::string
ব্যবহারকারী সংজ্ঞায়িত করা হয়, যদিও আপনি অবশ্যই এটা নিজেকে :) সংজ্ঞায়িত করা
জিডিসি ৪.১.২ সহ এমডি 64 এর জন্য একই কোড:
.loc 1 4 0 # int f = argc;
movl -20(%rbp), %eax
movl %eax, -4(%rbp)
.loc 1 6 0 # if( f == 0 ) {
cmpl $0, -4(%rbp)
jne .L2
.loc 1 7 0 # return 0;
movl $0, -36(%rbp)
jmp .L4
.loc 1 8 0 # }
.L2:
.loc 1 10 0 # if( 0 == f ) {
cmpl $0, -4(%rbp)
jne .L5
.loc 1 11 0 # return 1;
movl $1, -36(%rbp)
jmp .L4
.loc 1 12 0 # }
.L5:
.loc 1 14 0 # return 2;
movl $2, -36(%rbp)
.L4:
movl -36(%rbp), %eax
.loc 1 15 0 # }
leave
ret
আপনার সংস্করণে কোনও পার্থক্য থাকবে না।
আমি ধরে নিচ্ছি যে type
পতাকাটির পতাকা ব্যবহারকারী-সংজ্ঞায়িত প্রকার নয়, বরং এটি কিছু বিল্ট-ইন টাইপ। এনাম ব্যতিক্রম! । আপনি এনামটিকে বিল্ট ইন হিসাবে ব্যবহার করতে পারেন। আসলে, এটির মানগুলি অন্তর্নির্মিত এক ধরণের!
সেক্ষেত্রে, যদি এটি ব্যবহারকারী-সংজ্ঞায়িত প্রকার (বাদে enum
) থাকে তবে উত্তরটি সম্পূর্ণরূপে নির্ভর করে যে আপনি কীভাবে অপারেটরটিকে ওভারলোড করেছেন ==
। নোট করুন যে আপনি ==
দুটি ফাংশন সংজ্ঞায়িত করে আপনার ওভারলোড করতে হবে, আপনার প্রতিটি সংস্করণের জন্য একটি!
একেবারে কোনও পার্থক্য নেই।
অ্যাসাইনমেন্ট / তুলনা টাইপগুলি বাদ দেওয়ার বিষয়ে উল্লেখ করে আপনি এই সাক্ষাত্কার প্রশ্নের উত্তর দেওয়ার ক্ষেত্রে পয়েন্ট অর্জন করতে পারেন, যদিও:
if (flag = 0) // typo here
{
// code never executes
}
if (0 = flag) // typo and syntactic error -> compiler complains
{
// ...
}
যদিও এটি সত্য, উদাহরণস্বরূপ সি-সংকলক প্রাক্তন ( flag = 0
) এর ক্ষেত্রে সতর্ক করে দেয় , পিএইচপি, পার্ল বা জাভাস্ক্রিপ্ট বা তেমন কোনও সতর্কতা নেই <insert language here>
।
গতি-ভিত্তিতে একেবারে কোনও পার্থক্য থাকবে না। কেন সেখানে থাকতে হবে?
x == 0
তবে এটি ব্যবহার করতে পারে তবে 0 == x
সাধারণ তুলনা ব্যবহার করতে পারে। আমি বলেছিলাম এটি প্রতিহত করতে হবে।
virtual operator==(int)
একটি ব্যবহারকারী-সংজ্ঞায়িত ধরনের?
ওয়েল একটি ব্যবহারকারী সংজ্ঞায়িত টাইপ হয় যখন পার্থক্য আছে
struct sInt
{
sInt( int i ) : wrappedInt(i)
{
std::cout << "ctor called" << std::endl;
}
operator int()
{
std::cout << "operator int()" << std::endl;
return wrappedInt;
}
bool operator==(int nComp)
{
std::cout << "bool operator==(int nComp)" << std::endl;
return (nComp == wrappedInt);
}
int wrappedInt;
};
int
_tmain(int argc, _TCHAR* argv[])
{
sInt s(0);
//in this case this will probably be faster
if ( 0 == s )
{
std::cout << "equal" << std::endl;
}
if ( s == 0 )
{
std::cout << "equal" << std::endl;
}
}
প্রথম ক্ষেত্রে (0 == গুলি) রূপান্তরকারী অপারেটরকে ডাকা হয় এবং তারপরে ফিরে আসা ফলাফলটিকে 0 এর সাথে তুলনা করা হয় the দ্বিতীয় ক্ষেত্রে == অপারেটরকে ডাকা হয়।
সন্দেহ যখন এটি মানদণ্ড এবং সত্য শিখুন।
গতির দিক থেকে এগুলি একই রকম হওয়া উচিত।
তবে খেয়াল করুন যে কিছু লোক সমতা তুলনা (তথাকথিত "যোদা শর্তাদি") বাম দিকে স্থির রাখতে ব্যবহার করতে পারে এমন সমস্ত ত্রুটিগুলি এড়ানোর জন্য যা যদি আপনি (সমতা তুলনা অপারেটর) =
পরিবর্তে লিখেন (অ্যাসাইনমেন্ট ==
অপারেটর); যেহেতু একটি আক্ষরিক অর্পণ করা একটি সংকলন ত্রুটি ট্রিগার করে, এই ধরণের ভুল এড়ানো হয়।
if(flag=0) // <--- typo: = instead of ==; flag is now set to 0
{
// this is never executed
}
if(0=flag) // <--- compiler error, cannot assign value to literal
{
}
অন্যদিকে, বেশিরভাগ লোকেরা "ইয়োদা শর্তসাপেক্ষ" অদ্ভুত চেহারা এবং বিরক্তিকর বলে মনে করেন, বিশেষত যেহেতু তারা যে ত্রুটিগুলি প্রতিরোধ করে তাদের ক্লাসটি পর্যাপ্ত সংকলক সতর্কতা ব্যবহার করেও চিহ্নিত করা যেতে পারে।
if(flag=0) // <--- warning: assignment in conditional expression
{
}
অন্যরা যেমন বলেছে, তেমন কোনও পার্থক্য নেই।
0
মূল্যায়ন করতে হবে। flag
মূল্যায়ন করতে হবে। এই প্রক্রিয়াটি একই সময় নেয়, তারা যে দিকে রাখে তা নির্বিশেষে।
সঠিক উত্তরটি হবে: তারা উভয়ই একই গতি।
এমনকি এক্সপ্রেশন if(flag==0)
এবং if(0==flag)
একই পরিমাণে অক্ষর রয়েছে! তাদের মধ্যে যদি কোনওটির মতো লেখা থাকে if(flag== 0)
তবে সংকলকটির পার্স করার জন্য একটি অতিরিক্ত জায়গা থাকতে পারে, সুতরাং সংকলনের সময়কে নির্দেশ করার ক্ষেত্রে আপনার বৈধ কারণ থাকতে পারে।
তবে যেহেতু এ জাতীয় কোনও জিনিস নেই তাই একে অপরের চেয়ে দ্রুত হওয়া উচিত এমন কোনও কারণ নেই। যদি কোনও কারণ থাকে, তবে সংকলকটি উত্পন্ন কোডটিতে কিছু খুব খুব অদ্ভুত কাজ করছে ...
কোনটির দ্রুত নির্ভর করে আপনি কোন সংস্করণ == ব্যবহার করছেন তার উপর। এখানে একটি স্নিপেট রয়েছে যা == এর 2 টি সম্ভাব্য বাস্তবায়ন ব্যবহার করে এবং আপনি x == 0 বা 0 == x কল করতে চান কিনা তার উপর নির্ভর করে 2 টির মধ্যে একটি বেছে নেওয়া হয়েছে।
আপনি যদি কেবল একটি পড ব্যবহার করছেন তবে গতির দিকে আসার পরে এ বিষয়টির আসলেই কিছু উচিত নয়।
#include <iostream>
using namespace std;
class x {
public:
bool operator==(int x) { cout << "hello\n"; return 0; }
friend bool operator==(int x, const x& a) { cout << "world\n"; return 0; }
};
int main()
{
x x1;
//int m = 0;
int k = (x1 == 0);
int j = (0 == x1);
}
ব্যস, ব্যায়ামের জন্য, আমি ওপিকে দেওয়া মন্তব্যে সকলের সাথে একমত হয়েছি:
সংকলকটি যদি যথেষ্ট পরিমাণে চালাক না হয় (প্রকৃতপক্ষে আপনার এটি ব্যবহার করা উচিত নয়) বা অপ্টিমাইজেশন অক্ষম থাকে, x == 0
কোনও স্থানীয় সমাবেশ jump if zero
নির্দেশকে সংকলন করতে 0 == x
পারে , এবং সংখ্যাসূচক মানের তুলনায় আরও জেনেরিক (এবং ব্যয়বহুল) হতে পারে।
তবুও, আমি এমন কোনও বসের পক্ষে কাজ করতে চাই না যারা এই শর্তাবলী বিবেচনা করে ...
মৃত্যুদন্ডের গতির ক্ষেত্রে অবশ্যই কোনও পার্থক্য নেই। উভয় ক্ষেত্রে একইভাবে শর্তটি মূল্যায়ন করা দরকার।
আমি মনে করি সেরা উত্তরটি "এই ভাষাটি কোন ভাষায়?"
প্রশ্নটি ভাষাটি নির্দিষ্ট করে না এবং এটি 'সি' এবং 'সি ++' উভয়ই ট্যাগ করে। একটি সুনির্দিষ্ট উত্তরের আরও তথ্যের প্রয়োজন।
এটি একটি লম্পট প্রোগ্রামিং প্রশ্ন, তবে এটি "বিভ্রান্তিকর্তাকে" নিজেকে ফাঁসিয়ে দেওয়া বা গাছের দোল তৈরির "বিভাগটি তৈরি করার পর্যাপ্ত দড়ি দেওয়া উচিত the এই ধরণের প্রশ্নগুলির সমস্যাটি হ'ল তারা সাধারণত লিখিত হয়ে যায় এবং সাক্ষাত্কারকারীর কাছে সাক্ষাত্কারকারীর হাতে তুলে দেওয়া হয় যতক্ষণ না এটি এমন লোকেদের হাতে না আসে যারা সত্যিকার অর্থে সমস্ত কোণ থেকে বোঝে না।
প্রস্তাবিত উপায়গুলি ব্যবহার করে দুটি সাধারণ প্রোগ্রাম তৈরি করুন।
কোডগুলি জমা দিন। সমাবেশ দেখুন এবং আপনি বিচার করতে পারেন, কিন্তু আমি সন্দেহ আছে যে একটি পার্থক্য আছে!
সাক্ষাত্কারগুলি আগের চেয়ে কম হচ্ছে।
ঠিক একদিকে যেমন (আমি আসলেই মনে করি যে কোনও শালীন সংকলক এই প্রশ্নটিকে মোটা করে দেবে, যেহেতু এটি অপ্টিমাইজ করবে) 0 == ফ্ল্যাগের ওপরে পতাকা ব্যবহার করে == 0 টাইপোকে আটকাতে পারে যেখানে আপনি = এর মধ্যে কোনওটি ভুলে যান (যেমন আপনি যদি দুর্ঘটনাক্রমে টাইপ করেন তবে পতাকা = 0 এটি সংকলন করবে, তবে 0 = পতাকাটি করবে না), যা আমি মনে করি সবাই এক সময় বা অন্য সময়ে ভুল করেছে ...