,
অপারেটর সি তে কি করে ?
,
অপারেটর সি তে কি করে ?
উত্তর:
অভিব্যক্তি:
(expression1, expression2)
প্রথম এক্সপ্রেশন 1 মূল্যায়ন করা হয়, তারপরে এক্সপ্রেশন 2 মূল্যায়ন করা হয়, এবং এক্সপ্রেশন 2 এর মান পুরো এক্সপ্রেশনটির জন্য ফিরে আসে।
i
5, 4, 3, 2 বা 1 এর মান থাকবে না এটি কেবল 0 is
i = b, c;
সমতুল্য (i = b), c
কারণ অ্যাসাইনমেন্ট =
কমা অপারেটরের চেয়ে উচ্চতর প্রাধান্য আছে ,
। কমা অপারেটরের সবার চেয়ে কম অগ্রাধিকার রয়েছে।
expression1, expression2;
প্রথমে expression1
তার পার্শ্ব-প্রতিক্রিয়াগুলির জন্য সম্ভবত মূল্যায়ন করা হয় (যেমন কোনও ফাংশন ডাকা), তারপরে একটি ক্রম বিন্দু রয়েছে, তারপরে expression2
মূল্যায়ন করা হয় এবং মানটি ফিরে আসে ...
আমি while
লুপগুলিতে সর্বাধিক ব্যবহৃত দেখেছি :
string s;
while(read_string(s), s.len() > 5)
{
//do something
}
এটি অপারেশনটি করবে, তারপরে পার্শ্ব-প্রতিক্রিয়াটির ভিত্তিতে একটি পরীক্ষা করবে। অন্য উপায়টি এটির মতো করে করা হবে:
string s;
read_string(s);
while(s.len() > 5)
{
//do something
read_string(s);
}
while (read_string(s) && s.len() > 5)
। স্পষ্টতই read_string
এটির কার্যকর হবে না যদি কোনও রিটার্ন মান না থাকে (বা অর্থপূর্ণ কোনও না থাকে)। (সম্পাদনা করুন: দুঃখিত, পোস্টটি কতটা পুরানো তা লক্ষ্য করেননি))
while (1)
একটি break;
বিবৃতি ব্যবহার করতে ভয় পাবেন না । কোডটির ব্রেক-আউট অংশটি পরীক্ষার সময় বা ডাউন-টেস্টের মধ্যে চাপিয়ে দেওয়ার চেষ্টা করা প্রায়শই শক্তির অপচয় এবং কোডটি বোঝা আরও শক্ত করে তোলে।
while(1)
এবং break
;
কমা অপারেটর বাম প্রতীক মূল্যায়ন করবে, ফলে বাতিল তারপর ডানদিকের প্রতীক মূল্যায়ন এবং যে ফল কী হবে। কথ্য ব্যবহার লিঙ্কে উল্লিখিত একটি ব্যবহৃত ভেরিয়েবল শুরু হচ্ছে for
লুপ, এবং এটি নিম্নলিখিত উদাহরণে দেয়:
void rev(char *s, size_t len)
{
char *first;
for ( first = s, s += len - 1; s >= first; --s)
/*^^^^^^^^^^^^^^^^^^^^^^^*/
putchar(*s);
}
অন্যথায় কমা অপারেটরের অনেক দুর্দান্ত ব্যবহার নেই , যদিও পড়তে ও বজায় রাখা শক্ত এমন কোড উত্পন্ন করার জন্য এটি অপব্যবহার করা সহজ।
থেকে খসড়া C99 মান ব্যাকরণ নিম্নরূপ:
expression:
assignment-expression
expression , assignment-expression
এবং অনুচ্ছেদ 2 বলেছেন:
একটি কমা অপারেটর বাঁদিকে প্রতীক একটি অকার্যকর অভিব্যক্তি হিসাবে মূল্যায়ন করা হয়; এর মূল্যায়নের পরে একটি সিকোয়েন্স পয়েন্ট রয়েছে। তারপরে ডান অপরেন্ড মূল্যায়ন করা হয়; ফলাফলটির ধরণ এবং মান রয়েছে। ৯)) যদি কমা অপারেটরের ফলাফলটি পরিবর্তন করতে বা পরবর্তী সিকোয়েন্স পয়েন্টের পরে এটি অ্যাক্সেস করার চেষ্টা করা হয়, তবে আচরণটি সংজ্ঞায়িত।
পাদটীকা 97 বলেছেন:
কমা অপারেটর একটি লভ্যালু দেয় না ।
যার অর্থ আপনি কমা অপারেটরের ফলাফলকে বরাদ্দ করতে পারবেন না ।
এটি লক্ষ করা গুরুত্বপূর্ণ যে কমা অপারেটরের সর্বনিম্ন প্রাধান্য রয়েছে এবং তাই এমন কিছু ক্ষেত্রে রয়েছে যেখানে ব্যবহার করা ()
একটি বড় পার্থক্য করতে পারে, উদাহরণস্বরূপ:
#include <stdio.h>
int main()
{
int x, y ;
x = 1, 2 ;
y = (3,4) ;
printf( "%d %d\n", x, y ) ;
}
নিম্নলিখিত আউটপুট হবে:
1 4
কমা অপারেটর উভয় এক্সপ্রেশনকে এর উভয় পাশকে এক সাথে সংযুক্ত করে, উভয়কে বাম থেকে ডানে ক্রমে মূল্যায়ন করে। ডান-হাতের মানটি পুরো এক্সপ্রেশনটির মান হিসাবে ফিরে আসে।
(expr1, expr2)
মত { expr1; expr2; }
তবে আপনি expr2
একটি ফাংশন কল বা অ্যাসাইনমেন্টের ফলাফল ব্যবহার করতে পারেন ।
এটিকে for
একাধিক ভেরিয়েবল শুরু করতে বা বজায় রাখতে প্রায়শই লুপগুলিতে দেখা যায় :
for (low = 0, high = MAXSIZE; low < high; low = newlow, high = newhigh)
{
/* do something with low and high and put new values
in newlow and newhigh */
}
এগুলি ছাড়া, আমি কেবলমাত্র অন্য একটি ক্ষেত্রে "ক্রোধে" এটি ব্যবহার করেছি, যখন দুটি ক্রিয়াকলাপ সর্বদা ম্যাক্রোতে একসাথে থাকা উচিত wra আমাদের কাছে এমন কোড রয়েছে যা একটি নেটওয়ার্কে প্রেরণের জন্য বাইনার বাফারে বিভিন্ন বাইনারি মানগুলিকে অনুলিপি করে, এবং একটি পয়েন্টার বজায় থাকে যেখানে আমরা পৌঁছেছি:
unsigned char outbuff[BUFFSIZE];
unsigned char *ptr = outbuff;
*ptr++ = first_byte_value;
*ptr++ = second_byte_value;
send_buff(outbuff, (int)(ptr - outbuff));
যেখানে মানগুলি short
বা int
গুলি ছিল আমরা এটি করেছি:
*((short *)ptr)++ = short_value;
*((int *)ptr)++ = int_value;
পরে আমরা পড়লাম যে এটি সত্যিকার অর্থে বৈধ সি ছিল না, কারণ (short *)ptr
এখন আর এল-মান হয় না এবং বাড়ানো যায় না, যদিও আমাদের সংকলকটি তখন আপত্তি করত না। এটি ঠিক করার জন্য, আমরা এক্সপ্রেশনটিকে দুটি ভাগে ভাগ করি:
*(short *)ptr = short_value;
ptr += sizeof(short);
যাইহোক, এই পদ্ধতির সমস্ত বিকাশ সমস্ত সময় রাখা স্মরণে সমস্ত বিকাশকারী উপর নির্ভর করে। আমরা এমন একটি ফাংশন চেয়েছিলাম যেখানে আপনি আউটপুট পয়েন্টার, মান এবং মানটির ধরণটি পাস করতে পারেন। এটি সি, টেমপ্লেটগুলি সহ সি ++ নয়, আমাদের একটি স্বেচ্ছাসেবীর ধরণের ফাংশন থাকতে পারে না, তাই আমরা ম্যাক্রোতে স্থির হয়েছি:
#define ASSIGN_INCR(p, val, type) ((*((type) *)(p) = (val)), (p) += sizeof(type))
কমা অপারেটরটি ব্যবহার করে আমরা এটি প্রকাশ করতে বা আমাদের ইচ্ছামতো বিবৃতি হিসাবে ব্যবহার করতে সক্ষম হয়েছি:
if (need_to_output_short)
ASSIGN_INCR(ptr, short_value, short);
latest_pos = ASSIGN_INCR(ptr, int_value, int);
send_buff(outbuff, (int)(ASSIGN_INCR(ptr, last_value, int) - outbuff));
আমি এই উদাহরণগুলির কোনটিই ভাল স্টাইলের প্রস্তাব দিচ্ছি না! আসলে, আমি মনে করি মনে হয় স্টিভ ম্যাককনেলের কোড সম্পূর্ণfor
লুপে কমা অপারেটর ব্যবহার করার বিরুদ্ধে পরামর্শের সম্পূর্ণ পরামর্শ : পাঠযোগ্যতা এবং রক্ষণাবেক্ষণের জন্য, লুপটি কেবলমাত্র একটি ভেরিয়েবল দ্বারা নিয়ন্ত্রিত হওয়া উচিত এবং for
লাইনটিতে থাকা এক্সপ্রেশনগুলিতে কেবল লুপ-নিয়ন্ত্রণ কোড থাকা উচিত, আরম্ভ বা লুপ রক্ষণাবেক্ষণের অতিরিক্ত অতিরিক্ত বিট নয়।
এটি একাধিক বিবৃতিগুলির মূল্যায়নের কারণ ঘটায়, তবে ফলস্বরূপ মান হিসাবে কেবল শেষটি ব্যবহার করে (মূল্যায়ন, আমি মনে করি)।
তাই ...
int f() { return 7; }
int g() { return 8; }
int x = (printf("assigning x"), f(), g() );
x 8 এ সেট হওয়ার ফলাফল হওয়া উচিত।
আমি এটি কার্যকর হতে দেখেছি কেবলমাত্র সেই জায়গাটি যখন আপনি কোনও মজাদার লুপটি লিখেন যেখানে আপনি কোনও একটি এক্সপ্রেশনে একাধিক জিনিস করতে চান (সম্ভবত থিম এক্সপ্রেশন বা লুপ এক্সপ্রেশন like
bool arraysAreMirrored(int a1[], int a2[], size_t size)
{
size_t i1, i2;
for(i1 = 0, i2 = size - 1; i1 < size; i1++, i2--)
{
if(a1[i1] != a2[i2])
{
return false;
}
}
return true;
}
ক্ষমা করুন যদি কোনও বাক্য গঠন ত্রুটি থাকে বা আমি এমন কোনও কিছু মিশ্রিত করি যা কঠোর নয় সি। আমি যুক্তি দিচ্ছি না যে, অপারেটরটি ভাল ফর্ম, তবে আপনি এটির জন্য এটি ব্যবহার করতে পারেন। উপরের ক্ষেত্রে আমি সম্ভবত while
পরিবর্তে একটি লুপ ব্যবহার করব যাতে init এবং লুপের একাধিক অভিব্যক্তি আরও স্পষ্ট হয়। (এবং আমি ঘোষণার পরিবর্তে i1 এবং i2 ইনলাইনটি শুরু করতে এবং তারপরে আরম্ভ করার চেষ্টা করব .... ব্লাহ ব্লাহ ব্লাহ।)
আমি @ রাজেশ এবং @ জেফমারকাডোর প্রশ্নগুলি সমাধান করার জন্য এটি সহজভাবে জাগ্রত করছি যা আমি মনে করি যে এটি অত্যন্ত গুরুত্বপূর্ণ কারণ এটি শীর্ষস্থানীয় অনুসন্ধান ইঞ্জিনগুলির মধ্যে অন্যতম হিট।
উদাহরণস্বরূপ নীচের কোডের স্নিপেট নিন
int i = (5,4,3,2,1);
int j;
j = 5,4,3,2,1;
printf("%d %d\n", i , j);
এটি মুদ্রণ করবে
1 5
i
অধিকাংশ উত্তর দ্বারা ব্যাখ্যা ক্ষেত্রে পরিচালিত হয়। সমস্ত এক্সপ্রেশন বাম থেকে ডান ক্রমে মূল্যায়ন করা হয় তবে কেবল সর্বশেষটি নির্ধারিত হয় i
। (
প্রকাশের ফলাফল ) 1 ) is
।
j
কেস বিভিন্ন প্রাধান্য নিয়ম অনুসরণ করে যেহেতু ,
সর্বনিম্ন অপারেটর প্রাধান্য আছে। কারণ সেই নিয়ম, কম্পাইলার দেখেন ... কার্যভার অভিব্যক্তি, ধ্রুবক, ধ্রুবক । এক্সপ্রেশন আবার বাম-থেকে-ডান ক্রম এবং তাদের পার্শ্ব প্রতিক্রিয়া দৃশ্যমান থাকার ফলে মূল্যায়ন করা হয় j
হয় 5
ফলে j = 5
।
আন্তঃআদ্দীপকভাবে, int j = 5,4,3,2,1;
ভাষা অনুমান দ্বারা অনুমোদিত নয়। একটি প্রাথমিককরণ কোনও অ্যাসাইনমেন্ট-এক্সপ্রেশন আশা করে যাতে সরাসরি ,
অপারেটরের অনুমতি দেওয়া হয় না।
আশাকরি এটা সাহায্য করবে.