Skip to content Skip to main navigation Skip to footer

C Operators

C Language operators

The C programming language has a very large number of operators, more than 50 in total, which can be divided into several categories.

Arithmetic Operators

Arithmetic operators are used exclusively for arithmetic operations and contain the following types.

  • +: positive value operator (unary operator)
  • -: Negative operators (unary operators)
  • +: addition operator (binary operator)
  • -: subtraction operator (binary operator)
  • *: Multiplication operator
  • /: division operator
  • %: remainder operator

Arithmetic operators +,-

Both + and - can be used as either unary or binary operators. The term “unary operator” refers to the fact that only one operator is needed to perform the operation. The unary operator - is used to change the plus or minus sign of a value.

int x = -12;

In the above example, - converts the value 12 to -12.

The unary operator + has no effect on positive or negative values and is an operator that can be omitted entirely, but will not report an error if written.

int x = -12;
int y = +x;

In the above example, the value of the variable y is still -12, because + does not change the positive or negative values.

The binary operators + and - are used to complete addition and subtraction.

int x = 4 + 22;
int y = 61 - 23;

Arithmetic operators *

The operator * is used to complete the multiplication.

int num = 5;
printf("%i\n", num * num); // Outpu 25

Arithmetic operators /

The operator / is used to complete the division. Note that the division of two integers still yields an integer.

float x = 6 / 4;
printf("%f\n", x); // Output 1.000000

In the above example, even though the variable x is declared as float, the result of 6 / 4 is 1.0 instead of 1.5. The reason for this is that integer division in C is integer division, which returns only the integer part and discards the fractional part.

If you want to get a floating point result, both operators must have at least one floating point number, so that C performs a floating point division.

float x = 6.0 / 4; // or 6 / 4.0
printf("%f\n", x); // Output 1.500000

In the above example, 6.0 / 4 means dividing by a floating point number, the result is 1.5.

Here is another example:

int score = 5;
score = (score / 20) * 100;

In the above code, you may think that after the operation, the score will be equal to 25, but in fact the score is equal to 0. This is because score / 20 is an integer division, which will give an integer value of 0, so the multiplication by 100 will also give 0.

To get the desired result, you can change the divisor 20 to 20.0 to make the integer division into a floating point division.

score = (score / 20.0) * 100;

Arithmetic operators %

The % operator represents the modulo operation, which returns the remainder of two integers divided by each other. This operator can only be used with integers, not with floating point numbers.

int x = 6 % 4; // 2

The modulo rule for negative numbers is that the positive and negative sign of the result is determined by the positive and negative sign of the first operator.

11 % -5 // 1
-11 % -5 // -1
-11 % 5 // -1

In the above example, the plus or minus sign of the first operator (11 or -11) determines the plus or minus sign of the result.

Abbreviated form of assignment operations

If a variable performs arithmetic operations on its own value, C provides shorthand forms that allow the assignment and arithmetic operators to be combined into a single operator.

  • +=
  • -=
  • *=
  • /=
  • %=

Here are some examples.

i += 3; // equals to i = i + 3

i -= 8; // equals to  i = i - 8

i *= 9; // equals to  i = i * 9

i /= 2; // equals to  i = i / 2

i %= 5; // equals to i = i % 5

Increment operator, decrement operator

The C programming language provides two operators that perform + 1 and - 1 operations on variables themselves.

++: increament operator
--: decrement operator
i++; // equal to i = i + 1
i--; // equal to  i = i - 1

These two operators are placed before or after the variable, and their results are different. ++var and --var perform the increment or decrement operation first and then return the value of var after the operation; var++ and var -- return the value of var before the operation and then perform the increment or decrement operation.

int i = 42;
int j;

j = (i++ + 10);

// i: 43
// j: 52

j = (++i + 10)

// i: 44
// j: 54

In the above example, the different positions of the incremental operators cause the variable j to get a different value. Such a writing style is prone to unexpected results, so to eliminate surprises, you can rewrite it as follows.

j = (i + 10);
i++;

i++;
j = (i + 10);

In the above example, the increment operation of variable i and the return value are two separate steps, which makes it less likely that errors will occur and improves the readability of the code

Relational Operators

The expressions used for comparison in C programming language are called “relational expressions” and the operators used in them are called “relational operators“.

  • > Greater than operator
  • < Less than operator
  • >= Greater than or equal to operator
  • <= Less than operator
  • == Equality operator
  • ! = inequality operator

Here are some examples:

a == b;
a != b;
a < b;
a > b;
a <= b;
a >= b;

Relational expressions usually return either 0 or 1, indicating true or false; in the C programming language, 0 indicates false and all non-zero values indicate true.

For example, 20 > 12 returns 1, and 12 > 20 returns 0.

Relational expressions are often used in if or while structures.

if (x == 3) 
{
    printf("x is 3.\n");
}

Note that the equality operator == and the assignment operator = are two different operators and should not be confused. Sometimes, the following code may be written accidentally, and it will run, but it can easily have unexpected results.

if (x = 3) ...

In the above example, the original meaning is x == 3, but it is accidentally written as x = 3. This equation means that the variable x is assigned the value 3 and it returns 3, so the if statement is always true.

To prevent this error, some programmers like to write the variable to the right of the equal sign.

if (3 == x) ...

In this case, if == is written incorrectly as =, the compiler will report an error.

/* output error*/
if (3 = x) ...

Another mistake to avoid is that multiple relational operators should not be used concatenated together.

i < j < k

In the above example, two less-than operators are used in the expression. This is a legal expression that does not report errors, but usually does not achieve the desired result, i.e., it does not guarantee that the value of variable j is between i and k. Because the relational operator is calculated from left to right, the following expression is actually executed.

(i < j) < k

In the above expression, i < j returns 0 or 1, so the final comparison with variable k is 0 or 1. If you want to determine if the value of variable j is between i and k, you should use the following code.

i < j && j < k

Logical Operators

Logical operators provide logical definitions for building more complex expressions.

  • ! : Not operator (changes the true or false of a single expression).
  • &&: AND operator (true if both sides of an expression are true, false otherwise).
  • ||: OR operator (true if at least one expression on both sides is true, false otherwise).

The following is an example of the AND operator.

if (x < 200 && y > 100)
    printf("this is AND operator!\n");

In the above example, only x < 200 and y > 100 are true at the same time, x < 200 && y > 100 will be true.

The following is an example of NOT operator.

if (!(x < 100))
    printf("variable x is not less than 100\n");

In the above example, since the NOT operator ! has higher precedence than <, you must use square brackets to perform the NOT operation on the expression x < 100. Of course, a reasonable way to write this would be if(x >= 100).

For logical operators, any non-zero value means true, and a zero value means false. For example, 5 || 0 would return 1, and 5 && 0 would return 0.

The logical operator also has a functionality that it always evaluates the expression on the left side before the expression on the right side, and this order is guaranteed. If the left expression satisfies the conditions of the logical operator, the right expression is no longer evaluated. This situation is called “short-circuiting“.

if (number != 0 && 12/number == 2)

In the above example, if the expression on the left side of && (number ! = 0) is false, i.e., if number equals 0, the expression on the right (12/number == 2) will not be executed. Because the left expression returns 0, the entire && expression becomes false, and the right expression is no longer executed.

Bitwise Operators

The C programming language provides a number of bit operators to manipulate binary bits.

Complement operator

The complement operator ~ is a unary operator used to convert each binary bit to its opposite value, i.e., 0 becomes 1 and 1 becomes 0.

// return 01101100
~ 10010011

In the above example, ~ inverts each binary bit to get a new value.

Note: The ~ operator does not change the value of the variable, it just returns a new value.

Binary AND Operator &

The binary AND operator & compares each binary bit of two values and returns a new value. When both binary bits are 1, 1 is returned, otherwise 0 is returned.

// returns 00010001
10010011 & 00111101

In the above example, two eight-bit binary numbers are compared bit by bit and a new value is returned.

Binary OR Operator |

The binary OR operator | compares each binary bit of two values and returns a new value. Two binary bits return 1 as long as one is 1 (including the case where both are 1), otherwise they return 0.

// returns 10111111
10010011 | 00111101

Binary XOR Operator ^

The binary XOR operator ^ compares each binary bit of two values and returns a new value. If one and only one of the two binary bits is 1, 1 is returned, otherwise 0 is returned.

// Return 10101110
10010011 ^ 00111101

Binary Left Shift Operator <<

The binary Left Shift operator << shifts each bit of the left operator to the left by the specified number of bits, with the subsequent empty bits filled by zeros.

// 1000101000
10001010 << 2

In the above example, each binary bit of 10001010 is shifted two positions to the left.

The left shift operator is equivalent to multiplying by a specified power of 2. For example, a left shift of 2 bits is equivalent to multiplying by 4 (2 to the power of 2).

Binary Left Shift Operator >>

The binary right shift operator >> shifts each bit of the left operator, to the right by the specified number of bits, and the last value that cannot fit is discarded and the empty bit in the header is filled with zero.

// Return 00100010
10001010 >> 2

In the above example, each binary bit of 10001010 is shifted two positions to the right. The two lowest 10 bits are discarded and the top two bits are filled with zeros, so we end up with 00100010.

Note: the right-shift operator is best used only for unsigned integers, not negative numbers. This is because different systems have different approaches to how to handle the sign bit of a negative number after a right shift, and may yield different results.

The right shift operator is equivalent to dividing the operator by a specified power of 2. For example, a right shift of 2 bits is equivalent to dividing by 4 (2 to the power of 2).

Comma Operators

The comma operator is used to write multiple expressions together, running each expression in turn from left to right.

x = 10, y = 20;

In the above example, there are two expressions (x=10 and y=20) and the comma makes it possible to put them in the same statement.

The comma operator returns the value of the last expression as the value of the whole statement.

int x;
x = 1, 2, 3;

In the above example, the comma has lower priority than the assignment operator, so the assignment operation is performed first, then the comma operation is performed, and the variable x equals 1.

Operator precedence

The precedence is if an expression contains more than one operator, which operator should be executed first. The precedence of various operators is different.

3 + 4 * 5;

In the above example, the expression 3+4*5 has both an addition operator (+) and a multiplication operator (*) in it. Since multiplication has higher priority than addition, 4*5 will be computed first instead of 3+4.

If two operators have the same priority, the order of execution is determined by whether the operators are left-bound, or right-bound. Most operators are left combined (executed from left to right) and a few operators are right combined (executed from right to left), such as the assignment operator (=).

5 * 6 / 2;

In the above example, * and / have the same precedence, and they are both left bonding operators, so they are executed from left to right, calculating 5 * 6 first, then 6 / 2.

The precedence of operators is complex. Here are the precedences of some of the operators (listed from highest to lowest precedence)

  • Round brackets (())
  • Increment operator (++), decrement operator (–)
  • Unary operators (+ and -)
  • Multiplication (*), Division (/)
  • Addition (+), subtraction (-)
  • Relational operators (<, >, etc.)
  • Assignment operators (=)

Completely remembering the order of precedence of all operators is not necessary. The solution is to use more parentheses to prevent surprises and to help improve the readability of the code.

Was This Article Helpful?

1
Related Articles
0 Comments

There are no comments yet

Leave a comment

Your email address will not be published.