Exercise index of this lecture   Alphabetic index   Course home   

Exercises and solutions
Introduction to C#


2.1   Exploring the type Char  

The type System.Char (a struct) contains a number of useful methods, and a couple of constants.

Locate the type System.Char in your C# documentation and take a look at the methods available on characters.

You may ask where you find the C# documentation. There are several possibilities. You can find it at the Microsoft MSDN web site at msdn.microsoft.com. It is also integrated in Visual Studio and - to some degree - in Visual C# express. It comes with the C# SDK, as a separate browser. It is also part of the documentation web pages that comes with Mono. If you are a Windows user I will recommend the Windows SDK Documentation Browser which is bundled with the C# SDK.

Along the line of the character demo program above, write a small C# program that uses the char predicates IsDigit, IsPunctuation, and IsSeparator.

It may be useful to find the code position - also known as the code point - of a character. As an example, the code position of 'A' is 65. Is there a method in System.Char which gives access to this information? If not, can you find another way to find the code position of a character?

Be sure to understand the semantics (meaning) of the method GetNumericValue in type Char.

Solution

The program given below demonstrates the three static methods IsDigit, IsPunctuation, and IsSeparator. It also shows that the casting (type conversion) of a character to the numeric type short reveals the code position (code point) of a character. You get the same result if you cast to longer numeric integer types.

using System;
using System.Globalization;

class CharDemo{

  public static void Main(){

    Console.WriteLine(Char.IsDigit('.'));
    Console.WriteLine(Char.IsDigit('5'));
    Console.WriteLine(Char.IsDigit(' '));
    Console.WriteLine();

    Console.WriteLine(Char.IsPunctuation('.'));
    Console.WriteLine(Char.IsPunctuation('5'));
    Console.WriteLine(Char.IsPunctuation(' '));
    Console.WriteLine();

    Console.WriteLine(Char.IsSeparator('.'));
    Console.WriteLine(Char.IsSeparator('5'));
    Console.WriteLine(Char.IsSeparator(' '));
    Console.WriteLine();

    Console.WriteLine("ch1: {0}", (short)'A');
    Console.WriteLine("ch1: {0}", (short)'∆');
  }                  

}

The output of the program is

False
True
False

True
False
False

False
False
True

ch1: 65
ch1: 198

The method GetNumericValue is intended to be used on characters that represent digits in decimal numbers. As an example, Char.GetNumericValue('2') is equal to the number 2 in type double. If applied on non-digit characters, GetNumericValue returns -1.0. Notice that Char.GetNumericValue('a') is -1.0; In contexts where we work with hexadecimal numbers it would have been useful if Char.GetNumericValue('a') returned 10.


2.2   Hexadecimal numbers  

In this exercise we will write a program that can convert between decimal and hexadecimal notation of numbers. Please consult the focus boxes about hexadecimal numbers in the text book version if you need to.

You might expect that this functionality is already present in the C# libraries. And to some degree, it is.

The static method ToInt32(string, Int32) in class Convert converts the string representation of a number (the first parameter) to an arbitrary number system (the second parameter). Similar methods exist for other integer types.

The method ToString(string) in the struct Int32, can be used for conversion from an integer to a hexadecimal number, represented as a string. The parameter of ToString is a format string. If you pass the string "X" you get a hexadecimal number.

The program below shows examples:

using System;
class NumberDemo{
  public static void Main(){
     int i = Convert.ToInt32("7B", 16);     // hexadecimal 7B (in base 16) -> 
                                            // decimal 123 
     Console.WriteLine(i);                  // 123

     Console.WriteLine(123.ToString("X"));  // decimal 123 -> hexadecimal 7B 
  }
}

Now, write a method which converts a list (or array) of digits in base 16 (or more generally, base b, b >= 2) to a decimal number.

The other way around, write a method which converts a positive decimal integer to a list (or array) of digits in base 16 (or more generally, base b).

Here is an example where the requested methods are used:

  public static void Main(){
    int r = BaseBToDecimal(16, new List{7, 11});  // 7B  -> 123 
    List s = DecimalToBaseB(16, 123);             // 123 -> {7, 11} = 7B
    List t = DecimalToBaseB(2, 123);              // 123 -> {1, 1, 1, 1, 0, 1, 1 } = 
                                                       // 1111011
    Console.WriteLine(r);
    foreach (int digit in s) Console.Write("{0} ", digit);  Console.WriteLine();
    foreach (int digit in t) Console.Write("{0} ", digit);
  }   

Solution

Here is a solution which provides general methods to and from base B:

using System;
using System.Collections.Generic;

class NumberSystems{

  public static int BaseBToDecimal(int B, List<int> digits){
    int result = 0;
    for(int i = 0; i < digits.Count; i++)
       result += digits[digits.Count-i-1] * (int)Math.Pow(B,i);
    return result;
  }

  public static List<int> DecimalToBaseB(int B, int i){
    List<int> result = new List<int>();
    int j = i;
    do{
      result.Insert(0, j % B);
      j = j / B;
    }
    while(j > 0);
    return result;
  }

  public static void Main(){
    int r = BaseBToDecimal(16, new List<int>{7, 11});  // 7B  -> 123 
    List<int> s = DecimalToBaseB(16, 123);             // 123 -> {7, 11} = 7B
    List<int> t = DecimalToBaseB(2, 123);              // 123 -> {1, 1, 1, 1, 0, 1, 1 } = 
                                                       // 1111011
    Console.WriteLine(r);
    foreach (int digit in s) Console.Write("{0} ", digit);  Console.WriteLine();
    foreach (int digit in t) Console.Write("{0} ", digit);
  }   
}

The Pow method is a static method in class System.Math. Math.Pow(a, b) raises a to the power of b. Example: Math.Pow(2, 3) = 2 * 2 * 2. Pow works on doubles. Therefore we cast the result to an integer.

Notice that the operator / is an integer division operator when applied on values of type int.

The expressions i % j returns the remainder of the integer division i / j.

For details on List<T> for some type T (here int) please consult the slide overview of the class List.


2.3   ECTS Grades  

Define an enumeration type ECTSGrade of the grades A, B, C, D, E, Fx and F and associate the Danish 7-step grades 12, 10, 7, 4, 2, 0, and -3 to the symbolic ECTS grades.

What is the most natural underlying type of ECTSGrade?

Write a small program which illustrates how to use the new enumeration type.

Solution

Here is my solution:

using System;

public enum ECTSGrade: sbyte     // signed byte
  {A = 12, B = 10, C = 7, D = 4, E = 2, Fx = 0, F = -3}


public class GradeExercise{

  public static void Main(){

    ECTSGrade g1 = (ECTSGrade)0,
              g2 = ECTSGrade.B;
  
    Console.WriteLine("Grade g1: {0}", g1);    // Fx
    Console.WriteLine("Grade g2: {0}", g2);    // B
    Console.WriteLine("Grade g2: {0}", g2+1);  // 11  -- not 12
  }
}


2.4   Use of Enumeration types  

Consult the documentation of type type System.Enum, and get a general overview of the methods in this struct.

Be sure that you are able to find the documentation of System.Enum

Test drive the example EnumTest, which is part of MicroSoft's documentation. Be sure to understand the program relative to its output.

Write your own program with a simple enumeration type. Use the Enum.CompareTo method to compare two of the values of your enumeration type.

Solution

The class EnumTest from Microsoft's documentation pages of class System.Enum is reproduced here:

using System;

public class EnumTest {
    enum Days { Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday };
    enum BoilingPoints { Celcius = 100, Fahrenheit = 212 };
    [FlagsAttribute]
    enum Colors { Red = 1, Green = 2, Blue = 4, Yellow = 8 };

    public static void Main() {

        Type weekdays = typeof(Days);
        Type boiling = typeof(BoilingPoints);

        Console.WriteLine("The days of the week, and their corresponding values in the Days Enum are:");

        foreach ( string s in Enum.GetNames(weekdays) )
            Console.WriteLine( "{0,-11}= {1}", s, Enum.Format( weekdays, Enum.Parse(weekdays, s), "d"));

        Console.WriteLine();
        Console.WriteLine("Enums can also be created which have values that represent some meaningful amount.");
        Console.WriteLine("The BoilingPoints Enum defines the following items, and corresponding values:");

        foreach ( string s in Enum.GetNames(boiling) )
            Console.WriteLine( "{0,-11}= {1}", s, Enum.Format(boiling, Enum.Parse(boiling, s), "d"));

        Colors myColors = Colors.Red | Colors.Blue | Colors.Yellow;
        Console.WriteLine();
        Console.WriteLine("myColors holds a combination of colors. Namely: {0}", myColors);
    }
}

The output of the program is:

The days of the week, and their corresponding values in the Days Enum are:
Saturday   = 0
Sunday     = 1
Monday     = 2
Tuesday    = 3
Wednesday  = 4
Thursday   = 5
Friday     = 6

Enums can also be created which have values that represent some meaningful amount.
The BoilingPoints Enum defines the following items, and corresponding values:
Celcius    = 100
Fahrenheit = 212

myColors holds a combination of colors. Namely: Red, Blue, Yellow

Let me explain some details.

The first foreach loop traverses an array of strings returned by Enum.GetNames(weekdays). This is the array of strings "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday". The method Enum.Parse establishes a enumeration constant from the name of it (a string).

The method Enum.Format produces a formatted string of the second parameter (a value in the enumeration type). The following foreach statement produces equivalent results:

        foreach ( string s in Enum.GetNames(weekdays) )
            Console.WriteLine( "{0,-11}= {1}", s, (int)(Enum.Parse(weekdays, s)));

The second foreach loop is similar.

The last three lines show combined enumerations. It is noteworthy that the value of mycolor is formatted as Red, Blue, Yellow when printed. See also the Focus Box about combined enumerations.


2.5   Use of array types  

Based on the inspiration from the accompanying example, you are in this exercise supposed to experiment with some simple C# arrays.

First, consult the documentation of the class System.Array. Please notice the properties and methods that are available on arrays in C#.

Declare, initialize, and print an array of names (e.g. array of strings) of all members of your group.

Sort the array, and search for a given name using System.Array.BinarySearch method.

Reverse the array, and make sure that the reversing works.

Solution

Here is my solution:

using System;

class StringTry{

  public static void Main(){

    string[] group = {"Kurt", "Peter", "Paul", "Mary"};

    foreach(string name in group)
      Console.WriteLine(name);       // Kurt Peter Paul Mary

    Console.WriteLine();

    Array.Sort(group); 
    foreach(string name in group)
      Console.WriteLine(name);       // Kurt Mary Paul Peter

    int res = Array.BinarySearch(group, "Mary");
    Console.WriteLine(res);          // 1

    Console.WriteLine();

    Array.Reverse(group);
    foreach(string name in group)
      Console.WriteLine(name);       // Peter Paul Mary Kurt
 
  }

}


2.6   Use of string types  

Based on the inspiration from the accompanying example, you are in this exercise supposed to experiment with some simple C# strings.

First, consult the documentation of the class System.String - either in your documentation browser or at msdn.microsoft.com. Read the introduction (remarks) to string which contains useful information! There exists a large variety of operations on strings. Please make sure that you are aware of these. Many of them will help you a lot in the future!

Make a string of your own first name, written with escaped Unicode characters (like we did for "OOP" in the accompanying example). If necessary, consult the unicode code charts (Basic Latin and Latin-1) to find the appropriate characters.

Take a look at the System.String.Insert method. Use this method to insert your last name in the first name string. Make your own observations about Insert relative to the fact that strings in C# are immutable.

Solution

Here is my solution:

using System;

class StringTry{

  public static void Main(){
    string firstName = "\u004B\u0075\u0072\u0074", // "Kurt"
           lastName = "N\u00F8rmark",
           fullName = firstName.Insert(4, String.Concat(" ", lastName));

    Console.WriteLine(firstName);
    Console.WriteLine(lastName);
    Console.WriteLine(fullName);
  }

}


Generated: Monday February 7, 2011, 12:12:49