Consider the classic helloworld program in C:
int main ()
{
printf ("Hello World!\n");
}
The main syntactic elements are:
- C's only reserved word in this program: int.
- Function names: main, printf.
- Delimiters for the function main.
- An end-of-statement symbol, the semicolon.
- Parentheses for enclosing method parameters (arguments).
- A string literal, Hello World!.
- Braces that delimit the body of main.
Next, let us get accustomed to errors produced by the compiler
when the syntax is incorrect.
Exercise 0.5
What errors are reported by the compiler with this program?
int main ( // Forgot the matching right parenthesis
{
printf ("Hello World!\n");
}
Exercise 0.7
What errors are reported by the compiler with this program?
int main ()
{
printf ("Hello World!\n); // Forgot the matching right quote (")
}
Exercise 0.8
What errors are reported by the compiler with this program?
int main ()
{
printf ("Hello World!\n") // Forgot the semi-colon.
}
Exercise 0.9
What errors are reported the compiler with this program?
int main ()
{
printf ("Hello World!\n");
// Missing brace
Exercise 0.10
Try to compile and run this program.
main ()
{
printf ("Hello World!\n");
}
Data types and Identifiers
Let us examine some code with only int's to get started:
int main ()
{
// Declare an integer variable called "i".
int i;
// Assign it a value. Note the assignment operator "="
i = 5;
// Print out its value to the screen.
printf ("%d\n", i);
}
Next, let's play around with the syntax and observe what the
compiler reports.
Exercise 0.11
Try to compile and run this program.
int main ()
{
// Didn't declare "i"
// Assign it a value. Note the assignment operator "="
i = 5;
// Print out its value to the screen.
printf ("%d\n", i);
}
Exercise 0.12
Try to compile and run this program.
int main ()
{
// Declare an integer variable called "i".
int i;
// Wrong assignment operator
i := 5;
// Print out its value to the screen.
printf ("%d\n", i);
}
Note:
- Good programming style requires that variable names be chosen
for readability.
- Variable names like i are usually only appropriate
for loop (control) variables.
- What kinds of variable names are allowed?
The rules that apply to variable names also apply to
method and parameter names, the so-called identifiers.
About identifiers:
- An identifier must begin with a letter or underscore
- An identifiers can contain any number of letters, digits, or underscores.
- Case (upper or lower) is significant.
- No C reserved word can be used as an identifier.
- Examples of legal identifiers:
i
really_important_integer_for_counting_lines_in_a_text_file (bad style)
num_lines_in_file (acceptable, old C style)
numLinesInFile (recommended, new C style)
More about variable declaration syntax:
- Variables can be assigned values in a declaration:
int main ()
{
// Declare an integer variable called "i" and assign it a value.
int i = 5;
// Print out its value to the screen.
printf ("%d\n", i);
}
- Declarations can occur anywhere in a program body in C99 but
not in earlier versions.
- Multiple variables (of the same type) can be declared in a
single statement:
int main ()
{
// Declare multiple variables of the same type.
int i = 5, j = 6, k;
k = 7;
printf ("i=%d j=%d k=%d\n", i, j, k);
}
The preferred style is either:
int main ()
{
int i = 5; // i is the variable that ....
int j = 6; // j ...
int k = 7; // k ...
printf ("i=%d j=%d k=%d\n", i, j, k);
}
or
int main ()
{
int
i = 5, // i is the variable that ....
j = 6, // j ...
k = 7; // k ...
printf ("i=%d j=%d k=%d\n", i, j, k);
}
More Data Types
While there are seven additional data types, we will first focus on
a few:
- double
- Use double to store floating point numbers, as in:
int main ()
{
double
pi = 3.14159, // The constant Pi
radius = 2.0E03, // Circle radius in exponent format.
area = 0; // Area, not yet computed.
area = pi * radius * radius;
printf ("Area of circle with radius %lf is %lf\n", radius, area);
}
- double constants are decimal values
(3.14159), or in exponent notation (2.0E03).
- char
- A char variable holds a single character, e.g.,
int main ()
{
char
initial1 = 'J',
initial2 = 'F',
initial3 = 'K';
printf ("Initials: %c %c %c\n", initial1, initial2, initial3);
}
- "Backslash" combinations are used to represent special characters:
int main ()
{
char initial1 = 'J';
char initial2 = 'F';
char initial3 = 'K';
char newline = '\n';
char tab = '\t';
printf ("%c Initials: %c \" %c %c %c \" %c", newline, tab, initial1, initial2, initial3, newline);
}
- Notice the double quote character inside the string
"Initials: %c \".
- Strings
- Strings in C are really char-arrays, pointed to by a variable
of type char *
- Example:
int main ()
{
char *str1 = "Hello";
char *str2 = "World!";
// String constants can be concatenated by whitepace:
char *str3 = "Hello" " again";
printf ("%s %s \n %s \n", str1, str2, str3);
}
Casting
Casting is the term used to convert a value of one data type to
a value of another data type. For example:
int main ()
{
int i = 5, j = 6;
double x = 2.718, y = 3.141;
// Implicit cast:
x = i;
printf ("x = %lf\n", x); // Prints 5.0
// Explicit cast:
j = (int) y;
printf ("j = %d\n", j); // Prints 3
}
Exercise 0.13
What does the following program print out?
int main ()
{
printf ("%lf\n", ( (double) (int) 3.141 ) );
}
Expressions
Arithmetic expressions:
Exercise 0.14
What does the following program print out?
int main ()
{
int k = 13;
int i;
for (i=0; i < 8; i++) {
printf ("%d ", (k % 2));
k >>= 1;
}
printf ("%\n");
}
Boolean expressions:
- Boolean operators include:
&& | AND |
|| | OR |
! | NOT |
& | Bitwise AND |
| | Bitwise OR |
^ | Bitwise XOR |
- Examples of boolean expressions used in if statements:
if (i == 10)
printf ("i is equal to 10");
if ( !(i == 10) )
printf ("i is not equal to 10");
if (i < 10)
print ("i is less than 10");
if ( (i >= 5) && (i <= 10) )
print ("i is between 5 and 10");
if ( (i >= 5) && (i != 6) )
printf ("i larger than 6");
Statements
Finally, we will examine some basic C statements.
The following is not meant to be exhaustive, but rather, a quick
introduction to the most commonly used statements:
- Assignment:
- Assignment statements use the assignment operator =,
e.g.,
x = 5; // Simple assignment.
y = getInputValue(); // Assign a function's return value.
z = (x + y) / y; // Assign an expression value.
- Assignment can be combined with many operators, e.g.,
x += 5; // Add 5 to x
- Assignments can be grouped:
x = y = z = 0; // All are given the value 0.
- if-statement:
- An if-statement is the keyword if followed by a
boolean expression in parentheses, followed by a statement.
- Example:
if (x < 5)
printf ("x is less than 5");
- compound-statement:
- Compound statements are groups of statements placed in a
single block.
- A block is delineated with braces.
- Example:
if (x < 5) { // Start of block
y = 5;
z += x;
} // End of block
- Example:
if (x < 5) { // Start of outer block
y = 5;
z += x;
if (z > 10) { // Start of inner block
z = z - 1;
w = z * z;
} // End of inner block
} // End of outer block
- if-else and if-else-if statements:
- Example of if-else
if (x < 5) {
printf ("x is less than 5");
}
else {
printf ("x is not less than 5");
}
- Example of if-else-if
if (x < 5) {
printf ("x is less than 5");
}
else if (x > 5) {
printf ("x is greater than 5");
}
else if (x == 5) {
printf ("x is equal to 5");
}
else {
// Logically impossible!
}
- while loop:
- Example:
printf ("Countdown: ");
i = 10;
while (i >= 1) { // Start of while-body
printf ("%d\n", i);
i--;
} // End of while-body
- Any boolean expression can be used for the while-test
expression (i.e., in place of i >= 1).
- for loop:
- Example:
int i;
printf ("Countdown: \n");
for (i=10; i >= 1; i--) { // Start of for-body
printf ("%d\n", i);
} // End of while-body
- The loop-header first has a statement (int i = 10)
then a boolean expression (i>=1), followed by another
statement (i--), each separated by a semi-colon.
- Note: for consistency with C versions prior to C99, the
for-loop variable is defined earlier.
- Each statement (first, and third parts) can consist of
multiple comma-separated statements:
int i, j;
printf ("Weird countdown/up: \n");
for (i=10, j=1; ( (i >= 1) && (j <= 10) ); i--, j++) {
printf ("i=%d j=%d\n", i, j);
}
- Sometimes, the flexibility offered by the for-loop can be
taken too far, making some code examples difficult to read:
printf ("Really weird countdown/up: \n");
for (countInitializer (i,10), countInitializer (j,1);
checkCountGreaterEqual (i, 1) && checkCountLessEqual (j, 10);
incrementCount (i, -1), incrementCount (j, 1)) {
printf ("i=%d j=%d\n", i, j);
}
Exercise 0.15
What's wrong with the statement below? What happens when you compile?
if (i = 5)
printf ("i is equal to 5");
Exercise 0.16
What is the error in the following code?
int i = 10;
while (i >= 1)
printf ("i=%d\n", i);
i--;
Functions
Other languages call them "procedures" or "methods". C calls
them functions:
- A function refers to both a procedure (doesn't return a
value) or a function (does return a value).
- A function that does not return a value returns a void
value.
- A function declaration has a
return type, followed by the name, followed by parameter declarations.
- Example of a simple (static) method declaration:
void printHello ()
{
printf ("Hello World!");
}
int main ()
{
printHello ();
}
Note:
- The method printHello() has no parameters.
- The return type is void.
- Although main doesn't return anything, it's return
type is declared as int, for the esoteric applications
in which the int is used.
- Example with parameters and return values:
int squareIt (int inputInteger)
{
int squareValue = inputInteger * inputInteger;
return squareValue;
}
int main ()
{
int i = 5;
int j = squareIt (i);
printf ("The square of %d is %d\n", i, j);
}
Note:
- The method squareIt() takes one int parameter and
returns an int.
- The return-statement is the keyword return followed
by an expression whose type is the same as the return type.
- Let's consider some variations of the previous example to
illustrate a few points:
- The return-expression can be of any type that can be cast into
the return type, e.g,
int squareIt (int inputInteger)
{
double squareValue = inputInteger * inputInteger;
return (int) squareValue; // Cast to return type
}
int main ()
{
int i = 5;
int j = squareIt (i);
printf ("The square of %d is %d\n", i, j);
}
-
We can "tighten" the code in two ways:
int squareIt (int inputInteger)
{
return (inputInteger * inputInteger);
}
int main ()
{
int i = 5;
printf ("The square of %d is %d\n", i, squareIt (i));
}
Exercise 0.17
What happens if the function squareIt follows main?
int main ()
{
int i = 5;
printf ("The square of %d is %d\n", i, squareIt (i));
}
int squareIt (int inputInteger)
{
return (inputInteger * inputInteger);
}
Exercise 0.18
Is it possible for a function to return a value, but that the
value not be used?
int squareIt (int inputInteger)
{
return (inputInteger * inputInteger);
}
int main ()
{
int i = 5;
squareIt (i); // Return value not used.
}