Home > Articles > Programming > C#

Working with Operators and Control Flow in C#

This chapter introduces the C# operators related to assignment and arithmetic, shows how to use the operators along with the const keyword to declare constants, introduces the if statement and the important concepts of code blocks and scope, and discusses the bitwise operators, especially regarding masks. It also covers other control flow statements such as loops, switch, and goto, and ends with the C# preprocessor directives.
This chapter is from the book

This chapter is from the book

In this chapter, you will learn about operators, control flow statements, and the C# preprocessor. Operators provide syntax for performing different calculations or actions appropriate for the operands within the calculation. Control flow statements provide the means for conditional logic within a program or looping over a section of code multiple times. After introducing the if control flow statement, the chapter looks at the concept of Boolean expressions, which are embedded within many control flow statements. Included is mention of how integers will not cast (even explicitly) to bool and the advantages of this restriction. The chapter ends with a discussion of the C# preprocessor directives.

Operators

Now that you have been introduced to the predefined data types (refer to Chapter 2), you can begin to learn more about how to use these data types in combination with operators in order to perform calculations. For example, you can make calculations on variables that you have declared.

Listing 3.1. A Simple Operator Example

int difference = 4 – 2;

Operators are generally broken down into three categories: unary, binary, and ternary, corresponding to the number of operands 1, 2, and 3, respectively. This section covers some of the most basic unary and binary operators. Introduction to the ternary operator appears later in the chapter.

Plus and Minus Unary Operators (+, -)

Sometimes you may want to change the sign of a numerical value. In these cases, the unary minus operator (-) comes in handy. For example, Listing 3.2 changes the total current U.S. debt to a negative value to indicate that it is an amount owed.

Listing 3.2. Specifying Negative Values1

//National Debt to the Penny
decimal debt = -15236332233848.35M;

Using the minus operator is equivalent to subtracting the operand from zero.

The unary plus operator (+) rarely2 has any effect on a value. It is a superfluous addition to the C# language and was included for the sake of symmetry.

Arithmetic Binary Operators (+, -, *, /, %)

Binary operators require two operands. C# uses infix notation for binary operators: The operator appears between the left and right operands. The result of every binary operator other than assignment must be used somehow: for example, by using it as an operand in another expression such as an assignment.

The subtraction example in Listing 3.3 is an example of a binary operator—more specifically, an arithmetic binary operator. The operands appear on each side of the arithmetic operator and then the calculated value is assigned. The other arithmetic binary operators are addition (+), division (/), multiplication (*), and remainder (%)—sometimes called the mod operator.

Listing 3.3. Using Binary Operators

class Division
{
  static void Main()
  {
      int numerator;
      int denominator;
      int quotient;
      int remainder;

      System.Console.Write("Enter the numerator: ");
      numerator = int.Parse(System.Console.ReadLine());

      System.Console.Write("Enter the denominator: ");
      denominator = int.Parse(System.Console.ReadLine());

      quotient = numerator / denominator;                                    
      remainder = numerator % denominator;                                   

      System.Console.WriteLine(
          "{0} / {1} = {2} with remainder {3}",
          numerator, denominator, quotient, remainder);
  }
}

Output 3.1 shows the results of Listing 3.3.

Output 3.1.

Enter the numerator: 23
Enter the denominator: 3
23 / 3 = 7 with remainder 2

In the highlighted assignment statements above, the division and remainder operations are executed before the assignments. The order in which operators are executed is determined by their precedence and associativity. The precedence for the operators used so far is as follows.

  1. *, /, and % have highest precedence.
  2. + and - have lower precedence.
  3. = has the lowest precedence of these six operators.

Therefore, you can assume that the statement behaves as expected, with the division and remainder operators executing before the assignment.

If you forget to assign the result of one of these binary operators, you will receive the compile error shown in Output 3.2.

Output 3.2.

... error CS0201: Only assignment, call, increment, decrement,
and new object expressions can be used as a statement

Using the Addition Operator with Strings

Operators can also work with non-numeric operands. For example, it is possible to use the addition operator to concatenate two or more strings, as shown in Listing 3.4.

Listing 3.4. Using Binary Operators with Non-Numeric Types

class FortyTwo
{
  static void Main()
  {
      short windSpeed = 42;
      System.Console.WriteLine(
          "The original Tacoma Bridge in Washington\nwas "
          + "brought down by a "
          + windSpeed + " mile/hour wind.");
  }
}

Output 3.3 shows the results of Listing 3.4.

Output 3.3.

The original Tacoma Bridge in Washington
was brought down by a 42 mile/hour wind.

Because sentence structure varies among languages in different cultures, developers should be careful not to use the addition operator with strings that require localization. Composite formatting is preferred (refer to Chapter 1).

Using Characters in Arithmetic Operations

When introducing the char type in the preceding chapter, we mentioned that even though it stores characters and not numbers, the char type is an integral type (“integral” means it is based on an integer). It can participate in arithmetic operations with other integer types. However, interpretation of the value of the char type is not based on the character stored within it, but rather on its underlying value. The digit 3, for example, contains a Unicode value of 0x33 (hexadecimal), which in base 10 is 51. The digit 4, on the other hand, contains a Unicode value of 0x34, or 52 in base 10. Adding 3 and 4 in Listing 3.5 results in a hexadecimal value of 0x167, or 103 in base 10, which is equivalent to the letter g.

Listing 3.5. Using the Plus Operator with the char Data Type

int n = '3' + '4';
char c = (char)n;
System.Console.WriteLine(c);  // Writes out g.

Output 3.4 shows the results of Listing 3.5.

Output 3.4.

g

You can use this trait of character types to determine how far two characters are from each other. For example, the letter f is three characters away from the letter c. You can determine this value by subtracting the letter c from the letter f, as Listing 3.6 demonstrates.

Listing 3.6. Determining the Character Difference between Two Characters

int distance = 'f''c';
System.Console.WriteLine(distance);

Output 3.5 shows the results of Listing 3.6.

Output 3.5.

3

Special Floating-Point Characteristics

The binary floating-point types, float and double, have some special characteristics, such as the way they handle precision. This section looks at some specific examples, as well as some unique floating-point type characteristics.

A float, with seven decimal digits of precision, can hold the value 1,234,567 and the value 0.1234567. However, if you add these two floats together, the result will be rounded to 1234567, because the exact result requires more precision than the seven significant digits that a float can hold. The error introduced by rounding off to seven digits can become large compared to the value computed, especially with repeated calculations. (See also the upcoming Advanced Topic, Unexpected Inequality with Floating-Point Types.)

Since the double can hold a more accurate value than the float can store, the C# compiler will actually evaluate this expression to double number = 140.600006103516 because 140.600006103516 is the closest binary fraction to 140.6 as a float. This fraction is slightly larger than 140.6 when represented as a double.

Output 3.6 shows the results of Listing 3.7.

Output 3.6.

4.2 != 4.20000006258488
4.2 != 4.20000006258488
(float)4.2M != 4.2F
4.20000006258488 != 4.20000028610229
4.20000006258488 != 4.2
4.2F != 4.2D
4.19999980926514 != 4.2
4.2F != 4.2D

The Assert() methods alert the developer whenever their argument evaluates to false. However, of all the Assert() calls in this code listing, only half have arguments that evaluate to true. In spite of the apparent equality of the values in the code listing, they are in fact not equivalent due to the inaccuracies of a float.

You should be aware of some additional unique floating-point characteristics as well. For instance, you would expect that dividing an integer by zero would result in an error, and it does with data types such as int and decimal. The float and double types instead allow for certain special values. Consider Listing 3.8, and its resultant output, Output 3.7.

Listing 3.8. Dividing a Float by Zero, Displaying NaN

float n=0f;
// Displays: NaN
System.Console.WriteLine(n / 0);

Output 3.7.

NaN

In mathematics, certain mathematical operations are undefined, including dividing zero by itself. In C#, the result of dividing the float zero by zero results in a special “Not a Number” value; all attempts to print the output of such a number will result in NaN. Similarly, taking the square root of a negative number with System.Math.Sqrt(-1) will result in NaN.

A floating-point number could overflow its bounds as well. For example, the upper bound of the float type is approximately 3.4 x 1038. Should the number overflow that bound, the result would be stored as “positive infinity” and the output of printing the number would be Infinity. Similarly, the lower bound of a float type is –3.4 x 1038, and computing a value below that bound would result in “negative infinity,” which would be represented by the string -Infinity. Listing 3.9 produces negative and positive infinity, respectively, and Output 3.8 shows the results.

Listing 3.9. Overflowing the Bounds of a float

// Displays: -Infinity
System.Console.WriteLine(-1f / 0);
// Displays: Infinity
System.Console.WriteLine(3.402823E+38f * 2f);

Output 3.8.

-Infinity
Infinity

Further examination of the floating-point number reveals that it can contain a value very close to zero, without actually containing zero. If the value exceeds the lower threshold for the float or double type, the value of the number can be represented as “negative zero” or “positive zero,” depending on whether the number is negative or positive, and is represented in output as -0 or 0.

Compound Assignment Operators (+=, -=, *=, /=, %=)

Chapter 1 discussed the simple assignment operator, which places the value of the right-hand side of the operator into the variable on the left-hand side. Compound assignment operators combine common binary operator calculations with the assignment operator. Take Listing 3.10, for example.

Listing 3.10. Common Increment Calculation

int x = 123;
x = x + 2;

In this assignment, first you calculate the value of x + 2 and then you assign the calculated value back to x. Since this type of operation is relatively frequent, an assignment operator exists to handle both the calculation and the assignment with one operator. The += operator increments the variable on the left-hand side of the operator with the value on the right-hand side of the operator, as shown in Listing 3.11.

Listing 3.11. Using the += Operator

int x = 123;
x += 2;

This code, therefore, is equivalent to Listing 3.10.

Numerous other combination assignment operators exist to provide similar functionality. You can also use the assignment operator with subtraction, multiplication, division and the remainder operators (Listing 3.12 demonstrates).

Listing 3.12. Other Assignment Operator Examples

x -= 2;
x /= 2;
x *= 2;
x %= 2;

Increment and Decrement Operators (++, --)

C# includes special unary operators for incrementing and decrementing counters. The increment operator, ++, increments a variable by one each time it is used. In other words, all of the code lines shown in Listing 3.13 are equivalent.

Listing 3.13. Increment Operator

spaceCount = spaceCount + 1;
spaceCount += 1;
spaceCount++;

Similarly, you can also decrement a variable by one using the decrement operator, --. Therefore, all of the code lines shown in Listing 3.14 are also equivalent.

Listing 3.14. Decrement Operator

lines = lines - 1;
lines -= 1;
lines--;

The increment and decrement operators are used to control how many times a particular operation is performed. Notice also that in this example, the increment operator is used on a character (char) data type. You can use increment and decrement operators on various data types as long as some meaning is assigned to the concept of the “next” or “previous” value for that data type.

We saw that the assignment operator first computes the value to be assigned, and then causes the assignment. The result of the assignment operator is the value that was assigned. The increment and decrement operators are similar: They compute the value to be assigned, perform the assignment, and result in a value. It is therefore possible to use the assignment operator with the increment or decrement operator, though doing so carelessly can be extremely confusing. See Listing 3.16 and Output 3.10 for an example.

Listing 3.16. Using the Post-Increment Operator

int count = 123;
int result;
result = count++;                                                                    
System.Console.WriteLine(
  "result = {0} and count = {1}", result, count);

Output 3.10.

result = 123 and count = 124

You might be surprised that result was assigned the value that was count before count was incremented. Where you place the increment or decrement operator determines whether the assigned value should be the value of the operand before or after the calculation. If you want the value of result to be the value assigned to count, you need to place the operator before the variable being incremented, as shown in Listing 3.17.

Listing 3.17. Using the Pre-Increment Operator

int count = 123;
int result;
result = ++count;                                                                                
System.Console.WriteLine(
  "result = {0} and count = {1}", result, count);

Output 3.11 shows the results of Listing 3.17.

Output 3.11.

result = 124 and count = 124

In this example, the increment operator appears before the operand, so the result of the expression is the value assigned to the variable after the increment. If count is 123, ++count will assign 124 to count and produce the result 124. By contrast, the postfix increment operator count++ assigns 124 to count and produces the value that count held before the increment: 123. Regardless of whether the operator is postfix or prefix, the variable count will be incremented before the value is produced; the only difference is which value is produced. The difference between prefix and postfix behavior appears in Listing 3.18. The resultant output is shown in Output 3.12.

Listing 3.18. Comparing the Prefix and Postfix Increment Operators

class IncrementExample
{
  public static void Main()
  {
      int x = 123;
      // Displays 123, 124, 125.
      System.Console.WriteLine("{0}, {1}, {2}", x++, x++, x);
      // x now contains the value 125.
      // Displays 126, 127, 128
      System.Console.WriteLine("{0}, {1}, {2}", ++x, ++x, x);
      // x now contains the value 128.
  }
}

Output 3.12.

123, 124, 125
126, 127, 128

As Listing 3.18 demonstrates, where the increment and decrement operators appear relative to the operand can affect the result produced by the expression. The result of the prefix operators is the value that the variable had before it was incremented or decremented. The result of the postfix operators is the value that the variable had after it was incremented or decremented. Use caution when embedding these operators in the middle of a statement. When in doubt as to what will happen, use these operators independently, placing them within their own statements. This way, the code is also more readable and there is no mistaking the intention.

Constant Expressions and Constant Locals

The preceding chapter discussed literal values, or values embedded directly into the code. It is possible to combine multiple literal values in a constant expression using operators. By definition, a constant expression is one that the C# compiler can evaluate at compile time (instead of calculating it when the program runs) because it is composed entirely of constant operands. Constant expressions can then be used to initialize constant locals, which allow you to give a name to a constant value (similar to the way local variables allow you to give a name to a storage location). For example, the computation of the number of seconds in a day can be a constant expression that is then used in other expressions by name.

The const keyword in Listing 3.19 declares a constant local. Since a constant local is by definition the opposite of a variable—“constant” means “not able to vary”—any attempt to modify the value later in the code would result in a compile-time error.

Note that the expression assigned to secondsPerWeek is a constant expression because all the operands in the expression are also constants.

Listing 3.19. Declaring a Constant

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020