Unary Operators

Operators Description
++ Increment

The ++ (increment) operator adds 1 to the value of a scalar operand, or if the operand is a pointer, increments the operand by the size of the object to which it points. The operand receives the result of the increment operation. The operand must be a modifiable lvalue of arithmetic or pointer type.

You can put the ++ before or after the operand. If it appears before the operand, the operand is incremented, and then the incremented value is used in the expression. If you put the ++ after the operand, the value of the operand is used in the expression before the operand is incremented. For example:

play = ++play1 + play2++;

is equivalent to the following three expressions:

play1 = play1 + 1;
play  = play1 + play2;
play2 = play2 + 1;

Because the order of evaluation for subexpressions is not specified, avoid using a variable more than once in an expression in which the variable is incremented. For example, the following expression might cause i to be incremented before or after the function x is called:

y = x(i) + i++;

The result has the same type as the operand after integral promotion, but is not an lvalue. The usual arithmetic conversions on the operand are performed.

-- Decrement

The -- (decrement) operator subtracts 1 from the value of a scalar operand, or if the operand is a pointer, decreases the operand by the size of the object to which it points. The operand receives the result of the decrement operation. The operand must be a modifiable lvalue.

You can put the -- before or after the operand. If it appears before the operand, the operand is decremented, and the decremented value is used in the expression. If the -- appears after the operand, the current value of the operand is used in the expression and the operand is decremented.

For example:

play = --play1 + play2--;

is equivalent to the following three expressions:

play1 = play1 - 1;
play = play1 + play2;
play2 = play2 - 1;

Because the order of evaluation for subexpressions is not specified, avoid using a variable more than once in an expression in which the variable is decremented. For example, the following expression might cause i to be decremented before or after the function x is called:

y = x(i) + i--;

The result has the same type as the operand after integral promotion, but is not an lvalue. The usual arithmetic conversions on the operand are performed.

+ Unary Plus

The + (unary plus) operator maintains the value of the operand. The operand can have any arithmetic type. The result is not an lvalue.

The result of the unary plus expression has the same type as the operand after any integral promotions (for example, char to int). The usual arithmetic conversions on the operand are performed.

Note: Any plus sign in front of a constant is not part of the constant.

- Unary Minus

The + (unary plus) operator negates the value of the operand. The operand can have any arithmetic type. The result is not an lvalue.

For example, if quality has the value 100, -quality has the value -100.

The result of the unary minus expression has the same type as the operand after any integral promotions (for example, char to int). The usual arithmetic conversions on the operand are performed.

Note: Any plus sign in front of a constant is not part of the constant.

! Logical Negation

The ! (logical negation) operator determines whether the operand evaluates to 0 (false) or nonzero (true). The expression yields the value 1 (true) if the operand evaluates to 0, and the value 0 (false) if the operand evaluates to a nonzero value. The operand must have a scalar data type, but the result of the operation has always type int and is not an lvalue.

The following two expressions are equivalent:

!right;
right == 0;

The usual arithmetic conversions on the operand are performed.

~ Bitwise Negation

The ~ (bitwise negation) operator yields the bitwise complement of the operand. In the binary representation of the result, every bit has the opposite value of the same bit in the binary representation of the operand. The operand must have an integral type. The result has the same type as the operand but is not an lvalue.

Suppose x represents the decimal value 5. The 32-bit binary representation of x is:

00000000000000000000000000000101

The expression ~x yields the following result, represented here as a 32-bit binary number:

11111111111111111111111111111010

The 32-bit binary representation of ~0 is:

11111111111111111111111111111111
& Address

The & (address) operator yields a pointer to its operand. The operand must be an lvalue or function designator. It cannot be a bit field, nor can it have the storage class register.

If the operand is an lvalue or function, the resulting type is a pointer to the expression type. For example, if the expression has type int, the result is a pointer to an object having type int. The result is not an lvalue.

If p_to_y is defined as a pointer to an int and y as an int, the following expression assigns the address of the variable y to the pointer p_to_y:

p_to_y = &y;

You can use the & operator with overloaded functions only in an initialization or assignment where the left side uniquely determines which version of the overloaded function is used.

* Indirection

The * (indirection) operator determines the value referred to by the pointer-type operand.

The operand cannot be a pointer to an incomplete type. The operation yields an lvalue or a function designator if the operand points to a function. Arrays and functions are converted to pointers.

The type of the operand determines the type of the result. For example, if the operand is a pointer to an int, the result has type int.

Do not apply the indirection operator to any pointer that contains an address that is not valid, such as NULL. The result is not defined.

If p_to_y is defined as a pointer to an int and y as an int, the expressions:

p_to_y = &y;
*p_to_y = 3;

cause the variable y to receive the value 3.

Cast (type_name) Type Casting

A cast operator converts the type of the operand to a specified data type and performs the necessary conversions to the operand for the type.

The cast operator is a type specifier in parentheses. This type and the operand must be scalar. The type can also be void. The result has the type of the specified data type but is not an lvalue.

The following expression contains a cast expression, (double)x), to convert an operand of type int to a value of type double:

int x;
printf("x=%lf\n", (double)x);

The function printf receives the value of x as a double. The variable x remains unchanged by the cast.

sizeof Size of an Object

The sizeof operator yields the size in bytes of the operand. Types cannot be defined in a sizeof expression. Except in extended mode C, the sizeof operation cannot be performed on

  • A bit field
  • A function
  • An array with unspecified dimensions
  • An incomplete type (such as void)

The operand can be the parenthesized name of a type or expression.

The compiler must be able to evaluate the size at compile time. The expression is not evaluated; there are no side effects. For example, the value of b is 5 from initialization to the end of program runtime:

#include <stdio.h>

int main(void){
  int b = 5;
  sizeof(b++);
}

The result is an integer constant.

The size of a char object is the size of a byte. For example, if a variable x has type char, the expression sizeof(x) always evaluates to 1.

The result of a sizeof operation has type size_t, which is an unsigned integral type defined in the <stddef.h> header.

The size of an object is determined on the basis of its definition. The sizeof operator does not perform any conversions. If the operand contains operators that perform conversions, the compiler does take these conversions into consideration. The following expression causes the usual arithmetic conversions to be performed. The result of the expression x + 1 has type int (if x has type char, short, or int or any enumeration type) and is equivalent to sizeof(int):

sizeof (x + 1);

Except in preprocessor directives, you can use a sizeof expression wherever an integral constant is required. One of the most common uses for the sizeof operator is to determine the size of objects that are referred to during storage allocation, input, and output functions.

Another use of sizeof is in porting code across platforms. You should use the sizeof operator to determine the size that a data type represents. For example:

sizeof(int);

Using the sizeof operator on a bit field is not permitted in ansi mode. It is allowed in extended mode, and returns the same result as sizeof(int).

When applied to a C enumeration constant, sizeof always returns 4 because enumeration constants in C always have type int or unsigned int. When applied to an enumeration compiled under the enum=small option on AIX, the result of the sizeof operation is the size of the predefined type used to allocate storage for the enumeration.

The result of a sizeof expression depends on the type it is applied to:

An array:
The result is the total number of bytes in the array. For example, in an array with 10 elements, the size is equal to 1 0 times the size of a single element. The compiler does not convert the array to a pointer before evaluating the expression.

A class:
The result is always nonzero, and is equal to the number of bytes in an object of that class including any padding required for placing class objects in an array.

A reference:
The result is the size of the referenced object.



Operator Precedence and Associativity
Expressions and Operators
Types of Expressions


Operator Precedence and Associativity Table
Primary Operators
Binary Operators
Conditional Operator
Assignment Operators
Comma Operator
Arithmetic Conversions
Pointers
Overloading Functions