ఆపరేటర్లు & ఎక్స్ప్రెషన్స్
కంప్యూటర్ సైన్స్లో డేటా కేవలం మెమరీలో ఉండటం మాత్రమే సరిపోదు; ఆ డేటాపై గణనలు, తార్కిక నిర్ణయాలు (Logical Decisions), మరియు పోలికలు జరపాలి. ఒక ప్రోగ్రామ్లో లెక్కలు చేయడానికి మరియు ఫలితాలను సృష్టించడానికి వాడే ప్రత్యేక సంకేతాలనే ఆపరేటర్లు (Operators) అంటారు.
ఈ నాల్గవ అధ్యాయంతో మనం C++ Phase 01 (ఫండమెంటల్స్) ను విజయవంతంగా పూర్తి చేసుకోబోతున్నాం! ఈ లెసన్లో అరిథ్మెటిక్ ఆపరేటర్ల నుండి ఆధునిక C++20 Spaceship Operator (<=>), CPU లెవల్ బిట్వైజ్ మాస్కింగ్, మరియు ఒక రియల్-వరల్డ్ Vehicle Sensor Telemetry Engine ప్రాజెక్ట్ ద్వారా ఆపరేటర్ల పూర్తి అంతర్గత మెకానిక్స్ నేర్చుకుందాం!
1 ఆపరేటర్లు & ఎక్స్ప్రెషన్స్ అంటే ఏమిటి? (Operators & Operands)
కంప్యూటర్ ప్రాసెసర్ (ALU - Arithmetic Logic Unit) లో ఒక ఆపరేషన్ జరగడానికి మూడు ముఖ్య భాగాలు ఉంటాయి:
- ఆపరేటర్ (Operator): కంప్యూటర్కు ఏ పని చేయాలో ఆదేశించే సంకేతం (ఉదాహరణకు:
+,-,*,<<). - ఆపరాండ్ (Operand): ఆపరేటర్ ఏ విలువలపై పనిచేస్తుందో ఆ డేటా లేదా వేరియబుల్స్ (ఉదాహరణకు:
a + bలోaమరియుbఆపరాండ్లు). - ఎక్స్ప్రెషన్ (Expression): ఆపరేటర్లు మరియు ఆపరాండ్ల కలయిక ద్వారా ఒక ఫలిత విలువను ఉత్పత్తి చేసే పూర్తి స్టేట్మెంట్ (ఉదాహరణకు:
total = (price * qty) - discount;).
ఆపరాండ్ల సంఖ్యను బట్టి C++ ఆపరేటర్లు 3 రకాలు:
- Unary Operators: కేవలం ఒకే ఆపరాండ్పై పనిచేస్తాయి (ఉదా:
++x,-x,!flag,sizeof(int)). - Binary Operators: రెండు ఆపరాండ్ల మధ్య పనిచేస్తాయి (ఉదా:
a + b,x > y,a && b). - Ternary Operator: మూడు భాగాలతో పనిచేసే ఏకైక ఆపరేటర్ కండిషనల్ ఆపరేటర్ (
condition ? true_val : false_val).
2 అరిథ్మెటిక్ ఆపరేటర్లు & Integer Division vs Floating Division
ప్రాథమిక గణిత గణనల కోసం C++ 5 ప్రధాన అరిథ్మెటిక్ ఆపరేటర్లను అందిస్తుంది:
| ఆపరేటర్ | పేరు (Name) | ఉదాహరణ (Example) | ఫలితం (Result) |
|---|---|---|---|
+ |
కూడిక (Addition) | 10 + 5 |
15 |
- |
తీసివేత (Subtraction) | 10 - 5 |
5 |
* |
గుణకారం (Multiplication) | 10 * 5 |
50 |
/ |
భాగహారం (Division) | 10 / 4 |
2 (2.5 కాదు! Truncated) |
% |
శేషం (Modulus / Remainder) | 10 % 4 |
2 (మిగిలిన శేషం) |
⚠️ The Integer Division Trap (పూర్ణాంక భాగహార ప్రమాదం)
C++ లో రెండు పూర్ణాంకాలను (Integers) భాగిస్తే, ఫలితం కూడా ఎల్లప్పుడూ పూర్ణాంకమే అవుతుంది. దశాంశ భాగాన్ని (Decimals) కంపైలర్ పూర్తిగా రద్దు చేసి పారేస్తుంది (Truncation towards zero).
కచ్చితమైన 2.5 కావాలంటే, కనీసం ఒక్క ఆపరాండ్నైనా ఫ్లోటింగ్ పాయింట్గా మార్చాలి: 10.0 / 4 లేదా static_cast<double>(10) / 4!
3 ఇంక్రిమెంట్ & డిక్రిమెంట్: Prefix (++i) vs Postfix (i++) మైక్రోస్కోపిక్ మెమరీ తేడా
ఒక వేరియబుల్ విలువను 1 పెంచడానికి ++ మరియు 1 తగ్గించడానికి -- వాడతాము. అయితే వీటిని వేరియబుల్ ముందు రాస్తే Prefix అంటారు, వెనుక రాస్తే Postfix అంటారు.
⚡ Prefix (++i) — "First Increment, Then Use"
ముందుగా మెమరీలోని విలువను 1 పెంచుతుంది. ఆ తర్వాత మారిన కొత్త విలువను ఎక్స్ప్రెషన్లో ఉపయోగిస్తుంది. ఇందులో ఎటువంటి తాత్కాలిక వేరియబుల్ సృష్టించబడదు, కాబట్టి ఇది అత్యంత వేగవంతమైనది!
🐢 Postfix (i++) — "First Use, Then Increment"
పాత విలువను ఒక తాత్కాలిక కాపీ (Temporary Object) లో దాచిపెట్టి, ఆ పాత విలువను ఎక్స్ప్రెషన్కు ఇస్తుంది. ఆ తర్వాత అసలు వేరియబుల్ను 1 పెంచుతుంది. క్లాసెస్ మరియు STL ఇటరేటర్లలో ఇది అనవసరమైన మెమరీ కాపీని సృష్టిస్తుంది.
#include <iostream>
int main() {
int x = 5;
int y = 5;
// 1. Prefix: ముందు 1 పెరుగుతుంది (x=6), ఆపై a లోకి 6 వెళ్తుంది
int a = ++x;
// 2. Postfix: ముందు పాత విలువ (5) b లోకి వెళ్తుంది, ఆపై y 6 అవుతుంది
int b = y++;
std::cout << "Prefix -> x: " << x << " | a: " << a << " (రెండు 6 అయ్యాయి)\n";
std::cout << "Postfix -> y: " << y << " | b: " << b << " (b పాత విలువ 5 తీసుకుంది)\n";
return 0;
}
4 అసైన్మెంట్ & కాంపౌండ్ అసైన్మెంట్ ఆపరేటర్లు
ఒక వేరియబుల్కు విలువను కేటాయించడానికి = (Simple Assignment) వాడతాము. అయితే కోడ్ను కుదించడానికి మరియు CPU వేగాన్ని పెంచడానికి C++ Compound Assignment Operators ను అందిస్తుంది:
x += 5;అంటేx = x + 5;కు సమానం.x -= 3;అంటేx = x - 3;కు సమానం.x *= 2;అంటేx = x * 2;కు సమానం.x /= 4;అంటేx = x / 4;కు సమానం.x %= 2;అంటేx = x % 2;కు సమానం.
గమనిక: కాంపౌండ్ ఆపరేటర్లలో ఎడమవైపు వేరియబుల్ మెమరీ అడ్రస్ కేవలం ఒకే ఒక్కసారి మాత్రమే ఎవాల్యుయేట్ అవుతుంది, కాబట్టి ఇది చాలా వేగవంతమైనది.
5 రిలేషనల్ & కంపారిజన్ ఆపరేటర్లు
రెండు విలువల మధ్య సంబంధాన్ని పోల్చడానికి రిలేషనల్ ఆపరేటర్లను ఉపయోగిస్తాము. ఇవి ఎల్లప్పుడూ బూలియన్ ఫలితాన్ని (true లేదా false) ఇస్తాయి:
==(Equal to): రెండు విలువలు సమానమా? (ఉదా:5 == 5yieldstrue). ⚠️ గమనిక: సింగిల్=అసైన్మెంట్, డబుల్==కంపారిజన్!!=(Not Equal to): రెండు విలువలు అసమానమా? (ఉదా:5 != 3yieldstrue).>(Greater than),<(Less than): పెద్దదా లేదా చిన్నదా?>=,<=(Greater than or Equal to / Less than or Equal to).
6 C++20 Three-Way Comparison: స్పేస్షిప్ ఆపరేటర్ (<=>)
Modern C++20 లో ప్రవేశపెట్టబడిన అత్యంత విప్లవాత్మకమైన ఆపరేటర్ Three-Way Comparison Operator (<=>). దీని ఆకారం ఒక అంతరిక్ష నౌకలా ఉండటం వల్ల దీనిని ముద్దుగా "The Spaceship Operator" అంటారు!
గతంలో రెండు ఆబ్జెక్టులను పోల్చడానికి మనం 6 వేర్వేరు ఆపరేటర్లను (==, !=, <, >, <=, >=) ఓవర్లోడ్ చేయాల్సి వచ్చేది. కానీ C++20 లో కేవలం ఒక్క <=> రాస్తే చాలు, కంపైలర్ మిగిలిన 6 ఆపరేటర్లను ఆటోమేటిక్గా సిద్ధం చేస్తుంది!
#include <iostream>
#include <compare> // std::strong_ordering కోసం
int main() {
int a = 10;
int b = 20;
auto result = (a <=> b);
if (result < 0) {
std::cout << "a అనేది b కంటే చిన్నది (a < b)\n";
} else if (result > 0) {
std::cout << "a అనేది b కంటే పెద్దది (a > b)\n";
} else {
std::cout << "రెండూ సమానం (a == b)\n";
}
return 0;
}
7 లాజికల్ ఆపరేటర్లు & షార్ట్-సర్క్యూట్ ఎవాల్యుయేషన్ (Short-Circuit)
ఒకటి కంటే ఎక్కువ కండిషన్లను కలపడానికి లాజికల్ ఆపరేటర్లు ఉపయోగపడతాయి:
&&(Logical AND): అన్ని కండిషన్లుtrueఅయితేనే మొత్తం ఫలితంtrue.||(Logical OR): కనీసం ఒక్క కండిషన్trueఅయినా మొత్తం ఫలితంtrue.!(Logical NOT): ఫలితాన్ని తలక్రిందులు చేస్తుంది (trueనిfalseగా,falseనిtrueగా).
⚡ The Power of Short-Circuit Evaluation
C++ కంపైలర్ లాజిక్ ఎవాల్యుయేట్ చేసేటప్పుడు సమయాన్ని ఆదా చేయడానికి ఒక తెలివైన టెక్నిక్ వాడుతుంది:
- expr1 && expr2 లో, expr1 గనుక false అయితే, expr2 ను అసలు ముట్టుకోదు! ఎందుకంటే మొదటిది ఫాల్స్ అయితే మొత్తం ఫాల్స్ అని తెలుసు.
- expr1 || expr2 లో, expr1 గనుక true అయితే, expr2 ను చెక్ చేయదు!
లైఫ్-సేవింగ్ ఉపయోగం: if (ptr != nullptr && *ptr > 0) — ఇక్కడ పాయింటర్ నల్ అయితే రెండవ కండిషన్కు వెళ్లదు, దీనివల్ల ప్రోగ్రామ్ నల్-పాయింటర్ క్రాష్ అవ్వకుండా సురక్షితంగా రక్షించబడుతుంది!
8 బిట్వైజ్ ఆపరేటర్లు: బైనరీ లెవల్ డేటా మానిప్యులేషన్ & బిట్ మాస్కింగ్
ఆటోమోటివ్, ఎంబెడెడ్ సిస్టమ్స్ మరియు గేమ్ ఇంజిన్లలో ప్రతి ఒక్క బిట్ విలువైనది. C++ హార్డ్వేర్ బిట్స్ను నేరుగా మార్చడానికి 6 బిట్వైజ్ ఆపరేటర్లను అందిస్తుంది:
&(Bitwise AND): రెండు బిట్లు 1 అయితేనే 1.|(Bitwise OR): కనీసం ఒక బిట్ 1 అయినా 1.^(Bitwise XOR): రెండు బిట్లు వేర్వేరుగా ఉంటేనే 1 (1^0=1, 1^1=0). క్రిప్టోగ్రఫీలో విస్తృతంగా వాడతారు.~(Bitwise NOT / One's Complement): బిట్లను తిరగేస్తుంది (0 ని 1 గా, 1 ని 0 గా).<<(Left Shift): బిట్లను ఎడమవైపు జరుపుతుంది.x << 1అంటేx * 2(రెట్టింపు వేగవంతమైన గుణకారం!).>>(Right Shift): బిట్లను కుడివైపు జరుపుతుంది.x >> 1అంటేx / 2.
#include <iostream>
#include <bitset> // 8-బిట్ బైనరీ రిప్రజెంటేషన్ కోసం
int main() {
unsigned char a = 5; // బైనరీ: 00000101
unsigned char b = 3; // బైనరీ: 00000011
std::cout << "a (5) : " << std::bitset<8>(a) << '\n';
std::cout << "b (3) : " << std::bitset<8>(b) << '\n';
std::cout << "a & b : " << std::bitset<8>(a & b) << " (AND: 1)\n";
std::cout << "a | b : " << std::bitset<8>(a | b) << " (OR: 7)\n";
std::cout << "a ^ b : " << std::bitset<8>(a ^ b) << " (XOR: 6)\n";
std::cout << "a << 1 : " << (a << 1) << " (Left Shift: 5 * 2 = 10)\n";
return 0;
}
9 టెర్నరీ కండిషనల్ ఆపరేటర్ (? :)
చిన్న చిన్న if-else నిబంధనలను ఒకే ఒక్క లైన్లో అందంగా రాయడానికి Ternary Operator (? :) ఉపయోగపడుతుంది:
#include <iostream>
#include <string>
int main() {
int score = 85;
// టెర్నరీ ఆపరేటర్ ద్వారా ఒకే లైన్లో తీర్పు
std::string grade = (score >= 90) ? "A+ (Excellent)" :
(score >= 75) ? "A (Very Good)" :
(score >= 50) ? "B (Good)" : "C (Needs Improvement)";
std::cout << "విద్యార్థి స్కోర్: " << score << " => గ్రేడ్: " << grade << "\\n";
// నేరుగా std::cout లోపల వాడే విధానం
std::cout << "ఫలితం: " << ((score >= 50) ? "పాస్ (Passed!)" : "ఫెయిల్ (Failed)") << "\\n";
return 0;
}
C++ లో టెర్నరీ ఆపరేటర్ ఒక ఎక్స్ప్రెషన్ కాబట్టి దీనిని నేరుగా std::cout లోపలే లేదా const వేరియబుల్స్ ప్రారంభంలో వాడవచ్చు!
10 ఆపరేటర్ ప్రిసిడెన్స్ & అసోసియేటివిటీ (Precedence & Associativity)
ఒక సంక్లిష్టమైన ఎక్స్ప్రెషన్లో అనేక ఆపరేటర్లు ఉన్నప్పుడు (ఉదా: x = 5 + 3 * 2;), కంపైలర్ ఏ పనిని ముందు చేయాలి? దీనిని నిర్ణయించే నియమాలనే Operator Precedence (ప్రాధాన్యత) అంటారు.
గణితంలో BODMAS లాగానే, C++ లో గుణకారం (*) మరియు భాగహారానికి (/), కూడిక (+) కంటే ఎక్కువ ప్రాధాన్యత ఉంటుంది. అందుకే 5 + 3 * 2 లో ముందుగా 3 * 2 = 6 జరిగి, ఆపై 5 + 6 = 11 అవుతుంది.
| ప్రాధాన్యత (Rank) | ఆపరేటర్లు | అసోసియేటివిటీ (దిశ) | వివరణ |
|---|---|---|---|
| 1 (Highest) | :: |
Left to Right | Scope Resolution |
| 2 | (), [], ., ->, x++, x-- |
Left to Right | Function call, Array subscript, Postfix |
| 3 | ++x, --x, +, -, !, ~, sizeof |
Right to Left | Prefix, Unary plus/minus, Logical NOT |
| 4 | *, /, % |
Left to Right | Multiplicative |
| 5 | +, - |
Left to Right | Additive |
| 6 | <<, >> |
Left to Right | Bitwise Shift / Stream I/O |
| 7 | <=> |
Left to Right | Three-Way Comparison (C++20) |
| 8 | <, <=, >, >= |
Left to Right | Relational comparison |
| 9 | ==, != |
Left to Right | Equality |
| 10 | &, ^, | |
Left to Right | Bitwise AND, XOR, OR |
| 11 | &&, || |
Left to Right | Logical AND, Logical OR |
| 12 | ? : |
Right to Left | Ternary Conditional |
| 13 (Lowest) | =, +=, -=, *=, etc. |
Right to Left | Assignment operators |
💡 సీనియర్ సాఫ్ట్వేర్ ఇంజనీర్ సలహా:
ఆపరేటర్ ప్రిసిడెన్స్ టేబుల్ను బట్టీ కొట్టకండి! మీ ఉద్దేశం స్పష్టంగా ఉండటానికి ఎల్లప్పుడూ కుండలీకరణాలు () (Parentheses) వాడండి. కుండలీకరణాలకు ప్రపంచంలో అత్యధిక ప్రాధాన్యత ఉంటుంది, పైగా కోడ్ చదివే ఇతర డెవలపర్లకు ఎలాంటి గందరగోళం ఉండదు.
11 టైప్ ప్రమోషన్ & static_cast<T>()
వేర్వేరు డేటా టైపుల మధ్య ఆపరేషన్లు జరిగినప్పుడు, సమాచారం కోల్పోకుండా ఉండటానికి C++ చిన్న డేటా టైప్ను స్వయంచాలకంగా పెద్ద డేటా టైప్గా మారుస్తుంది. దీనిని Integral Promotion / Usual Arithmetic Conversions అంటారు.
int + doubleకలిపితే ఫలితంdoubleఅవుతుంది.short + shortకలిపితే CPU రిజిస్టర్లలో వేగంగా జరగడానికి కంపైలర్ రెండింటినీintగా ప్రమోట్ చేస్తుంది.
కానీ బలవంతంగా టైప్ మార్చాల్సి వచ్చినప్పుడు ఎప్పుడూ పాత C-Style కాస్టింగ్ వాడకుండా Modern static_cast<T>() మాత్రమే వాడాలి.
12 సాధారణ బిగినర్ తప్పులు, Undefined Behavior & డివిజన్ బై జీరో
కండిషన్లో if (x == 5) కి బదులుగా పొరపాటున if (x = 5) అని సింగిల్ ఈక్వల్ రాస్తే, x లోకి 5 అసైన్ అయ్యి అది ఎల్లప్పుడూ true అవుతుంది! దీనిని నివారించడానికి ఆధునిక కంపైలర్ వార్నింగ్స్ (-Wall) ఆన్ చేయండి.
ఒకే ఎక్స్ప్రెషన్లో ఒకే వేరియబుల్ను ఒకటి కంటే ఎక్కువసార్లు ఇంక్రిమెంట్ చేయడం C++ స్టాండర్డ్ ప్రకారం Undefined Behavior (UB). దీనికి నిర్దిష్ట ఫలితం ఉండదు; ఒక కంపైలర్లో 12 రావచ్చు, మరొక కంపైలర్లో 14 రావచ్చు, లేదా యాప్ క్రాష్ అవ్వవచ్చు! ఇలాంటి కోడ్ ఎప్పుడూ రాయకండి.
13 రియల్-వరల్డ్ ప్రాక్టీస్ ప్రాజెక్ట్: "Vehicle Sensor Telemetry & Bitmask Engine"
టెస్లా లేదా టాటా ఈవీ లాంటి మోడరన్ ఎలక్ట్రిక్ కార్లలో వాహన సెన్సార్ డేటా (ఇంజిన్ ఆన్, డోర్ లాక్, సీట్బెల్ట్, ఎయిర్బ్యాగ్) నెట్వర్క్ బ్యాండ్విడ్త్ ఆదా చేయడానికి సింగిల్ బైట్ లోని బిట్స్గా ప్రసారం చేయబడుతుంది.
ఈ మొదటి ఫేజ్ గ్రాండ్ ఫినాలేలో — మనం నేర్చుకున్న అరిథ్మెటిక్, రిలేషనల్, టెర్నరీ, మరియు బిట్వైజ్ మాస్కింగ్ అన్నింటినీ ఉపయోగించి ఒక పూర్తి స్థాయి "High-Performance Vehicle Telemetry Engine" ను నిర్మిద్దాం:
#include <iostream>
#include <string>
#include <iomanip>
#include <bitset>
// సెన్సార్ బిట్ మాస్క్లు (Bit Flags)
constexpr unsigned char ENGINE_ON = 1 << 0; // Bit 0 (00000001) - 1
constexpr unsigned char DOORS_LOCKED = 1 << 1; // Bit 1 (00000010) - 2
constexpr unsigned char SEATBELT_ON = 1 << 2; // Bit 2 (00000100) - 4
constexpr unsigned char HANDBRAKE_PULL = 1 << 3; // Bit 3 (00001000) - 8
int main() {
std::string vehicleModel = "TATA NEXON EV MAX (2026 Edition)";
double currentSpeedKmph = 84.50;
double batteryLevelPercent = 76.25;
int odometerKm = 14520;
// సింగిల్ బైట్ లో 4 సెన్సార్ల స్టేటస్ నిల్వ చేయడం (Bitwise OR |)
unsigned char carStatus = 0;
carStatus |= ENGINE_ON; // ఇంజిన్ స్టార్ట్ అయింది
carStatus |= DOORS_LOCKED; // డోర్స్ లాక్ అయ్యాయి
carStatus |= SEATBELT_ON; // సీట్బెల్ట్ ధరించారు
// హ్యాండ్బ్రేక్ రిలీజ్ చేయబడింది (కాబట్టి Bit 3 ఆఫ్ లో ఉంటుంది)
// బిట్వైజ్ చెకింగ్ (Bitwise AND &)
bool isEngineRunning = (carStatus & ENGINE_ON) != 0;
bool isDoorsSecure = (carStatus & DOORS_LOCKED) != 0;
bool isSeatbeltBuckled = (carStatus & SEATBELT_ON) != 0;
bool isHandbrakeEngaged = (carStatus & HANDBRAKE_PULL) != 0;
// సేఫ్టీ ఎవాల్యుయేషన్ (Logical && + Ternary ? :)
bool isDriveSafe = isEngineRunning && isDoorsSecure && isSeatbeltBuckled && !isHandbrakeEngaged;
std::string safetyAlert = isDriveSafe ? "✅ అన్ని సేఫ్టీ ప్రమాణాలు సరిగ్గా ఉన్నాయి (SAFE TO CRUISE)"
: "⚠️ ప్రమాదం! సీట్బెల్ట్ లేదా డోర్స్ సరిచూసుకోండి (SAFETY WARNING!)";
// అందమైన వెహికల్ టెలిమెట్రీ డ్యాష్బోర్డ్
std::cout << std::fixed << std::setprecision(2);
std::cout << "================================================================\n";
std::cout << " 🚗 VEHICLE TELEMETRY & SENSOR DIAGNOSTICS ENGINE \n";
std::cout << "================================================================\n";
std::cout << "వాహనం మోడల్ : " << vehicleModel << '\n';
std::cout << "ప్రస్తుత వేగం : " << currentSpeedKmph << " km/h\n";
std::cout << "బ్యాటరీ స్థాయి : " << batteryLevelPercent << " %\n";
std::cout << "ఓడోమీటర్ రీడింగ్: " << odometerKm << " km\n";
std::cout << "----------------------------------------------------------------\n";
std::cout << "సెన్సార్ రా బైట్ (Raw Byte): " << std::bitset<8>(carStatus) << " (Hex: 0x"
<< std::hex << static_cast<int>(carStatus) << std::dec << ")\n";
std::cout << "----------------------------------------------------------------\n";
std::cout << "ఇంజిన్ స్థితి : " << (isEngineRunning ? "ON (నడుస్తోంది)" : "OFF") << '\n';
std::cout << "డోర్ల భద్రత : " << (isDoorsSecure ? "LOCKED (సురక్షితం)" : "UNLOCKED (తెరిచి ఉంది)") << '\n';
std::cout << "సీట్బెల్ట్ స్థితి : " << (isSeatbeltBuckled ? "BUCKLED (ధరించారు)" : "UNBUCKLED") << '\n';
std::cout << "హ్యాండ్బ్రేక్ స్థితి: " << (isHandbrakeEngaged ? "ENGAGED" : "RELEASED (రిలీజ్ అయింది)") << '\n';
std::cout << "================================================================\n";
std::cout << "సిస్టమ్ డయాగ్నోస్టిక్స్ ఫలితం:\n" << safetyAlert << '\n';
std::cout << "================================================================\n";
return 0;
}
❓ ఇంటర్వ్యూ & పరీక్షల క్విజ్ (Knowledge Check)
ప్రశ్న 1: Prefix (++i) మరియు Postfix (i++) మధ్య తేడా ఏమిటి? C++ లో Prefix ఎందుకు ఫాస్ట్?
++i ముందు విలువను పెంచి, మారిన విలువను అందిస్తుంది; దీనికి ఎటువంటి తాత్కాలిక మెమరీ అవసరం లేదు. కానీ i++ పాత విలువను ఒక తాత్కాలిక ఆబ్జెక్ట్ (Temporary copy) లో భద్రపరిచి, ఆపై అసలు విలువను పెంచుతుంది. క్లాసెస్ మరియు లూప్ ఇటరేటర్లలో ++i వాడటం వల్ల అనవసరమైన ఆబ్జెక్ట్ కాపీయింగ్ జరగదు కాబట్టి చాలా వేగంగా పనిచేస్తుంది.
ప్రశ్న 2: లాజికల్ ఆపరేటర్లలో షార్ట్-సర్క్యూట్ ఎవాల్యుయేషన్ (Short-Circuit) అంటే ఏమిటి?
expr1 && expr2 లో expr1 గనుక ఫాల్స్ అయితే, మొత్తం ఎక్స్ప్రెషన్ ఫాల్స్ అవుతుందని ముందే తెలిసిపోతుంది కాబట్టి expr2 ను అసలు ఎవాల్యుయేట్ చేయదు. అలాగే expr1 || expr2 లో expr1 ట్రూ అయితే రెండవ దాన్ని ముట్టుకోదు. ఇది మెమరీ క్రాష్లను ఆపడానికి మరియు ప్రాసెసింగ్ సమయాన్ని ఆదా చేయడానికి చాలా ఉపయోగపడుతుంది.
ప్రశ్న 3: Modern C++20 లో వచ్చిన Spaceship Operator (<=>) ప్రయోజనం ఏమిటి?
<=> రాస్తే, కంపైలర్ మిగిలిన అన్ని కంపారిజన్ ఆపరేటర్లను స్వయంచాలకంగా సృష్టిస్తుంది (Consistent Three-Way Ordering).
ప్రశ్న 4: బిట్వైజ్ లెఫ్ట్ షిఫ్ట్ (<<) మరియు రైట్ షిఫ్ట్ (>>) గణితశాస్త్ర పరంగా ఏమి చేస్తాయి?
x << 1), అది 2 తో గుణించబడుతుంది (x * 2). అదే ఒక స్థానం కుడివైపు జరిపితే (x >> 1), అది 2 తో భాగించబడుతుంది (x / 2). CPU లో సాధారణ గుణకారాల కంటే షిఫ్ట్ ఆపరేషన్లు ఎన్నో రెట్లు వేగంగా జరుగుతాయి.
ప్రశ్న 5: int a = 5; int b = 2; double c = a / b; లో c విలువ 2.5 ఎందుకు రాదు? ఎలా పరిష్కరించాలి?
a మరియు b రెండూ పూర్ణాంకాలు కాబట్టి C++ పూర్ణాంక భాగహారం (Integer Division) చేసి దశాంశాన్ని కట్ చేసి 2 మాత్రమే ఇస్తుంది. ఆ తర్వాతే అది c లోకి వెళ్తుంది. కచ్చితమైన 2.5 రావాలంటే static_cast<double>(a) / b అని స్పష్టంగా టైప్ కాస్ట్ చేయాలి.
ఈ ప్రాజెక్ట్ను లైవ్గా మన కంపైలర్లో రన్ చేయండి!
ఎటువంటి లోకల్ సెటప్ లేకుండా, బ్రౌజర్లోనే నేరుగా Modern C++ (GCC 13 / C++20) కంపైలర్లో ఈ కోడ్ను ఎగ్జిక్యూట్ చేసి రన్టైమ్ అవుట్పుట్ను తనిఖీ చేయండి.