United States    
COMPAQ STORE | PRODUCTS |
SERVICES | SUPPORT | CONTACT US | SEARCH
Compaq C

Compaq C
Language Reference Manual


Previous Contents Index


Chapter 6
Expressions and Operators

An expression is any sequence of C operators and operands that produces a value or generates a side effect. The simplest expressions are constants and variable names, which yield values directly. Other expressions combine operators and subexpressions to produce values. An expression has a type as well as a value.

Except where noted in this chapter, the order of evaluation of subexpressions, and the order in which side effects take place, is unspecified. Code that depends on such order might produce unexpected results.

The operands of expressions must have compatible type. In some instances, the compiler makes conversions to force the data types of the operands to be compatible.

The following sections discuss these topics:

6.1 Primary Expressions

Simple expressions are called primary expressions; they denote values. Primary expressions include previously declared identifiers, constants, string literals, and parenthesized expressions.

Primary expressions have the following syntax:

primary-expression:

identifier
constant
string-literal
expression

The following sections describe the primary expressions.

6.1.1 Identifiers

An identifier is a primary expression provided it is declared as designating an object or a function.

An identifier that designates an object is an lvalue if its type is arithmetic, structure, union, or pointer. The name of an array evaluates to the address of the first element of the array; an array name is an lvalue but not a modifiable lvalue.

An identifier that designates a function is called a function designator. A function designator evaluates to the address of the function.

6.1.2 Constants

A constant is a primary expression. Its type depends on its form (integer, character, floating, or enumeration); see Section 1.8. A constant is never an lvalue.

6.1.3 String Literals

A string literal is a primary expression. Its type depends on its form (character or wchar_t ); see Section 1.8. A string literal is an lvalue.

6.1.4 Parenthesized Expressions

An expression within parentheses has the same type and value as the expression without parentheses would have. Any expression can be delimited by parentheses to change the precedence of its operators.

6.2 Overview of the C Operators

Variables and constants can be used in conjunction with C operators to create more complex expressions. Table 6-1 presents the set of C operators.

Table 6-1 C Operators
Operator Example Description/Meaning
() f() Function call
[] a[10] Array reference
-> s->a Structure and union member selection
. s.a Structure and union member selection
+ [unary] +a Value of a
- [unary] -a Negative of a
* [unary] *a Reference to object at address a
& [unary] &a Address of a
~ ~a One's complement of a
++ [prefix] ++a The value of a after increment
++ [postfix] a++ The value of a before increment
-- [prefix] --a The value of a after decrement
-- [postfix] a-- The value of a before decrement
sizeof sizeof (t1) Size in bytes of object with type t1
sizeof sizeof e Size in bytes of object having the type of expression e
__typeof__ __typeof__ (t1) Type of type t1
__typeof__ __typeof__ (e) Type of expression e
+ [binary]
- [binary]
* [binary]
/
%
a + b
a - b
a * b
a / b
a % b
a plus b
a minus b
a times b
a divided by b
Remainder of a/b
>>
<<
a >> b
a << b
a, right-shifted b bits
a, left-shifted b bits
& [binary]
|
^
a & b
a | b
a ^ b
Bitwise AND of a and b
Bitwise OR of a and b
Bitwise XOR (exclusive OR) of a and b
&&
||
!
a && b
a || b
!a
Logical AND of a and b (yields 0 or 1)
Logical OR of a and b (yields 0 or 1)
Logical NOT of a (yields 0 or 1)
?: a ? e1 : e2 Expression e1 if a is nonzero;
Expression e2 if a is zero
=
+=
-=
*=
/=
%=
>>=
<<=
&=
|=
^=
,
a = b
a += b
a -= b
a *= b
a /= b
a %= b
a >>= b
a <<= b
a &= b
a |= b
a ^= b
e1,e2
a, after b is assigned to it
a plus b (assigned to a)
a minus b (assigned to a)
a times b (assigned to a)
a divided by b (assigned to a)
Remainder of a/b (assigned to a)
a, right-shifted b bits (assigned to a)
a, left-shifted b bits (assigned to a)
a AND b (assigned to a)
a OR b (assigned to a)
a XOR b (assigned to a)
e2 (e1 evaluated first)

The C operators fall into the following categories:

Operator precedence determines the grouping of terms in an expression. This affects how an expression is evaluated. Certain operators have higher precedence than others; for example, the multiplication operator has higher precedence than the addition operator:


x = 7 + 3 * 2;        /* x is assigned 13, not 20   */ 

The previous statement is equivalent to the following:


x = 7 + ( 3 * 2 ); 

Using parenthesis in an expression alters the default precedence. For example:


x = (7 + 3) * 2;  /*  (7 + 3) is evaluated first    */ 

In an unparenthesized expression, operators of higher precedence are evaluated before those of lower precedence. Consider the following expression:


A+B*C 

The identifiers B and C are multiplied first because the multiplication operator (*) has higher precedence than the addition operator (+).

Table 6-2 shows the precedence the compiler uses to evaluate the C operators. Operators with the highest precedence appear at the top of the table; those with the lowest appear at the bottom. Operators of equal precedence appear in the same row.

Table 6-2 Precedence of C Operators
Category Operator Associativity
Postfix ( ) [] -> . ++ -- Left to right
Unary + - ! ~ ++ -- (type)
* & sizeof
Right to left
Multiplicative * / % Left to right
Additive + - Left to right
Shift << >> Left to right
Relational < <= > >= Left to right
Equality == != Left to right
Bitwise AND & Left to right
Bitwise XOR ^ Left to right
Bitwise OR | Left to right
Logical AND && Left to right
Logical OR || Left to right
Conditional ?: Right to left
Assignment = += -= *= /= %=
>>= <<= &= ^= |=
Right to left
Comma , Left to right

Associativity relates to precedence, and resolves any ambiguity over the grouping of operators with the same precedence. In the following statement, the rules of C specify that a * b is evaluated first:


y = a * b / c; 

In a more complicated example, associativity rules specify that b ? c : d is evaluated first in the following example:


a ? b ? c : d : e; 

The associativity of the conditional operator is right-to-left on the line. The assignment operator also associates right-to-left; for example:


int x = 0 , y = 5, z = 3; 
x = y = z;                  /*  x has the value 3, not 5    */ 

Other operators associate left-to-right; for example, the binary addition, subtraction, multiplication, and division operators all have left-to-right associativity.

Associativity applies to each row of operators in Table 6-2 and is right-to-left for some rows and left-to-right for others. The kind of associativity determines the order in which operators from the same row are evaluated in an unparenthesized expression. Consider the following expression:


A*B%C 

This expression is evaluated as follows because the multiplicative operators (*, /, %) are evaluated from left to right:


(A*B)%C 

Parentheses can always be used to control precedence and associativity within an expression.

6.3 Postfix Operators

Postfix expressions include array references, function calls, structure or union references, and postfix increment and decrement expressions. The operators in postfix expressions have left-to-right associativity.

Postfix expressions have the following syntax:

postfix-expression:

array-reference
function-call
structure-and-union-member-reference
postfix-increment-expression
postfix-decrement-expression

6.3.1 Array References

The bracket operator [ ] is used to refer to an element of an array. Array references have the following syntax:

array-reference:

postfix-expression [ expression ]

For example, in a one-dimensional array, you can refer to a specific element within the array as follows:


int sample_array[10];  /* Array declaration; array has 10 elements */ 
sample_array[0] = 180; /* Assign value to first array element      */ 

This example assigns a value of 180 to the first element of the array, sample_array[0] . Note that C uses zero-origin array subscripting.

In a two-dimensional array (more properly termed an array of arrays), you can refer to a specific element within the array, as follows:


int sample_array[10][5];  /* Array declaration; array has 50 elements */ 
sample_array[9][4] = 180; /* Assign value to last array element       */ 

This example assigns a value of 180 to the element sample_array[9][4] .

Conceptually, multidimensional arrays are of type arrays of arrays of arrays .... Therefore, if an array reference is not fully qualified, it refers to the address of the first element in the dimension that is not specified. For example:


int sample_array[10][5]; /* Array declaration                      */ 
int *p1;                 /* Pointer declaration                    */ 
 
p1 = sample_array[7];    /* Assigns address of subarray to pointer */ 

In this example, p1 contains the address of the first element in the one-dimensional subarray sample_array[7] . Although, as in this example, a partially qualified array can be used as an rvalue, only a fully qualified array reference can be used as an lvalue. For example, C does not allow the following statement, in which the second dimension of the array is omitted:


int sample_array[10][5]; /* Array declaration                      */ 
 
sample_array[7] = 21;    /* Error                                  */ 

A reference to an array name with no bracket can be used to pass the array's address to a function, as in the following statement:


funct(sample_array); 

Bracket operators can also be used to perform general pointer arithmetic as follows:


p1[intexp] 

Here, p1 is a pointer and intexp is an integer-valued expression. The result of the expression is the value pointed to by p1 incremented by the value of intexp multiplied by the size, in bytes, of the addressed object (array element). The expressions * (p1 + intexp) and p1[intexp] are defined to be equivalent; both expressions refer to the same memory location and have the same type. Array subscripting is a commutative operation: intexp[p1] is equivalent to p1[intexp] . A subscripted expression is always an lvalue.


Previous Next Contents Index
  

1.800.AT.COMPAQ

privacy and legal statement