Lesson 1: The very basics of C-programming
Purpose: | Introduce the C programming language. |
Contents: |
1. Compile and run a C program. 2. Basic components of C programs. |
References: | C Programming in wikibooks and/or C tutorial in tutorialspoint. |
Estimated time | 15 min - 2 hours depending on your earlier experiences. |
Before you start
The minimal requirements for programming in C are
- an editor which is used to enter and edit the program text and
- a C compiler which is used to translate the C-program to something the hardware can execute.
We recommend that you use the Linux computers at the IT-department for this lesson. That system has a couple of editors available like gedit, emacs, vi and vim. Choose whatever you like.
It is also possible to use an integrated environment like eclipse but it takes longer time get going unless you are already familiar with it.
It is of course also possible to use your own computer but you will probably have to install some software (e g xCode on a Mac and Cygwin or MinGW on a Windows system. See https://www.tutorialspoint.com/cprogramming/c_environment_setup.htm for instructions.
The first program
-
Start your editor and enter the following code
// A classic starter #include <stdio.h> int main() { printf("Hello world!\n"); return 0; }(This famous first program comes from "The C Programming Language" which is the standard textbook by Brian Kernighan and Dennis Ritchie published 1978. It has been widely used in many textbooks in most programming languages since then.)
-
Save the program under the name
hello.c
. -
Open a terminal window and give the command
gcc -o hello hello.c
. This command will translate the C-code to a machine code. The machine code is saved in a namedhello
. - If you get any error message you have probably done some mistyping. Correct the error and try again.
-
Now you can run the program just by giving it its name (
hello
as a command the terminal window. You may have to put a./
in front of the name depending on how your environment is set up.The terminal window should now contain something like this (after the listing of files and the contents of
hello.c
):vranx$ vranx$ ls -l -rwxr-xr-x 1 tom it 7664 Oct 19 13:06 hello* -rw-r--r-- 1 tom it 79 Oct 17 20:44 hello.c vranx$ cat hello.c // A classic starter #include <stdio.h> int main() { printf("Hello world!\n"); return 0; } vranx$ gcc -o hello hello.c vranx$ ./hello Hello world! vranx$
The option "-o hello
" on the gcc
-command specifies the name of the file
containing the executable code.
You can choose any name you want. You can actually leave out that option in which case the result will be stored in the file a.out
. Try that and run the result!
Each time you make any changes to the program ("the source code") you have save it and recompile before you run it.
Details in the program
Construct | Explanation |
---|---|
// A classic starter | This line is a comment which does not influence the function at all. A comment starts with double slash and goes to the end of the line. |
#include <stdio.h> |
Lines starting with the # -sign are instructions to a preprocessor.This particular statement says that a file containing definitions for the standard input/output library should be included. |
int main() { |
This line defines the beginning of a function named main .
The function has no parameters (indicated by the empty pair of parentheses () )
and returns a value of integer type.The particular name main has a special meaning: it defines
the starting point for the execution.
|
printf("Hello world!\n"); |
This is the first statement that really does something:
It calls the function printf
which sends the text string "Hello world\n" to the standard output.
As seen, strings are enclosed by quotation marks (" ) but these are not shown in the output.The printf -function works very similarly to the print -command in Python.
The main difference is the syntax.Statements are ended by semicolons ( ; ).
|
return 0; |
Since we declared above that main shall return an integer value we
should do that using a return -statement.
|
} |
This curly bracket marks the end of main . It matches the forward bracket at the end of
the function statement above.Unlike Python, indentation has no semantic meaning in C - the structure is marked by pairs of curly brackets. However, indentation is an important way to make the program structure clear for the human eye so use it! All good editors support indentation according to the language in use. |
Errors
It is inevitable that we make errors in the programming process. The compiler can discover errors like forgotten semicolons, misspelled names, forgotten declarations etc. The error messages from the compiler are usually (but not always) easy to understand.
Make some changes to the program above like remove a semicolon, remove one of the curly brackets, misspell the printf-function and see what the compiler says. It is important to really read the messages and try to understand what the meaning is!
Unfortunately, the compiler cannot discover all possible errors in a program and, as you will see, it may be much more difficult to find those other errors.
Examples
Here follows a series of annotated programs showing the basic constructs in C. Try them out and make minor modifications!Example 1: Iteration
Code | Explanation |
---|---|
/* squares.c This program writes a table over squares of the numbers 1, 2, ... 10 */ |
This is a way of writing comments that stretches over
several lines. It starts with /*
and ends with */
|
#include <stdio.h> int main() { | |
int i = 1; | Declares a variable of integer type and gives it a value. |
while (i <= 10) { | An iteration construction. Note that the condition has to be enclosed in parentheses! |
printf("%d \t %d \n", i, i*i); |
Sends the value of i and i*i to standard output.
The %d says that they are to be handled as integers
|
i = i + 1; |
Increases the value of i by 1.
|
} return 0; } |
Link to the source code. Copy it and try it out!
Example 2
This example demonstrates-
a program with two functions:
main
andfactorial
, -
the
for
-statement which is another iteration statement and -
the
++
- and--
-operators.
Code | Explanation |
---|---|
/* factorial.c Program that tabulates the factorial function */ #include <stdio.h> | |
int factorial(int n) { | Starts the definition of a function with one parameter of integer type and a return value also of integer type. |
int result = 1; while (n > 0) { result = result*n; | |
n--; |
Decreases the value of n with one.
A shorthand for n = n - 1 .
|
} return result; } | The iteration ends and the computed value is returned. |
int main() { |
Start of main as before. |
for (int i = 0; i<=10; i++) { |
Will repeat the following block with the values 0, 1, 2 , ... 10
on the variable i .
|
printf( "%2d %15d \n", i, factorial(i)); | The contents of the iteration. Notice the call to the factorial function. |
} | The end of the repeated block. |
return 0; } | The end of the main function as before. |
Exercises
- Copy the program from this link. Compile and run it.
-
Rewrite the
while
-statement in the factorial function as afor
-statement. -
Rewrite the
for
-statement inmain
as awhile
-statement. - What happens if you try to compute factorials up to 50 instead of 10? Explain!
-
Change the order of the function definitions, i.e. put the
main
-function before thefactorial
function. What happens when you compile? What happens when you run the program?
Example 3
This example demonstrates-
the
if
-statement and - a recursive function.
Code | Explanation |
---|---|
int factorial(int n) { if (n == 0) { return 1; } else { return n*factorial(n-1); } } |
A conditional statement. The condition has to be enclosed by parentheses.
Note how the function calls itself with a smaller argument. |
Exercises
-
Exchange the original iterative definition of
factorial
with this recursive definition. Compile, rerun and check that it works. -
Check what happens if you call this
factorial
with a negative argument!
Rewrite the code so you get an error message if factorial is called with a negative argument!
Notes on data types
The concept of data types is very important in C as well as in many other compiled language. So far we have only been working withint
type which, of course, stands for integer.
Integer types
There are several integer types.
The most common are
char
, short
, int
and long
.
The main difference is the amount of storage they occupy.
A char
usually takes one byte of memory and a long
at least 4 bytes.
We will mainly use int
for integer values.
The integer arithmetic is exact as long as you stay within the underlying hardwares restrictions.
Floating point types
The floating point can represent decimal numbers.
The most common types are float
(usually 4 bytes)
and double
(usually 8 bytes)
Floating point constants are written with a decimal point and/or
an exponent.
Examples: 1.0
, -0.25
, 1.0e3
, 1E-10
.
They will all be of type double
.
If you want to specify a constant of type float
you have to
append the letter f
.
Examples: 0.1f
, 1e-10f
.
Mixed mode arithmetic
If both the operands in an arithmetic operation are of integer type, the result will be
of integer type. If at least one of the operands is of floating point type,
the result will be of floating point type.
Example: 7/2
will be 3
while 7.0/2
will
be 3.5
.
(Note that the "slash" (/
) is used for both integer and floating point division
unlike some other languages.)
You can explicitly enforce conversion between types using a type cast operator. They are written as type name enclosed by parentheses.
Some examples:
The char
data type
As mentioned above a char
is an integer.
Character constants are enclosed by apostrophes.
Examples: 'a'
, '.'
, '1'
, '+'
.
Some special character constants have to be preceded by
a \
called the escape character.
Examples: '\''
for apostrophe and '\n'
for line break.
Since the char
is an integer type it is possible
to use them in arithmetic.
Examples:
Copy this program, compile, run and check the printouts!
The library ctype
contains functions for character handling.
The unix command man ctype
will list them.
Use
#include <ctype.h>
to use them!
Example 4
This example demonstrates reading and writing of characters.Code | Explanation |
---|---|
/* cat.c Copy standard input to standard output. */ #include <stdio.h> int main() { | |
int c; c = getchar(); |
Declares a variable and reads one character from standard input.
Note that we are using the type int for storing the
result from getchar .
|
while (c != EOF) { |
EOF is a predefined integer constant which can be retuned by getchar .
It indicates that no more characters are available.
|
putchar(c); c = getchar(); |
Sends the read character to standard output and reads the next. |
} return 0; } |
Exercises
-
Copy the program and save it under the name
cat.c
. Compile it and give executable code the namecat
. (It is actually a simple variant of the unix-commandcat
.) -
Check that it works using the command
./cat < cat.c
. It should produce a listing of its own source code. (If you remove the./
part you should get the same result produced by the unix command.) -
Modify the program so it counts number of copied characters and the number of lines
and prints these values at the end.
Hint: The
getchar
function returns the'\n'
at the end of a line i.e.if (c == '\n') ...
can be used to handle end of lines.
Example 5
In a previous example we demonstrated how single characters could be read using the functiongetchar
.
This example demonstrates how numbers can be read.
Code | Explanation |
---|---|
/* sum.c Reads and sums positive numbers. Ends when a non positive number is read. */ #include <stdio.h> int main() { double sum = 0; int n = 0; float x; | |
scanf("%f", &x); |
The function scanf is used to read values from standard input.
The string given as the first parameter contains information about
what type of values that should be read.
The %f indicates a float value.
The second parameter (&x ) is the address
to the variable x and thus telling C where to
store the read value.
|
while (x > 0) { n++; sum += x; scanf("%f", &x); } | Count, sum and read again. |
printf("Numbers read : %3d\n", n); printf("Sum of numbers: %5.2f\n", sum); return 0; } | Print the answers and leave. |
Exercises
- Copy the code and run the program and find out what you can have between the numbers (one or more blanks, line breaks, commas, ...?)
-
Rewrite the program so it sums integers instead of floats.
What happens if you enter a decimal number instead of an integer?
What happens if you keep
%f
inscanf
instead of changing it to%d
for reading integers? Ignore the compiler warning and run the program!
Logical values
The original C did not include a boolean (logical) data type.
Any scalar data type (integer, floating point, pointer) can be used.
The value 0 is considered as false
while all other values
are regarded as true
.
The standard inclusion file stdbool.h
defines the
bool
as a type and the constants true
and false
.
In the C99-standard the somewhat strange datatype _Bool
was introduced.
A lot of C programmers continue to use the traditional way regarding 0
(or NULL
) as false and all other values as true.
For example, an infinite loop can be written:
Example 6
This example demonstrates some new operators and the use ofbool
type.
Code | Explanation |
---|---|
#include <stdio.h> #include <math.h> #include <stdbool.h> |
We include math.h because we want to use the mathematical
function sqrt and stdbool.h because we want to
use bool , true and false .
|
bool isPrime(int n) { for (int i=2; i<=sqrt(n); i++) { if (n%i == 0) { return false; } } return true; } |
It is enough to check the divisibility up to the square root of n. The % -sign is the remainder (modulus) operator.
|
Note that the function could just as well be written without the bool
-constructs:
Exercises
-
Copy the code
and write a
main
function that checks if it works. -
Write and test a function
isTwinPrime(int n)
that checks if bothn
andn+2
are primes.
Go to next lesson.
Dölj style3dev.css för att bli av med annoteringarna!