Example: #include #include "project.h" #if VERSION == 1 #define MYPROJ_H "version1.h" #else #define MYPROJ_H "version2.h" #endif #include MYPROJ_H The #if, #elif, #else, and #endif Direc
Trang 1Example: #include <iostream>
#include "project.h"
#if VERSION == 1
#define MYPROJ_H "version1.h"
#else
#define MYPROJ_H "version2.h"
#endif
#include MYPROJ_H
The #if, #elif, #else, and #endif Directives
You can use the #if,#elif, and #endifdirectives to compile certain parts of a source
file and ignore others The directives are known as conditional compilation directives for
this reason
Syntax: #if expression1
[text1]
[#elif expression2
text2]
[#elif expression(n)
text(n)]
[#else
text(n+1)]
#endif
Each#ifdirective must be terminated by an #endifdirective Multiple #elif direc-tives can occur in between The #elsedirective can occur once only
The preprocessor evaluates expression1, expression2, in sequence If
an expression that yields “true” is found, that is its value is not 0, the corresponding code for this expression is processed
If none of these expressions is true, the #elsedirective is executed If this directive is omitted, no corresponding code is processed
expression1, expression1, must be constant expressions of integral types and cannot contain the cast operator Some compilers do not allow the use of the sizeofoperator
The corresponding text is a source text, that is, it comprises preprocessor directives, C++ statements, or whole C++ programs
When a corresponding text is processed, the preprocessor may first execute directives before passing the expanded source code to the compiler for compilation Code that the preprocessor has not processed is removed from the source
Trang 2The defined Operator
You can use the defined operator to check whether a symbolic constant or macro has been defined
Syntax: defined(name) The operator returns a value other than 0 if valid definition for name exists, and the value0in all other cases
A definition created using the #definedirective remains valid until it is removed by
an#undefdirective If the substitute text following name in the #definedirective is missing, the definition is still valid
Thedefinedoperator is normally used in #ifor#elifdirectives, for example
Example: #if defined VERSION
Using the definedoperator allows you to use its return value in a preprocessor expres-sion
The #ifdef and #ifndef Directives
You can also perform the same check using the #ifdefand#ifndefdirectives
Syntax: #ifdef name
#ifndef name The #ifdefdirective returns a value other than 0 ifname is defined and otherwise 0
In contrast, the #ifndefdirective ensures that a value has not yet been defined, that
is, that name is undefined, returning 0ifnamehas been defined, and a non-zero value
in any other case
Example: #if defined(STATE) && defined(COND)
The #line Directive
The compiler uses line numbers and the name of a source file to display errors discovered
on compilation You can use the #linedirective to change the line numbers and the file name
Syntax: #line new_number ["filename"]
At this position a new line count begins by new_number If filenameis stated, it will become the new file name that the compiler refers to when issuing error messages The new file name must be in quotes and new_numbermust be an integral constant
Example: #line 170 "genprog1.cpp"
The line number and the file name can also be stated as symbolic constants
790 A P P E N D I X
Trang 3Example: #if VERSION == 1
#define NEWNUMBER 20
#else
#define NEWNUMBER 25
#line NEWNUMBER
The #linedirective is often used by program generators compiling code to produce a C++ program In the case of error messages, the message can refer to the appropriate line and file name in the original code
The current line number and file name can be accessed using the standard macros LINE and FILE
Example: cout << "Current line number: "
<< LINE << endl
<< "File name: " << FILE << endl;
The #error Directive
The#errordirective can be used to show preprocessor errors
Syntax: #error errortext;
The message errortextis issued and compilation is terminated
#if VERSION < 3
#error VERSION too old.\n
##error Version 3 or better needed
#endif
#include "version.h"
If the symbolic constant VERSIONis defined and the value is less than 3, the following error message is output:
VERSION too old
Version 3 or better needed
The #pragma Directive
The #pragma directive is compiler dependent and allows you to define your own
pre-processor commands for a specific compiler
Syntax: #pragma command
Any other compiler that supports the #pragmadirective but does not support the com-mand following #pragmasimply ignores the command
Example: #pragma pack(1)
This directive causes a Microsoft compiler to align the components of a class bytewise, avoiding gaps Other options are pack(2)andpack(4)
Trang 4■ PRE-DEFINED STANDARD MACROS
The ANSI standard provides for six pre-defined standard macros Their names begin and end with two underscores:
LINE Returns the number of the line containing the LINE macro The
first line in a source code is line 1 The numbering can be modified using the #linedirective
FILE Returns the name of the source file that contains the FILE
macro The name can be modified using the #linedirective
DATE Returns the date in the mmm dd yyyyformat, where mmmis an
abbreviation for the month, ddis the day of the month, and yyyyis the year, resulting in Jul 17 2001, for example
DATE refers to the point in time when the preprocessor started processing the source Thus, the macro returns the same result at any position in the source code
TIME Returns the time as a string in the format hh:mm:ss, where hhrefers
to hours, mmto minutes, and ssto seconds, e.g., 15:23:47 TIME refers to the point in time when the preprocessor started processing the source Thus, the macro returns the same result at any position in the source code
STDC Is only defined if the source code contains ANSI keywords only cplusplus Is defined if the source code is compiled using a C++ compiler
792 A P P E N D I X
Trang 5■ BINDING C FUNCTIONS
Calling C Functions in C++ Programs
C functions from C libraries can be called in a C++ program However, function calls are interpreted differently by the C++ compiler than you would expect from a C compiler You must therefore supply additional binding information that is accessible via an extern "C" declaration
Example: extern "C" void oldfunc(int size);
This informs the C++ compiler that a C compiler was used to compile the oldfunc() function
If you need to declare multiple C functions, you can declare their prototypes after extern "C" within curved brackets If you have already declared the functions in a header file, you can include the header file in an extern "C"block
Example: extern "C"
{
#include "graphic.h"
}
It is common practise to declare extern "C" code in C header files You can then include the C header both in C and in C++ programs
Example: #if defined _cplusplus
extern "C"
{
#endif
// Prototypes for C functions here
#if defined cplusplus
}
#endif
The symbolic constant cplusplus is evaluated to discover whether the current compiler is a C or C++ compiler If cplusplusis defined, that is, a C++ compiler is active, the extern "C"block is inserted
Defining C Functions in C++ Programs
It is also possible to define your own C functions for a C++ program You need to do this
if you call a function that expects a C function as an argument, such as the standard qsort()andbsearch()functions
The definition for a C function in a C++ program must be encased in an extern
"C"block This instructs the compiler to compile the function as a C function
Trang 6Example: #include <string>
#include <iostream>
#include <cstdlib>
using namespace std;
static char* city[] = { "Paris", "London",
"Barcelona", "Hollywood"} static char* key = "New York";
extern "C" int scmp(const void*, const void*);
int main() { // Sort cities:
qsort( city, 4, sizeof(char*), scmp);
// Find city:
if( bsearch( &key, city, 4,
sizeof(char*),scmp) == NULL) cout << "City" << (string) key
<< "not found.\n";
}
extern "C"
{
int scmp(const void *s1, const void *s2) {
return strcmp( *(const char**)s1,
*(const char**)s2 );
}
}
The C function scmp() is passed to the standard functions bsearch() for binary searching and qsort()for sorting using the quick sort algorithm
794 A P P E N D I X
Trang 7■ OPERATORS OVERVIEW
Arithmetical Operators:
Relational Operators:
Logical Operators:
Assignment Operators:
Bit-wise operators:
addition, subtraction multiplication division, modulus division unary plus, minus operator increment, decrement operator
+
*
/
+
++
-%
-
“equal”, “unequal”
“less”, “less or equal”
“greater”, “greater or equal”
==
<
>
!=
<=
>=
AND, OR NOT
&&
!
||
AND, NOT
OR, exclusive-OR left shift, right shift
&
|
<<
~
^
>>
simple assignment compound assignment ( op is a binary arithmetical or binary bit-wise operator)
=
op=
Trang 8■ OPERATORS OVERVIEW (CONTINUED)
Access Operators:
Cast Operators:
Operators for Storage Allocation
Other Operators:
scope resolution operator subscript operator indirection operator class member access operators pointer to member operators
::
[]
* *
->
->*
C cast operator dynamic cast operator static cast operator const cast operator reinterpret cast operator
conditional expression and comma operator
address-of operator call to function name create a temporary object of type type
sizeof operator (size of type) typeid operator (type informations)
To allocate storage dynamically for
an object, an array resp.
To free dynamically allocated storage for an object, an array resp.
(type) dynamic_cast<>
static_cast<>
const_cast<>
reinterpret_cast<>
new
delete
new []
delete []
?:
&
name() type() sizeof() typeid() ,
796 A P P E N D I X
Trang 9■ OPERATOR PRECEDENCE TABLE
Operator
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
from left to right
from left to right
from left to right
from left to right from left to right from left to right from left to right from left to right from left to right from left to right from left to right from left to right from left to right from left to right from right to left from right to left
from right to left
::
!
.*
*
>>
<
==
^
|
||
!=
<<
->*
~
++("postfix")
+ ("unary")
+ ("binary") - ("binary")
&&
?:
=
%=
&=
,
- ( "unary") ++ ("prefix") - ( "prefix")
– –("postfix")
dynamic_cast<>
reinterpret_cast<>
new new[] delete delete[]
(type) sizeof()
Trang 10■ ASCII CODE TABLE
decimal octal hex character decimal octal hex character
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
(BLANK)
!
"
#
$
%
& ' ( )
* + , - / 0 1 2 3 4 5 6 7 8 9 :
;
<
=
>
?
040 041 042 043 044 045 046 047 050 051 052 053 054 055 056 057 060 061 062 063 064 065 066 067 070 071 072 073 074 075 076 077
000 001 002 003 004 005 006 007 010 011 012 013 014 015 016 017 020 021 022 023 024 025 026 027 030 031 032 033 034 035 036 037
00 01 02 03 04 05 06 07 08 09 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
(NUL) (SOH) (STX) (ETX) (EOT) (ENQ) (ACK) (BEL) (BS) (HT) (LF) (VT) (FF) (CR) (SO) (SI) (DLE) (DC1) (DC2) (DC3) (DC4) (DC5) (SYN) (ETB) (CAN) (EM) (SUB) (ESC) (FS) (GS) (RS) (US)
798 A P P E N D I X