This week's topics are covered in Essential C#: see ch. 1 Introducing C#, ch. 2 Data Types, ch. 3 More with Data Types (Arrays), ch. 4 Operators and Control Flow.
Here is a summary of the C# elements we discussed:
using System; class Hello { static void Main() { Console.WriteLine("hello, world"); } }
A local variable declaration declares one or more local variables and optionally gives them initial values:
int i = 3, j = 4;
When you declare a local variable, you can use the var
keyword to tell the compiler to infer its type. For example:
var s = "distant hill";
This is equivalent to
string s = "distant hill";
A single-line comment begins with //
and extends to
the end of the line:
x += 1; // increment x
Comments delimited with /*
and */
can
extend over multiple lines:
/* this is a comment with multiple lines */
sbyte
– 8 bits, signed (-128 to 127)
byte
– 8 bits, unsigned (0 to 255)
short
– 16 bits, signed (-32,768 to 32,767)
ushort
– 16 bits, unsigned (0 to 65,535)
int
– 32 bits, signed (-231 to 231 - 1)
uint
– 32 bits, unsigned (0 to 232 – 1)
long
– 64 bits, signed (- 263 to 263 –
1)
ulong
– 64 bits, unsigned (0 to 264 - 1)
A literal integer (or floating-point value) may contain embedded underscores for readability:
int i = 1_000_000_000; // 1 billion
The inferred type of an integer literal is the first of these types which can hold it: int, uint, long, ulong.
float
– 32 bits, 7 significant digits
double
– 64 bits, 15-16 significant digits
decimal
– 128 bits, 28 significant digits, base-10 representation
The inferred type of a floating-point literal (e.g. 3.4
)
is double
by default. To create a literal of type float
,
append the character 'f', e.g. 3.4f
.
C# will perform an implicit conversion between two numeric types if every possible value of the source type is valid in the destination type. For example:
short s; ... int i = s; // implicit conversion
You can also implicitly convert a char
to any numeric
type that can hold a 16-bit unsigned value:
char c = 'ř'; int i = c; // now i holds the Unicode value for 'ř', i.e. 345
You can use an explicit conversion to force a conversion between any two numeric types. This is accomplished with a type cast:
int i = 1000; short s = (short) i;
If the destination type cannot hold the source value, it will wrap around or be truncated.
You can explicitly convert any numeric type to a char
:
int i = 100; char c = (char) i; // now c is 'd', which is ASCII/Unicode character 100
The bool
type represents a Boolean value, namely either true
or false
.
A char
is a 16-bit Unicode character.
A character constant is enclosed in single quotes, e.g. 'x'
or 'ř'
.
A character constant containing a backslash is an escape
sequence.
Here are some common escape sequences:
\n
– newline
\r
– carriage return
\'
- single quote
\"
- double quote
\\
- backslash
To create a character constant representing a single quote or backslash, use one of the sequences above:
WriteLine('\\'); // writes a backslash WriteLine('\''); // writes a single quote
A string
is an immutable sequence of
characters. A string literal is enclosed in double quotes, e.g.
"hello"
.
Ordinary string literals may contain escape sequences.
You may access individual characters of a string using square brackets:
string s = "spire"; char c = s[2]; // now c = 'i'
Note that characters are indexed starting from 0.
A string beginning with $
may contain interpolated
values enclosed in braces:
int a = 3, b = 4; WriteLine($"{a} plus {b} equals {a + b}");
A interpolated value may be followed by a format specifier (preceded by a colon).
There are many predefined format specifiers. Many format specifiers can be followed by an integer called the precision, whose meaning varies among specifiers. Here are two useful specifiers:
f
– prints a number in fixed-point decimal
(i.e. not using scientific notation). The precision is the number of
the digits after the decimal point.
n
– prints a number using thousands
separators. The precision is the number of digits after the decimal
point.
For example,
const double pi = 3.14159; const int i = 1357; WriteLine($"{pi:f2} {i:n0}");
writes
3.14 1,357
A literal string preceded with @ is a verbatim string, and differs from an ordinary string literal in two ways:
A backslash (\
) in a verbatim string is an
ordinary backslash; it does not introduce an escape sequence.
A verbatim string may extend over multiple lines.
To include a double quote character (") in a verbatim string, type it twice. For example:
string s = @"He said, ""Where is she?""" Console.WriteLine(s)
prints
He said, "Where is she?"
You can allocate an array like this:
int[] i = new int[10];
With this form of allocation all elements are initialized to the element type's default value. For example, the default value for integers is 0.
Alternatively, you can allocate an array and initialize its elements to specific values:
int[] i = { 3, 4, 5 };
Arrays are indexed from 0. The Length
property returns
the length of an array.
+
: addition
The +
operator can also be used to concatenate
strings:
WriteLine("good" + " " + "bread");
It can also concatenate strings and other kinds of values:
int i = 4; WriteLine("i = " + i);
-
: subtraction
*
: multiplication
/
: division
The / operator performs integer division if both its arguments have integer types:
WriteLine(7 / 3); // will write 2
Otherwise, floating-point division is performed:
WriteLine(7 / 3.0); // will write 2.3333
The result of integer division is truncated toward zero. For example, -17 / 5 is -3. (This differs from some other languages such as Python, which truncates toward -∞.)
%
: remainder
Be aware that if a < 0 and b > 0, then (a % b) will be negative or zero, never positive. For example, (-17 % 5) is -2. This is consistent with the fact that division truncates toward zero. (This differs from some other languages such as Python. In Python, if b > 0 then (a mod b) is always a value in the range 0 ≤ x < b.)
! : not
| : or
&& : and
==
: equals
!=
: does not equal
These operators are defined on numbers and characters, but not on strings.
<
: less than
<=
: less than or equal to
>
: greater than
>=
: greater than or equal to
+=
: addition
-=
: subtraction
*=
: multiplication
/=
: division
%=
: remainder
if (i > 0) { WriteLine("positive"); WriteLine("definitely positive"); } else if (i == 0) WriteLine("zero"); else WriteLine("negative");
An if
statement executes a statement (or block) if the
given value is true. If the statement has an else
clause, it is executed if the given value is false.
while (i < 10) { sum = sum + i; i += 1; }
A while
loop loops as long as the given condition is
true.
do { s = ReadLine(); } while (s != "yes" && s != "no");
A do
/while
loop is like a while
loop, but checks the loop condition at the bottom of the loop body.
for (int i = 0 ; i < 10 ; i += 1) WriteLine(i);
A for
statement contains three clauses, separated by
semicolons, plus a loop body.
The initializer (e.g. int
i =
0
)
executes once at the beginning of the loop. It contains either a
variable declaration, or one or more statements separated by commas.
The condition (e.g.
i
<
10
)
is evaluated before every loop iteration. If it is false, the loop
terminates.
The iterator (e.g. i +=
1
)
executes at the end of every loop iteration. It contains one or more
statements, separated by commas.