`
universsky
  • 浏览: 92286 次
文章分类
社区版块
存档分类
最新评论

Constants & Operators

 
阅读更多

Constants

Constants are expressions with a fixed value.

Literals

Literals are the most obvious kind of constants. They are used to express particular values within the source code of a program. We have already used these previously to give concrete values to variables or to express messages we wanted our programs to print out, for example, when we wrote:

a = 5;


the 5 in this piece of code was a literal constant.

Literal constants can be divided in Integer Numerals, Floating-Point Numerals, Characters, Strings and Boolean Values.

Integer Numerals


1
2
3
1776
707
-273


They are numerical constants that identify integer decimal values. Notice that to express a numerical constant we do not have to write quotes (") nor any special character. There is no doubt that it is a constant: whenever we write 1776 in a program, we will be referring to the value 1776.

In addition to decimal numbers (those that all of us are used to using every day), C++ allows the use of octal numbers (base 8) and hexadecimal numbers (base 16) as literal constants. If we want to express an octal number we have to precede it with a 0 (a zero character). And in order to express a hexadecimal number we have to precede it with the characters 0x (zero, x). For example, the following literal constants are all equivalent to each other:

1
2
3
75         // decimal
0113       // octal
0x4b       // hexadecimal 


All of these represent the same number: 75 (seventy-five) expressed as a base-10 numeral, octal numeral and hexadecimal numeral, respectively.

Literal constants, like variables, are considered to have a specific data type. By default, integer literals are of type int. However, we can force them to either be unsigned by appending the u character to it, or long by appending l:

1
2
3
4
75         // int
75u        // unsigned int
75l        // long
75ul       // unsigned long 


In both cases, the suffix can be specified using either upper or lowercase letters.

Floating Point Numbers

They express numbers with decimals and/or exponents. They can include either a decimal point, an e character (that expresses "by ten at the Xth height", where X is an integer value that follows the e character), or both a decimal point and an e character:

1
2
3
4
3.14159    // 3.14159
6.02e23    // 6.02 x 10^23
1.6e-19    // 1.6 x 10^-19
3.0        // 3.0 


These are four valid numbers with decimals expressed in C++. The first number is PI, the second one is the number of Avogadro, the third is the electric charge of an electron (an extremely small number) -all of them approximated- and the last one is the number three expressed as a floating-point numeric literal.

The default type for floating point literals is double. If you explicitly want to express a float or a long double numerical literal, you can use the f or l suffixes respectively:

1
2
3.14159L   // long double
6.02e23f   // float 


Any of the letters that can be part of a floating-point numerical constant (e, f, l) can be written using either lower or uppercase letters without any difference in their meanings.

Character and string literals

There also exist non-numerical constants, like:

1
2
3
4
'z'
'p'
"Hello world"
"How do you do?" 


The first two expressions represent single character constants, and the following two represent string literals composed of several characters. Notice that to represent a single character we enclose it between single quotes (') and to express a string (which generally consists of more than one character) we enclose it between double quotes (").

When writing both single character and string literals, it is necessary to put the quotation marks surrounding them to distinguish them from possible variable identifiers or reserved keywords. Notice the difference between these two expressions:

1
2
x
'x'


x alone would refer to a variable whose identifier is x, whereas 'x' (enclosed within single quotation marks) would refer to the character constant 'x'.

Character and string literals have certain peculiarities, like the escape codes. These are special characters that are difficult or impossible to express otherwise in the source code of a program, like newline (\n) or tab (\t). All of them are preceded by a backslash (\). Here you have a list of some of such escape codes:

\n newline
\r carriage return
\t tab
\v vertical tab
\b backspace
\f form feed (page feed)
\a alert (beep)
\' single quote (')
\" double quote (")
\? question mark (?)
\\ backslash (\)

For example:

1
2
3
4
'\n'
'\t'
"Left \t Right"
"one\ntwo\nthree" 


Additionally, you can express any character by its numerical ASCII code by writing a backslash character (\) followed by the ASCII code expressed as an octal (base-8) or hexadecimal (base-16) number. In the first case (octal) the digits must immediately follow the backslash (for example \23 or \40), in the second case (hexadecimal), an x character must be written before the digits themselves (for example \x20 or \x4A).

String literals can extend to more than a single line of code by putting a backslash sign (\) at the end of each unfinished line.

1
2
"string expressed in \
two lines" 


You can also concatenate several string constants separating them by one or several blank spaces, tabulators, newline or any other valid blank character:

"this forms" "a single" "string" "of characters"


Finally, if we want the string literal to be explicitly made of wide characters (wchar_t type), instead of narrow characters (char type), we can precede the constant with the L prefix:

L"This is a wide character string"


Wide characters are used mainly to represent non-English or exotic character sets.

Boolean literals

There are only two valid Boolean values: true and false. These can be expressed in C++ as values of type bool by using the Boolean literals true and false.

Defined constants (#define)

You can define your own names for constants that you use very often without having to resort to memory-consuming variables, simply by using the #define preprocessor directive. Its format is:

#define identifier value
For example:

1
2
#define PI 3.14159
#define NEWLINE '\n' 


This defines two new constants: PI and NEWLINE. Once they are defined, you can use them in the rest of the code as if they were any other regular constant, for example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// defined constants: calculate circumference

#include <iostream>
using namespace std;

#define PI 3.14159
#define NEWLINE '\n'

int main ()
{
  double r=5.0;               // radius
  double circle;

  circle = 2 * PI * r;
  cout << circle;
  cout << NEWLINE;

  return 0;
}
31.4159


In fact the only thing that the compiler preprocessor does when it encounters #define directives is to literally replace any occurrence of their identifier (in the previous example, these were PI and NEWLINE) by the code to which they have been defined (3.14159 and '\n' respectively).

The #define directive is not a C++ statement but a directive for the preprocessor; therefore it assumes the entire line as the directive and does not require a semicolon (;) at its end. If you append a semicolon character (;) at the end, it will also be appended in all occurrences of the identifier within the body of the program that the preprocessor replaces.

Declared constants (const)

With the const prefix you can declare constants with a specific type in the same way as you would do with a variable:

1
2
const int pathwidth = 100;
const char tabulator = '\t';


Here, pathwidth and tabulator are two typed constants. They are treated just like regular variables except that their values cannot be modified after their definition.

Operators

Once we know of the existence of variables and constants, we can begin to operate with them. For that purpose, C++ integrates operators. Unlike other languages whose operators are mainly keywords, operators in C++ are mostly made of signs that are not part of the alphabet but are available in all keyboards. This makes C++ code shorter and more international, since it relies less on English words, but requires a little of learning effort in the beginning.

You do not have to memorize all the content of this page. Most details are only provided to serve as a later reference in case you need it.

Assignment (=)

The assignment operator assigns a value to a variable.

a = 5;


This statement assigns the integer value 5 to the variable a. The part at the left of the assignment operator (=) is known as the lvalue (left value) and the right one as the rvalue (right value). The lvalue has to be a variable whereas the rvalue can be either a constant, a variable, the result of an operation or any combination of these.
The most important rule when assigning is the right-to-left rule: The assignment operation always takes place from right to left, and never the other way:

a = b;


This statement assigns to variable a (the lvalue) the value contained in variable b (the rvalue). The value that was stored until this moment in a is not considered at all in this operation, and in fact that value is lost.

Consider also that we are only assigning the value of b to a at the moment of the assignment operation. Therefore a later change of b will not affect the new value of a.

For example, let us have a look at the following code - I have included the evolution of the content stored in the variables as comments:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// assignment operator

#include <iostream>
using namespace std;

int main ()
{
  int a, b;         // a:?,  b:?
  a = 10;           // a:10, b:?
  b = 4;            // a:10, b:4
  a = b;            // a:4,  b:4
  b = 7;            // a:4,  b:7

  cout << "a:";
  cout << a;
  cout << " b:";
  cout << b;

  return 0;
}
a:4 b:7


This code will give us as result that the value contained in a is 4 and the one contained in b is 7. Notice how a was not affected by the final modification of b, even though we declared a = b earlier (that is because of the right-to-left rule).

A property that C++ has over other programming languages is that the assignment operation can be used as the rvalue (or part of an rvalue) for another assignment operation. For example:

a = 2 + (b = 5);


is equivalent to:

1
2
b = 5;
a = 2 + b;


that means: first assign 5 to variable b and then assign to a the value 2 plus the result of the previous assignment of b (i.e. 5), leaving a with a final value of 7.

The following expression is also valid in C++:

a = b = c = 5;


It assigns 5 to the all three variables: a, b and c.

Arithmetic operators ( +, -, *, /, % )

The five arithmetical operations supported by the C++ language are:

+ addition
- subtraction
* multiplication
/ division
% modulo

Operations of addition, subtraction, multiplication and division literally correspond with their respective mathematical operators. The only one that you might not be so used to see is modulo; whose operator is the percentage sign (%). Modulo is the operation that gives the remainder of a division of two values. For example, if we write:

a = 11 % 3;


the variable a will contain the value 2, since 2 is the remainder from dividing 11 between 3.

Compound assignment (+=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=)


When we want to modify the value of a variable by performing an operation on the value currently stored in that variable we can use compound assignment operators:

expression is equivalent to
value += increase; value = value + increase;
a -= 5; a = a - 5;
a /= b; a = a / b;
price *= units + 1; price = price * (units + 1);

and the same for all other operators. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
// compound assignment operators

#include <iostream>
using namespace std;

int main ()
{
  int a, b=3;
  a = b;
  a+=2;             // equivalent to a=a+2
  cout << a;
  return 0;
}
5


Increase and decrease (++, --)

Shortening even more some expressions, the increase operator (++) and the decrease operator (--) increase or reduce by one the value stored in a variable. They are equivalent to +=1 and to -=1, respectively. Thus:

1
2
3
c++;
c+=1;
c=c+1;


are all equivalent in its functionality: the three of them increase by one the value of c.

In the early C compilers, the three previous expressions probably produced different executable code depending on which one was used. Nowadays, this type of code optimization is generally done automatically by the compiler, thus the three expressions should produce exactly the same executable code.

A characteristic of this operator is that it can be used both as a prefix and as a suffix. That means that it can be written either before the variable identifier (++a) or after it (a++). Although in simple expressions like a++ or ++a both have exactly the same meaning, in other expressions in which the result of the increase or decrease operation is evaluated as a value in an outer expression they may have an important difference in their meaning: In the case that the increase operator is used as a prefix (++a) the value is increased before the result of the expression is evaluated and therefore the increased value is considered in the outer expression; in case that it is used as a suffix (a++) the value stored in a is increased after being evaluated and therefore the value stored before the increase operation is evaluated in the outer expression. Notice the difference:

Example 1 Example 2
B=3;
A=++B;
// A contains 4, B contains 4
B=3;
A=B++;
// A contains 3, B contains 4

In Example 1, B is increased before its value is copied to A. While in Example 2, the value of B is copied to A and then B is increased.

Relational and equality operators ( ==, !=, >, <, >=, <= )


In order to evaluate a comparison between two expressions we can use the relational and equality operators. The result of a relational operation is a Boolean value that can only be true or false, according to its Boolean result.

We may want to compare two expressions, for example, to know if they are equal or if one is greater than the other is. Here is a list of the relational and equality operators that can be used in C++:

== Equal to
!= Not equal to
> Greater than
< Less than
>= Greater than or equal to
<= Less than or equal to

Here there are some examples:

1
2
3
4
5
(7 == 5)     // evaluates to false.
(5 > 4)      // evaluates to true.
(3 != 2)     // evaluates to true.
(6 >= 6)     // evaluates to true.
(5 < 5)      // evaluates to false. 


Of course, instead of using only numeric constants, we can use any valid expression, including variables. Suppose that a=2, b=3 and c=6,

1
2
3
4
(a == 5)     // evaluates to false since a is not equal to 5.
(a*b >= c)   // evaluates to true since (2*3 >= 6) is true. 
(b+4 > a*c)  // evaluates to false since (3+4 > 2*6) is false. 
((b=2) == a) // evaluates to true.  


Be careful! The operator = (one equal sign) is not the same as the operator == (two equal signs), the first one is an assignment operator (assigns the value at its right to the variable at its left) and the other one (==) is the equality operator that compares whether both expressions in the two sides of it are equal to each other. Thus, in the last expression ((b=2) == a), we first assigned the value 2 to b and then we compared it to a, that also stores the value 2, so the result of the operation is true.

Logical operators ( !, &&, || )


The Operator ! is the C++ operator to perform the Boolean operation NOT, it has only one operand, located at its right, and the only thing that it does is to inverse the value of it, producing false if its operand is true and true if its operand is false. Basically, it returns the opposite Boolean value of evaluating its operand. For example:

1
2
3
4
!(5 == 5)    // evaluates to false because the expression at its right (5 == 5) is true. 
!(6 <= 4)    // evaluates to true because (6 <= 4) would be false. 
!true        // evaluates to false
!false       // evaluates to true.  


The logical operators && and || are used when evaluating two expressions to obtain a single relational result. The operator && corresponds with Boolean logical operation AND. This operation results true if both its two operands are true, and false otherwise. The following panel shows the result of operator && evaluating the expression a && b:

&& OPERATOR a b a && b
true true true
true false false
false true false
false false false

The operator || corresponds with Boolean logical operation OR. This operation results true if either one of its two operands is true, thus being false only when both operands are false themselves. Here are the possible results of a || b:

|| OPERATOR a b a || b
true true true
true false true
false true true
false false false

For example:

1
2
( (5 == 5) && (3 > 6) )  // evaluates to false ( true && false ).
( (5 == 5) || (3 > 6) )  // evaluates to true ( true || false ). 


When using the logical operators, C++ only evaluates what is necessary from left to right to come up with the combined relational result, ignoring the rest. Therefore, in this last example ((5==5)||(3>6)), C++ would evaluate first whether 5==5 is true, and if so, it would never check whether 3>6 is true or not. This is known as short-circuit evaluation, and works like this for these operators:

operator short-circuit
&& if the left-hand side expression is false, the combined result is false (right-hand side expression not evaluated).
|| if the left-hand side expression is true, the combined result is true (right-hand side expression not evaluated).

This is mostly important when the right-hand expression has side effects, such as altering values:

if ((i<10)&&(++i<n)) { /*...*/ }


This combined conditional expression increases i by one, but only if the condition on the left of && is true, since otherwise the right-hand expression (++i<n) is never evaluated.

Conditional operator ( ? )


The conditional operator evaluates an expression returning a value if that expression is true and a different one if the expression is evaluated as false. Its format is:

condition ? result1 : result2

If condition is true the expression will return result1, if it is not it will return result2.

1
2
3
4
7==5 ? 4 : 3     // returns 3, since 7 is not equal to 5.
7==5+2 ? 4 : 3   // returns 4, since 7 is equal to 5+2.
5>3 ? a : b      // returns the value of a, since 5 is greater than 3.
a>b ? a : b      // returns whichever is greater, a or b. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// conditional operator

#include <iostream>
using namespace std;

int main ()
{
  int a,b,c;

  a=2;
  b=7;
  c = (a>b) ? a : b;

  cout << c;

  return 0;
}
7


In this example a was 2 and b was 7, so the expression being evaluated (a>b) was not true, thus the first value specified after the question mark was discarded in favor of the second value (the one after the colon) which was b, with a value of 7.

Comma operator ( , )

The comma operator (,) is used to separate two or more expressions that are included where only one expression is expected. When the set of expressions has to be evaluated for a value, only the rightmost expression is considered.

For example, the following code:

a = (b=3, b+2);


Would first assign the value 3 to b, and then assign b+2 to variable a. So, at the end, variable a would contain the value 5 while variable b would contain value 3.

Bitwise Operators ( &, |, ^, ~, <<, >> )


Bitwise operators modify variables considering the bit patterns that represent the values they store.

operator asm equivalent description
& AND Bitwise AND
| OR Bitwise Inclusive OR
^ XOR Bitwise Exclusive OR
~ NOT Unary complement (bit inversion)
<< SHL Shift Left
>> SHR Shift Right

Explicit type casting operator

Type casting operators allow you to convert a datum of a given type to another. There are several ways to do this in C++. The simplest one, which has been inherited from the C language, is to precede the expression to be converted by the new type enclosed between parentheses (()):

1
2
3
int i;
float f = 3.14;
i = (int) f;


The previous code converts the float number 3.14 to an integer value (3), the remainder is lost. Here, the typecasting operator was (int). Another way to do the same thing in C++ is using the functional notation: preceding the expression to be converted by the type and enclosing the expression between parentheses:

i = int ( f );


Both ways of type casting are valid in C++.

sizeof()

This operator accepts one parameter, which can be either a type or a variable itself and returns the size in bytes of that type or object:

a = sizeof (char);


This will assign the value 1 to a because char is a one-byte long type.
The value returned by sizeof is a constant, so it is always determined before program execution.

Other operators

Later in these tutorials, we will see a few more operators, like the ones referring to pointers or the specifics for object-oriented programming. Each one is treated in its respective section.

Precedence of operators

When writing complex expressions with several operands, we may have some doubts about which operand is evaluated first and which later. For example, in this expression:

a = 5 + 7 % 2


we may doubt if it really means:

1
2
a = 5 + (7 % 2)    // with a result of 6, or
a = (5 + 7) % 2    // with a result of 0 


The correct answer is the first of the two expressions, with a result of 6. There is an established order with the priority of each operator, and not only the arithmetic ones (those whose preference come from mathematics) but for all the operators which can appear in C++. From greatest to lowest priority, the priority order is as follows:

Level Operator Description Grouping
1 :: scope Left-to-right
2 () [] . -> ++ -- dynamic_cast static_cast reinterpret_cast const_cast typeid postfix Left-to-right
3 ++ -- ~ ! sizeof new delete unary (prefix) Right-to-left
* & indirection and reference (pointers)
+ - unary sign operator
4 (type) type casting Right-to-left
5 .* ->* pointer-to-member Left-to-right
6 * / % multiplicative Left-to-right
7 + - additive Left-to-right
8 << >> shift Left-to-right
9 < > <= >= relational Left-to-right
10 == != equality Left-to-right
11 & bitwise AND Left-to-right
12 ^ bitwise XOR Left-to-right
13 | bitwise OR Left-to-right
14 && logical AND Left-to-right
15 || logical OR Left-to-right
16 ?: conditional Right-to-left
17 = *= /= %= += -= >>= <<= &= ^= |= assignment Right-to-left
18 , comma Left-to-right

Grouping defines the precedence order in which operators are evaluated in the case that there are several operators of the same level in an expression.

All these precedence levels for operators can be manipulated or become more legible by removing possible ambiguities using parentheses signs ( and ), as in this example:

a = 5 + 7 % 2;


might be written either as:

a = 5 + (7 % 2);

or
a = (5 + 7) % 2;


depending on the operation that we want to perform.

So if you want to write complicated expressions and you are not completely sure of the precedence levels, always include parentheses. It will also make your code easier to read.
分享到:
评论

相关推荐

    Python 2.6 Quick Reference (Letter) (2009).pdf

    Lexical entities : keywords, identifiers, string literals, boolean constants, numbers, sequences, dictionaries, operators ?Basic types and their operations: None, bool, Numeric types, sequence types...

    Embedded C Programming and the ATMEL AVR Book & CD

    Here, they'll experiment with variables and constants, operators and expressions, control statements, pointers and arrays, memory types, preprocessor directives, real-time methods, and more!...

    Swift.Pocket.Reference.Programming.for.iOS.and.OS.X.2nd.Edition.149194

    Variables and Constants Tuples Operators Strings and Characters Arrays Dictionaries Sets Functions Closures Optionals Program Flow Classes Structures Enumerations Access Control Extensions Checking ...

    C程序设计语言第2版

    Chapter 2: Types, Operators and Expressions Variable Names Data Types and Sizes Constants Declarations Arithmetic Operators Relational and Logical Operators Type Conversions Increment and ...

    The_C_Programming_Language-英文版

    1.4 Symbolic Constants 17 1.5 Character Input and Output 17 1.5.1 File Copying 18 1.5.2 Character Counting 19 1.5.3 Line Counting 20 1.5.4 Word Counting 21 1.6 Arrays 23 1.7 Functions 25 1.8 Arguments...

    西电软工oop上机题目4 10.11.rar

    Define a class for analyzing, storing, evaluating, and printing simple arithmetic expressions consisting of integer constants and the operators +, -, *, and /. The public interface should look like ...

    超清晰PDF C++

    Naming Constants 17 Arithmetic Operators and Expressions 19 Integer and Floating-Point Division 21 Pitfall: Division with Whole Numbers 22 Type Casting 23 Increment and Decrement Operators 25 Pitfall:...

    C++ Basic

    Naming Constants 17 Arithmetic Operators and Expressions 19 Integer and Floating-Point Division 21 Pitfall: Division with Whole Numbers 22 Type Casting 23 Increment and Decrement Operators 25 Pitfall:...

    The C programming Language(chm格式完整版)

    Chapter 2: Types, Operators and Expressions Variable Names Data Types and Sizes Constants Declarations Arithmetic Operators Relational and Logical Operators Type Conversions Increment and ...

    mt4编程手册(PDF)

    操作符 [Operators] 8 函数 [Function] 13 变量 [Variables] 14 预处理程序 [Preprocessor] 17 账户信息 [Account Information] 19 数组函数 [Array Functions] 20 类型转换函数 [Conversion Functions] 27 公用函数...

    VB.net与C#的语法区别(非常全面)

    VB.net与C#的语法区别Program Structure、Comments、Data Types、Constants、Enumerations、Operators、Choices、Loops、Arrays、Functions、Strings、Exception Handling、Namespaces、Classes / Interfaces等

    javat编程基础

    java编程基础,Java primitive data types and related subjects, such as variables, constants, data types, operators, and expressions. Control statements Array String

    C# 语言规格说明(English Edition第五版)

    7.12.2 User-defined conditional logical operators 206 7.13 The null coalescing operator 206 7.14 Conditional operator 207 7.15 Anonymous function expressions 208 7.15.1 Anonymous function signatures ...

    ISO_IEC_11172-2 MPEG1标准

    2.2.7 Constants 18 2.3 Method of Describing Bit Stream Syntax 18 2.4 Requirements 20 2.4.1 Coding Structure and Parameters 20 2.4.2 System Target Decoder 20 2.4.3 Specification of the System Stream ...

    ISO_IEC_11172-1 System 标准

    2.2.7 Constants 18 2.3 Method of Describing Bit Stream Syntax 18 2.4 Requirements 20 2.4.1 Coding Structure and Parameters 20 2.4.2 System Target Decoder 20 2.4.3 Specification of the System Stream ...

    C++超详细的基础教程

    Constants 4.操作符/运算符 Operators 5.控制台交互 Communication through console 3.控制结构和函数 Control structures and Functions 1.控制结构 Control Structures 2.函数I Functions I 3.函数II ...

    Learning.Swift.2.Programming.2nd.Edition.01344315

    Collect data with arrays and dictionaries, and store it with variables and constants Group commonly-used code into functions for easy reuse Structure your code with enums, structs, and classes Use ...

    C.Quick.Syntax.Reference

    What are Custom Conversions, Namespaces, Constants, and the Preprocessor How to do Event Handling What are Type Conversions, Templates, Headers, and more Who this book is for This book is a quick, ...

    ARM® Compiler v5.06 for µVision® armasm User Guide

    4.20 Optional hash with immediate constants 4.21 Use of macros 4.22 Test-and-branch macro example 4.23 Unsigned integer division macro example 4.24 Instruction and directive relocations 4.25 Frame ...

Global site tag (gtag.js) - Google Analytics