ఆపరేటర్లు, ఎక్స్ప్రెషన్స్ & ప్రిసిడెన్స్ నియమాలు
కంప్యూటర్ అంటే ఏమిటి? కేవలం డేటాను భద్రపరిచే ఒక స్టోరేజ్ డివైస్ మాత్రమేనా? ఖచ్చితంగా కాదు! కంప్యూటర్ యొక్క అసలైన సూపర్ పవర్ దానిలోని CPU (Central Processing Unit) మరియు ALU (Arithmetic Logic Unit) లో ఉంది. సెకనుకు బిలియన్ల కొద్దీ లెక్కలు చేయడం, రెండు సంఖ్యలలో ఏది పెద్దదో పోల్చడం, మరియు కండిషన్లను బట్టి నిర్ణయాలు తీసుకోవడమే కంప్యూటర్ యొక్క గుండెకాయ!
ఈ గణింపులను, తార్కిక నిర్ణయాలను ప్రోగ్రామర్ ఆదేశించే అత్యంత శక్తివంతమైన చిహ్నాలనే (Symbols) ప్రోగ్రామింగ్ ప్రపంచంలో ఆపరేటర్లు (Operators) అంటారు. C లాంగ్వేజ్లో ఆపరేటర్లు కేవలం గణితానికే పరిమితం కావు; కంప్యూటర్ రిజిస్టర్లలోని బైనరీ బిట్లను నేరుగా తిప్పేసే బిట్వైజ్ ఆపరేటర్లు, మైక్రోసెకన్లలో కోడ్ను ఆదా చేసే షార్ట్-సర్క్యూట్ లాజిక్, మరియు ఇంటర్వ్యూలలో విద్యార్థులను గందరగోళానికి గురిచేసే Prefix (++i) vs Postfix (i++) మెమరీ టెక్నిక్స్ C ఆపరేటర్ల ప్రత్యేకత!
ఈ నాల్గవ అధ్యాయంతో మనం మొదటి ఫేజ్ (Phase 01: బేసిక్స్ & మెమరీ ఆర్కిటెక్చర్) ను సంపూర్ణంగా పూర్తి చేసుకోబోతున్నాం. C లోని ప్రతి ఆపరేటర్, వాటి ప్రాధాన్యతా నియమాలు (Precedence), మరియు టైప్ కాస్టింగ్ రహస్యాలను లోతుగా పరిశీలిద్దాం!
- ఆపరేటర్లు & ఎక్స్ప్రెషన్స్ పరిచయం: Operands, Operators, మరియు Expressions ఆర్కిటెక్చర్.
- అరిథ్మెటిక్ ఆపరేటర్లు:
+,-,*,/,%(మాడ్యులో శేషం నియమాలు). - Prefix (++i) vs Postfix (i++): తాత్కాలిక రిజిస్టర్ కాపీ వర్సెస్ తక్షణ ఇంక్రిమెంట్ మెమరీ మెకానిక్స్.
- రిలేషనల్ ఆపరేటర్లు:
==,!=,>,<,>=,<=(C లో బూలియన్ అంటే 1 మరియు 0). - లాజికల్ ఆపరేటర్లు & షార్ట్-సర్క్యూట్:
&&,||,!లలో కండిషన్ స్కిప్పింగ్ మెకానిజం. - బిట్వైజ్ ఆపరేటర్లు:
&,|,^,~,<<,>>తో హార్డ్వేర్ లెవల్ ఫాస్ట్ మల్టిప్లికేషన్. - అసైన్మెంట్ ఆపరేటర్లు: కాంపౌండ్ అసైన్మెంట్ (
+=,-=,*=,/=). - కండిషనల్ టెర్నరీ ఆపరేటర్ (? :): వన్-లైన్ డెసిషన్ మేకింగ్ సింటాక్స్.
- ఆపరేటర్ ప్రిసిడెన్స్ & అసోసియేటివిటీ: BODMAS కంటే సంక్లిష్టమైన C ఆపరేటర్ ప్రాధాన్యతా టేబుల్.
- టైప్ కాస్టింగ్: ఇంప్లిసిట్ ప్రమోషన్ vs ఎక్స్ప్లిసిట్ టైప్ కాస్టింగ్ (
(float)a / b). - ఇంటరాక్టివ్ క్విజ్: 5 ట్రిక్కీ ప్రాక్టికల్ ప్రశ్నలు & విశ్లేషణ.
ఒక ప్రోగ్రామ్లో డేటాపై నిర్దిష్ట గణిత లేదా తార్కిక చర్యలను (Operations) చేయడానికి ఉపయోగించే చిహ్నాలను ఆపరేటర్లు (Operators) అంటారు. ఆపరేటర్ ఏ విలువలపై అయితే పనిచేస్తుందో ఆ విలువలను ఆపరాండ్లు (Operands) అంటారు:
a మరియు b లు ఆపరాండ్లు; + మరియు = లు ఆపరేటర్లు; మొత్తం కలిపి ఒక ఎక్స్ప్రెషన్ (Expression)!
ఆపరాండ్ల సంఖ్యను బట్టి C ఆపరేటర్లు 3 రకాలు:
- Unary Operators: కేవలం ఒకే ఒక ఆపరాండ్పై పనిచేస్తాయి (ఉదా:
++a,-x,!flag,sizeof(int)). - Binary Operators: రెండు ఆపరాండ్ల మధ్య పనిచేస్తాయి (ఉదా:
a + b,x * y,p > q). - Ternary Operator: మూడు ఆపరాండ్లపై పనిచేస్తుంది (కేవలం
condition ? true_val : false_val).
ప్రాథమిక గణిత అవసరాల కోసం C లో 5 అరిథ్మెటిక్ ఆపరేటర్లు ఉన్నాయి:
| ఆపరేటర్ | పేరు | ఉదాహరణ | ఫలితం | కీలక నియమం |
|---|---|---|---|---|
+ |
కూడిక (Addition) | 10 + 5 |
15 |
సాధారణ సంకలనం |
- |
తీసివేత (Subtraction) | 10 - 5 |
5 |
వ్యవకలనం |
* |
గుణకారం (Multiplication) | 10 * 5 |
50 |
గుణకారం |
/ |
భాగాహారం (Division) | 10 / 4 |
2 |
పూర్ణాంకాల భాగాహారంలో దశాంశాలు తొలగించబడతాయి (Truncated)! |
% |
మాడ్యులో శేషం (Modulus) | 10 % 3 |
1 |
భాగాహారం చేసిన తర్వాత మిగిలే శేషాన్ని (Remainder) ఇస్తుంది! |
1. ఫ్లోట్లపై పనిచేయదు:
5.5 % 2 రాస్తే కంపైలర్ error: invalid operands to binary % అని ఎర్రర్ ఇస్తుంది. మాడ్యులో కేవలం పూర్ణాంకాలపై (int, char, short, long) మాత్రమే పనిచేస్తుంది.2. నెగెటివ్ నంబర్ల గుర్తు:
-10 % 3 చేస్తే ఫలితం -1 అవుతుంది (ఎడమవైపు ఉన్న ఆపరాండ్ గుర్తు ఫలితానికి వస్తుంది).
జాబ్ ఇంటర్వ్యూలలో బిగినర్లను అత్యధికంగా గందరగోళానికి గురిచేసే టాపిక్ ఇంక్రిమెంట్ (++) మరియు డిక్రిమెంట్ (--) ఆపరేటర్లు:
CPU ముందుగా ఆ వేరియబుల్ విలువను 1 పెంచుతుంది, ఆ పెరిగిన కొత్త విలువను మాత్రమే ఎక్స్ప్రెషన్లో ఉపయోగిస్తుంది.
CPU ప్రస్తుత పాత విలువను ఒక తాత్కాలిక కాపీలో దాచి ఎక్స్ప్రెషన్లో వాడుతుంది. ఆ స్టేట్మెంట్ పూర్తయ్యాక మాత్రమే మెమరీలో విలువ 1 పెరుగుతుంది!
#include <stdio.h>
int main(void) {
int a = 5;
int b = 5;
// 1. Postfix: ముందు పాత విలువ 5 అసైన్ అవుతుంది, తర్వాత a = 6 అవుతుంది
int res1 = a++;
printf("Postfix -> res1: %d, a: %d\n", res1, a); // res1: 5, a: 6
// 2. Prefix: ముందు b = 6 అవుతుంది, తర్వాత ఆ 6 అసైన్ అవుతుంది
int res2 = ++b;
printf("Prefix -> res2: %d, b: %d\n", res2, b); // res2: 6, b: 6
return 0;
}
రెండు విలువల మధ్య సంబంధాన్ని పోల్చడానికి రిలేషనల్ ఆపరేటర్లు వాడతాం. పైథాన్లో True, False అని ప్రత్యేక బూలియన్ పదాలు ఉంటాయి. కానీ ఒరిజినల్ C భాషలో బూలియన్ డేటా టైప్ లేదు!
C లో సత్యం & అసత్యం సూత్రం:
- 0 (Zero) = అసత్యం (FALSE)
- సున్నా కాని ఏదైనా సంఖ్య (1, -5, 100) = సత్యం (TRUE)
- కంపైలర్ పోలిక నిజమైతే ఎల్లప్పుడూ 1 ని రిటర్న్ చేస్తుంది; అబద్ధమైతే 0 ని రిటర్న్ చేస్తుంది.
| ఆపరేటర్ | అర్థం | ఉదాహరణ | ఫలితం (1 or 0) |
|---|---|---|---|
== |
రెండు సమానమా? (Equal to) | 5 == 5 |
1 (True) |
!= |
సమానం కాదా? (Not Equal to) | 5 != 3 |
1 (True) |
> |
పెద్దదా? (Greater than) | 10 > 20 |
0 (False) |
< |
చిన్నదా? (Less than) | 10 < 20 |
1 (True) |
>= |
పెద్దదా లేదా సమానమా? | 15 >= 15 |
1 (True) |
<= |
చిన్నదా లేదా సమానమా? | 8 <= 12 |
1 (True) |
అనేక కండిషన్లను ఒకదానితో ఒకటి కలిపి సంక్లిష్టమైన నిర్ణయాలు తీసుకోవడానికి 3 లాజికల్ ఆపరేటర్లు ఉన్నాయి:
&&(Logical AND): రెండు కండిషన్లూ నిజమైతేనే (True) ఫలితం 1 అవుతుంది.||(Logical OR): రెండింటిలో ఏ ఒక్క కండిషన్ నిజమైనా ఫలితం 1 అవుతుంది.!(Logical NOT): సత్యాన్ని అసత్యంగా, అసత్యాన్ని సత్యంగా తలకిందులు చేస్తుంది.
⚡ షార్ట్-సర్క్యూట్ ఎవాల్యుయేషన్ (Short-Circuit Magic):
C కంపైలర్ సమయాన్ని ఆదా చేయడానికి చాలా తెలివైన టెక్నిక్ను ఉపయోగిస్తుంది:
- AND (&&) లో: మొదటి కండిషన్ ఫాల్స్ (0) అయితే — రెండో కండిషన్ను అసలు చూడను కూడా చూడదు! ఎందుకంటే ఒకటి ఫాల్స్ అయితే మొత్తం ఫాల్స్ అని తెలుసు.
- OR (||) లో: మొదటి కండిషన్ ట్రూ (1) అయితే — రెండో కండిషన్ను ఎగ్జిక్యూట్ చేయదు! ఎందుకంటే ఒకటి ట్రూ అయితే మొత్తం ట్రూ అని ఖరారైపోతుంది.
#include <stdio.h>
int main(void) {
int a = 0;
int b = 10;
// a == 0 కాబట్టి మొదటి కండిషన్ ఫాల్స్! దాంతో ++b ఎగ్జిక్యూట్ అవ్వదు!
if (a != 0 && ++b > 10) {
printf("ఈ బ్లాక్ రన్ అవ్వదు\n");
}
printf("షార్ట్ సర్క్యూట్ వల్ల b విలువ పెరగలేదు: %d\n", b); // b విలువ ఇంకా 10 మాత్రమే!
return 0;
}
కంప్యూటర్ మెమరీలోని ప్రతి బిట్ను (0 మరియు 1) నేరుగా నియంత్రించడానికి ఉపయోగించే అత్యంత శక్తివంతమైన ఆపరేటర్లు ఇవి. ఎంబెడెడ్ సిస్టమ్స్, డివైస్ డ్రైవర్లు, క్రిప్టోగ్రఫీ మరియు గేమింగ్ ఇంజిన్లలో వీటిని విరివిగా వాడతారు:
| ఆపరేటర్ | పేరు | పనితీరు | ఉదాహరణ |
|---|---|---|---|
& |
Bitwise AND | రెండు బిట్లు 1 అయితేనే 1 | 5 & 3 (101 & 011 = 001) → 1 |
| |
Bitwise OR | ఏ ఒక్క బిట్ 1 అయినా 1 | 5 | 3 (101 | 011 = 111) → 7 |
^ |
Bitwise XOR | రెండు బిట్లు వేర్వేరైతేనే 1 (సమానమైతే 0) | 5 ^ 3 (101 ^ 011 = 110) → 6 |
~ |
Bitwise NOT | ప్రతి బిట్ను తిరగేస్తుంది (0→1, 1→0) | ~5 → -6 (2's Complement) |
<< |
Left Shift | బిట్లను ఎడమవైపు జరుపుతుంది (2 తో గుణకారం!) | 5 << 1 (5 * 2) → 10 |
>> |
Right Shift | బిట్లను కుడివైపు జరుపుతుంది (2 తో భాగాహారం!) | 20 >> 1 (20 / 2) → 10 |
x * 2 కంటే x << 1 వాడటం CPU సైకిల్స్ పరంగా చాలా వేగవంతమైనది! అలాగే (n & 1) == 0 వాడితే ఆ సంఖ్య సరిసంఖ్య (Even Number) అని క్షణాల్లో తెలుసుకోవచ్చు!
ఒక వేరియబుల్కు విలువను కేటాయించడానికి = వాడతాం. కోడ్ను క్లుప్తంగా, అందంగా రాయడానికి C లో కాంపౌండ్ అసైన్మెంట్ (Compound Assignment) ఆపరేటర్లు ఉన్నాయి:
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;
చిన్న చిన్న డెసిషన్ మేకింగ్ కోసం 4 లైన్ల if-else రాయకుండా — ఒకే ఒక్క లైన్లో షార్ట్కట్గా విలువను నిర్ణయించే అద్భుతమైన ఆపరేటర్ టెర్నరీ ఆపరేటర్ (Ternary Operator):
#include <stdio.h>
int main(void) {
int marks = 75;
// టెర్నరీ ఆపరేటర్తో ఫలితం నిర్ణయం
char *result = (marks >= 40) ? "పాస్ అయ్యారు! 🎉" : "ఫెయిల్ అయ్యారు ❌";
printf("పరీక్ష ఫలితం: %s\n", result);
// రెండు సంఖ్యలలో ఏది పెద్దదో కనుగొనడం
int x = 45, y = 80;
int max = (x > y) ? x : y;
printf("పెద్ద సంఖ్య: %d\n", max);
return 0;
}
ఒక ఎక్స్ప్రెషన్లో అనేక ఆపరేటర్లు ఉన్నప్పుడు (ఉదా: x = 5 + 3 * 2;) — కంపైలర్ ఏ పనిని ముందు చేయాలి? పాఠశాలలో మనం నేర్చుకున్న BODMAS సూత్రం C లో సరిపోదు; C కి ప్రత్యేకమైన 15 స్థాయిల Precedence (ప్రాధాన్యత) మరియు Associativity (దిశ) నియమాలు ఉన్నాయి:
| ప్రాధాన్యత (Rank) | ఆపరేటర్ కేటగిరీ | ఆపరేటర్లు | అసోసియేటివిటీ (దిశ) |
|---|---|---|---|
| 1 (అత్యున్నతం) | పోస్ట్ఫిక్స్ & గ్రూపింగ్ | (), [], ->, ., i++, i-- |
ఎడమ నుండి కుడికి (Left to Right) |
| 2 | యునరీ ఆపరేటర్లు | ++i, --i, !, ~, +, -, *(ptr), &, sizeof |
కుడి నుండి ఎడమకు (Right to Left) |
| 3 | గుణకారం/భాగాహారం | *, /, % |
ఎడమ నుండి కుడికి |
| 4 | కూడిక/తీసివేత | +, - |
ఎడమ నుండి కుడికి |
| 5 | బిట్వైజ్ షిఫ్ట్ | <<, >> |
ఎడమ నుండి కుడికి |
| 6 | రిలేషనల్ పోలిక | <, <=, >, >= |
ఎడమ నుండి కుడికి |
| 7 | సమానత్వం | ==, != |
ఎడమ నుండి కుడికి |
| 8 | లాజికల్ AND / OR | &&, || |
ఎడమ నుండి కుడికి |
| 9 | టెర్నరీ | ? : |
కుడి నుండి ఎడమకు |
| 10 (అత్యల్పం) | అసైన్మెంట్ | =, +=, -=, *=, /= |
కుడి నుండి ఎడమకు |
( ) వాడండి. బ్రాకెట్లకు అన్నింటికంటే అత్యున్నత ప్రాధాన్యత ఉంటుంది కాబట్టి బ్రాకెట్లోని పని ఎల్లప్పుడూ మొదట జరుగుతుంది!
ఒక డేటా టైప్ను మరొక డేటా టైప్గా మార్చే ప్రక్రియనే టైప్ కాస్టింగ్ (Type Casting) అంటారు. ఇది రెండు రకాలుగా జరుగుతుంది:
1. ఇంప్లిసిట్ టైప్ కాస్టింగ్ (Implicit Type Promotion):
రెండు వేర్వేరు సైజు గల డేటా టైప్స్ కలిసినప్పుడు — కంపైలర్ స్వయంచాలకంగా చిన్న డేటా టైప్ను పెద్ద డేటా టైప్గా ప్రమోట్ చేస్తుంది (ఉదాహరణకు int + float కలిపితే ఫలితం ఆటోమేటిక్గా float అవుతుంది).
2. ఎక్స్ప్లిసిట్ టైప్ కాస్టింగ్ (Explicit Casting):
ప్రోగ్రామర్ ఉద్దేశపూర్వకంగా ఒక విలువ ముందు బ్రాకెట్లలో కావాల్సిన డేటా టైప్ రాసి బలవంతంగా మార్చడం:
#include <stdio.h>
int main(void) {
int totalMarks = 485;
int subjects = 6;
// 1. కాస్టింగ్ లేకపోతే: 485 / 6 = 80.000000 మాత్రమే వస్తుంది!
float wrongAvg = totalMarks / subjects;
printf("తప్పుడు సగటు : %.2f\n", wrongAvg);
// 2. ఎక్స్ప్లిసిట్ కాస్టింగ్: (float)totalMarks ద్వారా 80.833336 వస్తుంది!
float correctAvg = (float)totalMarks / subjects;
printf("సరైన సగటు : %.2f\n", correctAvg);
return 0;
}
ఈ నాల్గవ అధ్యాయంలో మీరు నేర్చుకున్న ఆపరేటర్ల సూక్ష్మ భావనలను పరీక్షించుకోవడానికి క్రింది ప్రశ్నలపై క్లిక్ చేయండి:
❓ ప్రశ్న 1: 5.0 % 2 చేస్తే C లో ఫలితం ఎంత వస్తుంది?
❓ ప్రశ్న 2: int x = 10; int y = x++; రన్ అయ్యాక x మరియు y ల విలువలు ఎంత ఉంటాయి?
x++) లో ముందు పాత విలువ 10 ని y కి కేటాయించి, ఆ తర్వాత x విలువ 11 గా మారుతుంది.
❓ ప్రశ్న 3: 8 << 2 బిట్వైజ్ లెఫ్ట్ షిఫ్ట్ చేస్తే వచ్చే సంఖ్య ఎంత?
8 * 2^2 = 32).
❓ ప్రశ్న 4: C లాంగ్వేజ్లో ఏకైక టెర్నరీ ఆపరేటర్ ఏది?
❓ ప్రశ్న 5: int res = 10 + 5 * 2; లో మొదట ఏ ఆపరేషన్ జరుగుతుంది?
+) కంటే గుణకారం (*) కి ఎక్కువ ప్రాధాన్యత ఉంటుంది. కాబట్టి ఫలితం 20 అవుతుంది.
పైన వివరించిన Prefix vs Postfix మరియు Bitwise Left-shift కోడ్లను మన ఆన్లైన్ C కంపైలర్లో రన్ చేయండి. ఆపరేటర్లను మార్చి మీ స్వంత గణిత ప్రయోగాలను లైవ్గా చేసి చూడండి!
🎓 Phase 01: బేసిక్స్ & మెమరీ ఆర్కిటెక్చర్ పూర్తయింది!
🌟 Phase 01 లో మీరు సాధించిన 4 మైలురాళ్ళు:
- Chapter 01: Dennis Ritchie హిస్టరీ, C ప్రాముఖ్యత, 4-దశల GCC పైప్లైన్ మరియు Hello World అనాటమీ.
- Chapter 02: RAM మెమరీ స్లాట్లు, డేటా టైప్స్ (int, float, char), sizeof మరియు Signed/Unsigned ఓవర్ఫ్లో.
- Chapter 03: stdin స్ట్రీమ్స్, scanf మెకానిక్స్, & అడ్రస్ ఆపరేటర్ మరియు డేంజరస్ బఫర్ ట్రాప్స్.
- Chapter 04: అరిథ్మెటిక్, రిలేషనల్, లాజికల్ షార్ట్-సర్క్యూట్, బిట్వైజ్ ఆపరేటర్లు మరియు టైప్ కాస్టింగ్.
ఇప్పుడు మీకు కంప్యూటర్ మెమరీ, వేరియబుల్స్ మరియు డేటాపై పూర్తి నియంత్రణ లభించింది! ఇక మనం ప్రోగ్రామ్కు ఆలోచించే శక్తిని మరియు పనులను పదేపదే చేసే సత్తాను అందించే రెండవ దశలోకి అడుగుపెడదాం!