Operators in C-3 | Programming and Data Structures - Computer Science Engineering (CSE) PDF Download

Increment (Decrement) operators require L-value Expression

What will be the output of the following program?
#include<stdio.h>
int main()
{
   int i = 10;
   printf("%d", ++(-i));
   return 0;
}
(a) 11
(b) 10
(c) -9
(d) None
Ans: (d)
Explanation: In C/C++ the pre-increment (decrement) and the post-increment (decrement) operators require an L-value expression as operand. Providing an R-value or a const qualified variable results in compilation error.
In the above program, the expression -i results in R-value which is operand of pre-increment operator. The pre-increment operator requires an L-value as operand, hence the compiler throws an error.
The increment/decrement operators needs to update the operand after the sequence point, so they need an L-value. The unary operators such as -, +, won’t need L-value as operand. The expression -(++i) is valid.
In C++ the rules are little complicated because of references. We can apply these pre/post increment (decrement) operators on references variables that are not qualified by const. References can also be returned from functions.

Precedence of postfix ++ and prefix ++ in C/C++

In C/C++, precedence of Prefix ++ (or Prefix –) has higher priority than dereference (*) operator, and precedence of Postfix ++ (or Postfix –) is higher than both Prefix ++ and *.
If p is a pointer then *p++ is equivalent to *(p++) and ++*p is equivalent to ++(*p) (both Prefix ++ and * are right associative).
For example, program 1 prints ‘h’ and program 2 prints ‘e’.
// Program 1
#include<stdio.h>
int main()
{
  char arr[] = "geeksforgeeks";
  char *p = arr;
  ++*p;
  printf(" %c", *p);
  getchar();
  return 0;
}
Output: h

// Program 2
#include<stdio.h>
int main()
{
  char arr[] = "geeksforgeeks";
  char *p = arr;
  *p++;
  printf(" %c", *p);
  getchar();
  return 0;
}
Output: e

Modulus on Negative Numbers

What will be the output of the following C program?
#include <stdio.h>
int main()
{
   int a = 3, b = -8, c = 2;
   printf("%d", a % b / c);
   return 0;
}
Output: 1

% and / have same precedence and left to right associativity. So % is performed first which results in 3 and / is performed next resulting in 1. The emphasis is, sign of left operand is appended to result in case of modulus operator in C.
#include <stdio.h>
int main()
{
   // a positive and b negative.
   int a = 3, b = -8;
   printf("%d", a % b);
   return 0;
}
Output: 3
#include <stdio.h>
int main()
{
   // a negative and b positive
   int a = -3, b = 8;
   printf("%d", a % b);
   return 0;
}
Output: -3
#include <stdio.h>
int main()
{
   // a and b both negative
   int a = -3, b = -8;
   printf("%d", a % b);
   return 0;
}
Output: -3

C/C++ Ternary Operator – Some Interesting Observations

Predict the output of following C++ program.
#include <iostream>
using namespace std;
int main()
{
   int test = 0;
   cout << "First  character " << '1' << endl;
   cout << "Second character " << (test ? 3 : '1') << endl;
   return 0;
}
One would expect the output will be same in both the print statements. However, the output will be,
First  character 1
Second character 49
Why the second statement printing 49? Read on the ternary expression.

Ternary Operator (C/C++)

A ternary operator has the following form,
exp1 ? exp2 : exp3
The expression exp1 will be evaluated always. Execution of exp2 and exp3 depends on the outcome of exp1. If the outcome of exp1 is non zero exp2 will be evaluated, otherwise exp3 will be evaluated.

1. Side Effects: Any side effects of exp1 will be evaluated and updated immediately before executing exp2 or exp3. In other words, there is sequence point after the evaluation of condition in the ternary expression. If either exp2 or exp3 have side effects, only one of them will be evaluated.
2. Return Type: It is another interesting fact. The ternary operator has return type. The return type depends on exp2, and convertibility of exp3 into exp2 as per usual\overloaded conversion rules. If they are not convertible, the compiler throws an error. See the examples below,
The following program compiles without any error. The return type of ternary expression is expected to be float (as that of exp2) and exp3 (i.e. literal zero – int type) is implicitly convertible to float.
#include <iostream>
using namespace std;
int main()
{
   int test = 0;
   float fvalue = 3.111f;
   cout << (test ? fvalue : 0) << endl;
   return 0;
}
The following program will not compile, because the compiler is unable to find return type of ternary expression or implicit conversion is unavailable between exp2 (char array) and exp3 (int).
#include <iostream>
using namespace std;
int main()
{
   int test = 0;
   cout << test ? "A String" : 0 << endl;
   return 0;
}
The following program *may* compile, or but fails at runtime. The return type of ternary expression is bounded to type (char *), yet the expression returns int, hence the program fails. Literally, the program tries to print string at 0th address at runtime.
#include <iostream>
using namespace std;
int main()
{
   int test = 0;
   cout << (test ? "A String" : 0) << endl;
   return 0;
}
We can observe that exp2 is considered as output type and exp3 will be converted into exp2 at runtime. If the conversion is implicit the compiler inserts stubs for conversion. If the conversion is explicit the compiler throws an error. If any compiler misses to catch such error, the program may fail at runtime.
3. Best Practice: It is the power of C++ type system that avoids such bugs. Make sure both the expressions exp2 and exp3 return same type or atleast safely convertible types. ​We can see other idioms like C++ convert union for safe conversion.

Difference between ++*p, *p++ and *++p

Predict the output of following C programs.
// Program 1
#include <stdio.h>
int main(void)
{
    int arr[] = {10, 20};
    int *p = arr;
    ++*p;
    printf("arr[0] = %d, arr[1] = %d, *p = %d",
                          arr[0], arr[1], *p);
    return 0;
}
// PROGRAM 2
#include <stdio.h>
int main(void)
{
    int arr[] = {10, 20};
    int *p = arr;
    *p++;
    printf("arr[0] = %d, arr[1] = %d, *p = %d",
                          arr[0], arr[1], *p);
    return 0;
}
// Program 3
#include <stdio.h>
int main(void)
{
    int arr[] = {10, 20};
    int *p = arr;
    *++p;
    printf("arr[0] = %d, arr[1] = %d, *p = %d",
                          arr[0], arr[1], *p);
    return 0;
}
The output of above programs and all such programs can be easily guessed by remembering following simple rules about postfix ++, prefix ++ and * (dereference) operators

  1. Precedence of prefix ++ and * is same. Associativity of both is right to left.
  2. Precedence of postfix ++ is higher than both * and prefix ++. Associativity of postfix ++ is left to right.
    The expression ++*p has two operators of same precedence, so compiler looks for assoiativity. Associativity of operators is right to left. Therefore the expression is treated as ++(*p). Therefore the output of first program is “arr[0] = 11, arr[1] = 20, *p = 11“.
    The expression *p++ is treated as *(p++) as the precedence of postfix ++ is higher than *. Therefore the output of second program is “arr[0] = 10, arr[1] = 20, *p = 20“.
    The expression *++p has two operators of same precedence, so compiler looks for assoiativity. Associativity of operators is right to left. Therefore the expression is treated as *(++p). Therefore the output of third program is “arr[0] = 10, arr[1] = 20, *p = 20“.

Pre-increment (or pre-decrement) in C++

In C++, pre-increment (or pre-decrement) can be used as l-value, but post-increment (or post-decrement) can not be used as l-value.
For example, following program prints a = 20 (++a is used as l-value)
// CPP program to illustrate
// Pre-increment (or pre-decrement)
#include <cstdio>
int main()
{
    int a = 10;
    ++a = 20; // works
    printf("a = %d", a);
    getchar();
    return 0;
}
a = 20
The above program works whereas the following program fails in compilation with error “non-lvalue in assignment” (a++ is used as l-value)
// CPP program to illustrate
// Post-increment (or post-decrement)
#include <cstdio>
int main()
{
    int a = 10;
    a++ = 20; // error
    printf("a = %d", a);
    getchar();
    return 0;
}
prog.cpp: In function 'int main()':
prog.cpp:6:5: error: lvalue required as left operand of assignment
 a++ = 20; // error
     ^

How ++a is different from a++ as lvalue?
It is because ++a returns an lvalue, which is basically a reference to the variable to which we can further assign — just like an ordinary variable. It could also be assigned to a reference as follows:
int &ref = ++a; // valid
int &ref = a++; // invalid
Whereas if you recall how a++ works, it doesn’t immediately increment the value it holds. For brevity, you can think of it as getting incremented in the next statement. So what basically happens is that a++ returns an rvalue, which is basically just a value like the value of an expression which is not stored. You can think of a++ = 20; as follows after being processed:
int a = 10;
// On compilation, a++ is replaced by the value of a which is an rvalue:
10 = 20; // Invalid
// Value of a is incremented
a = a + 1;
That should help to understand why a++ = 20; won’t work.

The document Operators in C-3 | Programming and Data Structures - Computer Science Engineering (CSE) is a part of the Computer Science Engineering (CSE) Course Programming and Data Structures.
All you need of Computer Science Engineering (CSE) at this link: Computer Science Engineering (CSE)
119 docs|30 tests

Top Courses for Computer Science Engineering (CSE)

FAQs on Operators in C-3 - Programming and Data Structures - Computer Science Engineering (CSE)

1. What is the eligibility criteria for appearing in the C-3 GATE exam?
Ans. To appear in the C-3 GATE exam, candidates must have a Bachelor's degree in Computer Science or a related field. They should also have a minimum percentage of marks as specified by the conducting authority.
2. How can I apply for the C-3 GATE exam?
Ans. The application process for the C-3 GATE exam is online. Candidates need to visit the official website and fill out the application form with the required details, upload necessary documents, and pay the application fee. It is important to submit the application within the specified deadline.
3. What is the exam pattern of the C-3 GATE exam?
Ans. The C-3 GATE exam consists of multiple-choice questions and numerical answer type questions. The duration of the exam is three hours. The paper is divided into multiple sections, including technical aptitude, programming, data structures, algorithms, and computer networks. The weightage of each section may vary depending on the year.
4. Are there any negative marks in the C-3 GATE exam?
Ans. Yes, there are negative marks in the C-3 GATE exam. For every incorrect multiple-choice question, 1/3 of the marks allotted to that question will be deducted. However, there are no negative marks for numerical answer type questions.
5. How can I prepare for the C-3 GATE exam effectively?
Ans. To prepare for the C-3 GATE exam effectively, candidates can follow a structured study plan, refer to standard textbooks and study materials, solve previous years' question papers, and take online mock tests. It is also important to understand the exam pattern and syllabus thoroughly and focus on weak areas to improve overall performance. Additionally, joining coaching classes or online tutorials can provide guidance and additional resources for preparation.
119 docs|30 tests
Download as PDF
Explore Courses for Computer Science Engineering (CSE) exam

Top Courses for Computer Science Engineering (CSE)

Signup for Free!
Signup to see your scores go up within 7 days! Learn & Practice with 1000+ FREE Notes, Videos & Tests.
10M+ students study on EduRev
Related Searches

Viva Questions

,

Semester Notes

,

Exam

,

Operators in C-3 | Programming and Data Structures - Computer Science Engineering (CSE)

,

MCQs

,

past year papers

,

Summary

,

Important questions

,

video lectures

,

ppt

,

Operators in C-3 | Programming and Data Structures - Computer Science Engineering (CSE)

,

Sample Paper

,

study material

,

pdf

,

mock tests for examination

,

Operators in C-3 | Programming and Data Structures - Computer Science Engineering (CSE)

,

shortcuts and tricks

,

Previous Year Questions with Solutions

,

Extra Questions

,

Objective type Questions

,

practice quizzes

,

Free

;