Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Pro Visual C++-CLI And The .NET 2.0 Platform (2006) [eng]-1

.pdf
Скачиваний:
70
Добавлен:
16.08.2013
Размер:
24.18 Mб
Скачать

58

C H A P T E R 2 C + + / C L I B A S I C S

Character Literals

C++/CLI provides two different types of character literals:

Character

Escape sequence

Character literals are the most basic form and are simply a printable letter, number, or symbol enclosed in single quotes. These literals can be placed in either char (8-bit) types (or any other integer type, for that matter) and Char (16-bit) types. Here are a few examples:

‘A’

‘0’

‘+’

Escape sequences are a little more elaborate and come in a few flavors. Like the character literal form, escape sequences are placed within single quotes. The first character within the quotes is always a backslash [\]. After the backslash will be a character such as the ones shown in Table 2-9, an octal number, or an x followed by a hexadecimal number. The octal or hexadecimal numbers are the numeric equivalent of the character you want the literal to represent.

Table 2-9. Special Escape Sequences

Escape Sequence

Character

\?

Question mark

\'

Single quote

\"

Double quote

\\

Backslash

\0

Null

\a

Bell or alert

\b

Backspace

\f

Form feed

\n

New line

\r

Carriage return

\t

Tab

\v

Vertical tab

 

 

All the character literal types can be prefixed with the letter L to tell the compiler to create a Unicode equivalent of the character literal. Remember that Unicode characters are 16 bits, so they will not fit in the char type; instead, they should be placed in Char types.

Listing 2-12 is a program showing character literals in action.

C H A P T E R 2 C + + / C L I B A S I C S

59

Listing 2-12. Character Literals in Action using namespace System;

// Character

Literals in

Action

 

void main()

 

 

 

{

 

 

 

char a =

'a';

// character 'a'

 

Char b =

L'b';

// Unicode 'b'

 

char t =

'\t';

// tab escape

 

Char s =

L'\\';

// Unicode backslash escape

char d =

'\45';

// octal escape

 

Char e =

L'\x0045';

// Unicode hexadecimal escape

Console::WriteLine (

a ); // displays

numeric equiv of 'A'

Console::WriteLine (

b ); // displays

the letter 'b'

Console::WriteLine (

t ); // displays

numeric equiv of tab

Console::WriteLine (

s ); // displays

backslash

Console::WriteLine (

d ); // displays

decimal equiv of octal 45

Console::WriteLine (

e ); // displays

the letter 'e'

}

 

 

 

Figure 2-13 shows the results of this little program.

Figure 2-13. Results of CharLiteral.exe

String Literals

Managed string literals are simply character strings enclosed in double quotes. You can also create literal strings prefixed with the letter L, creating a Unicode string literal.

By the way, the escape sequences shown previously also work within Strings. You must be careful to avoid too many characters after the backslash being taken as the escape sequence. Realistic examples of this are difficult with the Latin alphabet, but this illustrates the point:

String ^s1 = "\x61"; // a

String ^s2 = "\x611"; // is NOT a1 but a Unicode hexadecimal escape of 611

60

C H A P T E R 2 C + + / C L I B A S I C S

Listing 2-13 is a program showing string literals in action.

Listing 2-13. String Literals in Action

using namespace System;

// String Literals in Action void main()

{

String^ a = "Managed String"; String^ b = L"Unicode String";

Console::WriteLine(a);

Console::WriteLine(b);

}

Figure 2-14 shows the results of this little program.

Figure 2-14. Results of StringLiteral.exe

Comments

Documenting programs is a very important practice all software developers should do, no matter what programming language they use. Unfortunately, documentation is often the first thing to suffer when a project is crunched for time.

If you are the only developer for a program, you might think that because you wrote the program, you should have no problem remembering how the program works. From experience, leaving a piece of code and coming back to it six months or more later is nearly equivalent to reading someone else’s code, unless, of course, it is documented.

C++/CLI, like traditional C++, provides two comment styles: the single-line comment and the multiline comment. There is also a third comment style that allows for the autogeneration of documentation. I’ll cover this style in Chapter 6.

The single-line comment begins with a double slash (//). Anything after the double slash is a comment. Depending on where you place the double slash, you can use a single-line comment for an entire line or just part of a line. By the way, you probably noticed the comments in the previous example code, but here are a couple more examples:

// This entire line is a comment.

int x = 0; // This comment uses part of the line.

The multiline comment starts with /* and ends with */. You can place multiline comments anywhere in the code, even on different lines. You must use care with this kind of comment, because embedding a multiline comment within a multiline comment will cause errors. Here are some multiline comments:

C H A P T E R 2 C + + / C L I B A S I C S

61

/*****************************************************

* Common comment box. You will see these frequently * * within programs. *

*****************************************************/

Int32 x = 0; /* This is a comment on a single line */ Int32 y = 0; /* This is a comment that stretched for More than one line */

/* Embedded comments like this /* do not work as you might expect */ this portion would

not be commented and will in this case cause errors */

Because of the embedded comment problem, many programmers, myself included, prefer to use the double slash comment.

Operators

C++/CLI and traditional C++ are identical, except for one new operator introduced in C++/CLI, the unary % (or reference operator). If you have programmed in C++, then you should find very little new information in this section, but it might serve as a bit of a refresher. For anyone inexperienced in C++, this section is essential because it shows all the basic operations available to a C++/CLI programmer.

Arithmetic Operators

Arithmetic operators are used to perform arithmetic operations on integer, floating-point, and decimal data types. Seven arithmetic operations are available, as shown in Table 2-10.

Table 2-10. Arithmetic Operators

Operator Action

-Subtraction or unary minus

+Addition

*Multiplication

/Division

%Modulus

--Decrement

++Increment

The -, +, *, and / operators perform exactly as expected. The % operator evaluates to the remainder of a division operation. The -- and ++ operators decrease and increase the operand by 1, respectively. You can place the -- and ++ operators before the operand, and in this way, the operand is incremented or decremented before any other operations take place in the expression. You can also place these operators after the operand, and in this case, the operand is incremented or decremented after all the operations in the expression are done.

62

C H A P T E R 2 C + + / C L I B A S I C S

When an expression contains more than one arithmetic operator, the arithmetic operators will be evaluated according to the precedence shown in Table 2-11. If two operators of the same precedence occur in the expression, then they are evaluated from left to right.

Table 2-11. Arithmetic Precedence

Precedence

Operators

Highest

-- ++ - (unary minus)

 

* / %

Lowest

- +

 

 

Comparisons and Logical Operators

Comparison operators are used to compare two expressions and then generate a Boolean value (true/false) based on the result of the comparison. There are six comparison operators, as shown in Table 2-12.

Table 2-12. Comparison Operators

Operator Meaning

>Greater than

>=

Greater than or equal to

<Less than

<=

Less than or equal to

==Equal to

!=

Not equal to

 

 

Caution Be very careful when using the assignment operator = and the equal to operator ==. If you mistakenly use = for the comparison operator, the left value is overwritten by the right, and if the left value is nonzero, then the comparison will have a true result. This is unlikely to be what you want.

Logical operators are similar to comparison operators except that they compare Boolean values instead of expressions. The three logical operators are shown in Table 2-13.

Table 2-13. Logical Operators

Operator Meaning

!NOT: If the operand was true, then false is evaluated or vice versa.

&&AND: If both operands are true, then evaluate to true; otherwise, evaluate to false.

||OR: If either or both operands are true, then evaluate to true; otherwise, evaluate to false.

C H A P T E R 2 C + + / C L I B A S I C S

63

Often, you will find both a comparison and a logical operator in the same comparison statement. For grins and giggles, figure out what this means:

a < b && c >= d || !e

When a statement contains more than one comparison or logical operator, then they will be evaluated according to the precedence shown in Table 2-14. If two operators of the same precedence occur in the expression, then they are evaluated from left to right.

Table 2-14. Comparison and Logical Operator Precedence

Highest !

> >= < <=

== !=

&&

Lowest ||

Bitwise Operators

The bitwise operators are used to manipulate the bits of an integer type value. There are six bitwise operators, as shown in Table 2-15.

Table 2-15. Bitwise Operators

Operator

Action

&

Bitwise AND

|

Bitwise OR

^

Bitwise XOR

~

Ones complement

>>Right shift

<<Left shift

The bitwise AND operator compares the bit pattern of its two operands. If both the bits at the same offset in the bit pattern are 1s, then the resulting bit pattern will become a 1; otherwise, it will become a 0. For example:

0101 & 0011 becomes 0001

The bitwise OR operator compares the bit pattern of its two operands. If either or both the bits at the same offset in the bit pattern are 1s, then the resulting bit pattern will become a 1; otherwise, it will become a 0. For example:

0101 & 0011 becomes 0111

64

C H A P T E R 2 C + + / C L I B A S I C S

The bitwise XOR operator compares the bit pattern of its two operands. If either, but not both, of the bits at the same offset in the bit pattern is a 1, then the resulting bit pattern will become a 1; otherwise, it will become a 0. For example:

0101 & 0011 becomes 0110

The ones complement operator simply flips the bits. If it was a 1, then it becomes a 0, and vice versa:

0101 becomes 1010

The shift operators shift all the bits of the operand per the number of bits specified right (>>) or left (<<). For example:

Right shift - 00101100 >> 2 becomes 00001011

Left shift - 00101100 << 2 becomes 10110000

Tip Right-shifting by 1 bit is equivalent to dividing by 2, and left-shifting by 1 bit is equivalent to multiplying by 2. Both shifts are far faster than either dividing or multiplying on a computer. So, if you need a little more speed in your application, and you are working with integer types and dividing or multiplying by factors of 2, you might want to consider shifting instead.

When a statement contains more than one bitwise operator, then the bitwise operators will be evaluated according to the precedence shown in Table 2-16. If two operators of the same precedence occur in the expression, then they are evaluated from left to right.

Table 2-16. Bitwise Operator Precedence

Highest

~

 

>> <<

 

&

 

^

Lowest

|

 

 

Conditional Operator

The conditional operator is the only ternary operator available to C++/CLI programmers. A ternary operator uses three expressions.

The conditional operator takes the first expression and sees if it is true (nonzero) or false (zero). If it is true, then the second expression is executed. If it is false, then the third expression is executed. A conditional operator looks like this:

expression1 ? expression2 : expression3;

a < b ? "a is less than b" : "a is greater than or equal to b";

C H A P T E R 2 C + + / C L I B A S I C S

65

Comma Operator

The comma operator causes a sequence of expressions to act as a single expression, with the last expression ultimately becoming that to which the total expression evaluates. You can place a series of comma-delimited expressions anywhere you can place a normal expression.

You will probably see the comma operator most frequently used in the initialization and increment sections of a for loop, but there is nothing stopping a programmer from using it elsewhere.

I discuss for loops later in this chapter.

The following example, though completely contrived, shows the comma operator in action. First, b is incremented, then a is assigned the value of multiplying post incremented a and b, and finally, c is assigned the value of a modulus b:

int a = 2; int b = 3;

int c = (b++, a = b++ * a++, a % b);

The values of the variables after this code snippet finishes are

a = 9 b = 5 c = 4

Assignment Operators

There are 11 assignment operators available to C++/CLI, as shown in Table 2-17.

Table 2-17. Assignment Operators

Operator Action

=Assign

+=

Add then assign

-=

Subtract then assign

*=

Multiply then assign

/=

Divide then assign

%=

Modulus then assign

>>=

Shift right then assign

<<=

Shift left then assign

&=

AND then assign

^=

XOR then assign

|=

OR then assign

 

 

The operator used to assign one value to another is simply the equal sign (=). The expression on the right side of the equal sign is calculated and then assigned to the value on the left side of the equal sign.

66

C H A P T E R 2 C + + / C L I B A S I C S

You have seen assignment used several times already in this chapter, but here are a few more examples:

String ^str = "This is a managed string."; int num1 = 0x1234;

int num2 = 4321; num1 = num2;

Assigning a common value to several different variables can be accomplished by stringing together several assignments. For example, to assign 42 to the variables a, b, and c, you would write

a = b = c = 42;

It is a common practice to take a value, do some operation it, and then place the results back into the original operator. For example:

a = a + 5; b = b * 2;

So common is this that C++/CLI provides a set of special assignments to handle it:

a += 5; b *= 2;

Address of, Reference, and Indirection Operators

Three operators are available to C++/CLI programmers for handling handles and pointers, as shown in Table 2-18.

Table 2-18. Address of, Reference, and Indirection Operators

Operator

Action

& (unary)

Address of

% (unary)

Reference

* (unary)

Indirection

 

 

The address of operator returns the address of the object after it. For example, if x were located at address 1024, then to place the address (1024) in variable y, you would write this:

y = &x;

// place the address of x into y

Unsafe The address of operator, by its very nature of being a manipulator of pointers, has to be and is an unsafe operation.

The reference operator was introduced, by necessity, in C++/CLI as a consequence of a syntactical lack of a safe operator to reference handles. Introduced for the same reason as the handle, the reference operator provides a means to reference only managed data objects (objects on the managed heap). Thus, it provides an obvious syntactical difference between managed and unsafe code (which use the address of operator). The following code shows how to create a reference of an int value type:

C H A P T E R 2 C + + / C L I B A S I C S

67

int

intVT =

10;

 

 

 

 

int

%intRef

= intVT;

// Assign int value type to a

reference.

Console::WriteLine(intRef);

// Print out

reference. This should contain 10.

intRef = 20;

 

// Change value of

reference.

 

Console::WriteLine(intVT);

// Print out

value

type. This

should contain 20.

The indirection operator has been augmented in C++/CLI from Managed Extensions for C++ and now gets the value from the address or a handle stored within itself. On the one hand, if

y contained the address 1024, then to place the value of 50 at the address 1024, you would write

*y = 50; // place the value of 50 at the address y points to

On the other hand, if y were a handle to an int, then to place the value of 50 on that handle, you would write:

*y = 50; // place the value of 50 at the int handle y

Hmm . . . Looks kind of familiar, don’t you think?

Listing 2-14 is a program that shows the reference and indirection operators in action. I’ll hold off demonstrating the address of operator until I discuss unsafe code in detail in Chapters 20 and 21.

Listing 2-14. Reference and Indirection Operators in Action

using namespace System;

ref class RefClass

{

public: int X;

RefClass(int x)

{

X = x;

}

};

// Reference and Indirection in Action void main()

{

RefClass rc(10); RefClass ^o;

o = %rc;

//

place a reference of

rc in the handle o

Console::WriteLine(o->X);

// print out object. This should contain 10.

rc.X = 20;

 

// place 50 at the address y points to

Console::WriteLine(o->X);

// print out object. This should contain 20.

int %i = rc.X;

 

// assign rc.X to a reference

i = 30;

 

// change value of reference

Console::WriteLine(o->X);

// print out object. This should contain 30.

Console::WriteLine();