Introduction to C Programming
Basic Structure and Fundamentals
This page shows three examples, in increasing order of complexity, both in the program
itself and the file structure it uses. It ends with details about types, naming variables,
etc.
-
helloworld.c - Hello World program - most basic program with only printing
-
addThree.c - Program that accepts user input and prints output.
-
funcAddThree.c - Program that calls a function to perform calculation.
-
three files - hwx.c, hwx.h, test-hwx.c - Program structure required in this class - three files.
-
Naming rules
Hello World
The basic form of a simple C program is as shown below. ( Line numbers have been added for future reference. )
1/* Filename.c
2 *
3 * This program was written by Ima Programmer on some date
4 * This program does something useful . . .
5 */
6
7 #include <stdlib.h> // For accessing the standard library functions
8 #include <stdio.h> // For standard input and output functions
9
10
11 int main( ) { // every C program begins at main
12
13 printf("Hello world\n"); // this is how we print to the screen
14 return 0; // convention says return a code
15
16 } // main
Explanation of Specific Lines
- The symbols /* and */ enclose a block comment, which may extend over any number of lines, or which may enclose only part of a line. Additional stars at the beginning of the line remind the reader that it is still within a multi-line comment.
- EVERY well-written program should begin with a large block comment specifying the name of the file, the author of the program, when it was written, and a brief description of what the program does and why. In large projects the opening comment may include reference to external documents ( software requirements documentation ), and may include a revision history of who modified the program when and for what purposes.
- The #include statement informs the compiler of what libraries are needed.
- stdlib.h is a header file containing necessary definitions for the use of the standard C library functions. Many systems automatically include this one, but there are exceptions, and it never hurts to include it again, just to be sure.
- stdio.h contains the definitions of standard input and output functions. It is very rare that a C program would not need this header file.
- More advanced programs may need to include other libraries, such as cmath for using trigonometric functions.
- The double slash symbol, //, is a line comment. It indicates a comment that extends to the end of the current line.
- Line 11 says that we are starting a function named main, which is the starting point for all C programs.
- The keyword int says that main returns an integer value as its return type. ( See line 14. )
- The open brace indicates the beginning of a block of code, which must be matched by a closing brace ( on line 16. )
- In this case, main provides no arguments. In other programs you may see the following alternatives:
- int main (void ) { - expressly states that main takes no arguments.
- int main( int argc, char *argv[ ] ) { - Beyond the scope of this introduction.
- int main( int argc, char *argv[ ], char ** envp ) { - Beyond the scope of this introduction.
- "printf" is the standard library function for formatted printing
- A simple text string can be enclosed in double quotes, as shown.
- The \n indicates a new line character. Without this, all the printout would appear on a single line. Multiple \n characters yield blank lines.
- Every function must have a return statement, which causes the function to end and return control to whoever called it.
- Because main was declared to have an integer return type in line 13, this function must return an integer.
- The return value from main is typically interpreted as an error code, with a value of zero indicating successful completion.
- Negative 1 is a commonly used return value used to indicate an unspecified error of some kind.
- It is good practice to comment the closing brace of every function, and any other closing brace that is more than a few lines away from its matching opening brace. This makes it much easier to read more complex programs, which may have MANY sets of nested and consecutive braced blocks.
A Simple Sample:
- This simple program adds three numbers and reports the total.
1 /* addThree.c
2 * This program was written by John Bell in January 2013 for CS 107
3 * This program asks the user for two floating point numbers and
4 * an integer, and reports their total. Note that one of the floating
5 * point numbers is stored as a double precision data type.
6 */
7
8 #include <stdlib.h> // For accessing the standard library
9 #include <stdio.h> // For standard input and output
10
11 int main( )
12 {
13 // Declare variables to be used
14 int number; // The integer
15 float fpNumber = 0.0f; // The floating point number
16 double dpNumber = 0.0, total = 0.0; // The double and the total
17
18 // Explain to the user what the program does
19 printf( "This program adds together two floating point numbers\n" );
20 printf( "and an integer.\n" );
21 printf( "Written January 2009 by John Bell for CS 107.\n\n" );
22
23 // Get user input ( and check it if possible )
24 printf( "Please enter the first floating point number > " );
25 scanf( "%f", &fpNumber );
26
27 printf( "\nPlease enter the second floating point number > " );
28 scanf( "%lf", &dpNumber );
29
30 printf( "\nPlease enter the integer > " );
31 scanf( "%d", &number );
32
33 // Perform necessary calculations
34 total = fpNumber + dpNumber + number;
35
36 // Report results ( in a complete and well-formed format. )
37 printf( "\nThe total of %f plus %f plus %d is %f\n", fpNumber,
38 dpNumber, number, total );
39
40 return 0;
41 } // main
Explanation of Specific Lines
- Line 14 declares that this program uses a variable named "number" that is of type "int".
- All variables in C must be declared befrore they can be used.
- Traditional C compilers requried that all variable declarations be made before any executable statements.
- Most C programmers continue to follow this convention, even though the restriction has been relaxed in modern compilers, and there are sometimes good reasons for declaring variables later on in the program.
- In this example, "number" is not assigned any initial value, so it will start out with an unknown random value. In general, this is bad practice.
- Note the semicolon at the end of the line, which is how C knows that a statement has ended.
- Line 15 declares and initializes a variable named "fpNumber" of type float, the most basic of floating point data types.
- This variable has been given an inital value of 0.0.
- The letter "f" following the 0.0 indicates that this number is to be interepreted to be of type "float", as opposed to the default of "double".
- Line 16 declares and initializes two variables of type "double", a floating-point data type with twice the numerical precision of the data type "float".
- Scientific and engineering programs typically use doubles instead of floats, unless there is a specific reason to do otherwise.
- These variables are also both initialized to zero.
- "printf" is the standard library function for formatted printing
- A simple text string can be enclosed in double quotes, as shown.
- Note \n can be placed anywhere within the string - even at the beginning
- Every well-written program should begin by explaining to the user what the program does.
- Note that because this line has no "\n" at the end, the curser will be left at the end of the line with the question.
- scanf is the standard library function for reading data in from the keyboard.
- The % symbol is a format specifier, and indicates what type of value to read in. %f specifies to read in a float data type.
- Note that the variable name must have an ampersand in front of it in a scanf statement. The exact reason for this will be explained in the course section on pointers.
- The format specifier for a double precison number is %lf", as opposed to %f". ( A double is essentially a "long" float. )
- The format specifier for an integer is "%d". ( "d" stands for "decimal" integer, as opposed to octal or hexadecimal. )
- The equals symbol, =, as used here is an assignment, which takes the value from the right side and stores it in the left side.
- The plus sign, +, peforms addition, and yields the sum of its two arguments.
- Format specifiers for printing numbers are similar to those used when reading them in.
- The first argument to printf when printing numbers is a quoted string, with % format specifiers inserted everywhere that a numerical value is desired.
- The quoted string is followed by a comma-separated list of values ( variables and/or expressions ) to be printed, one per format specifier.
- Note that both the float and the double type use "%f" as their format specifier when printing, as opposed to the "%f" for floats and "%lf" for doubles when scanning.
- Note that the output of the results is a complete sentence, and includes an echoing back of the user's input.
- Note also that a line of code may span over multiple lines in the file. C/C++ only recognizes the semi-colon as the end of a line.
- In your program, you need each line to be on no more than 80 characters. To contine
a single line of code, advance to the next line and tab in farther than the beginning
line of the instruction.
Calling a Function
1 /* functiontemp.c
2 * purpose: Show how to implement, use functions.
3 */
4 #include <stdio.h>
5 #include <stdlib.h>
6
7 /* add three numbers
8 * purpose: adds three numbers
9 * input parameters:
10 * float - first number
11 * double - second number
12 * double - third number
13 * return value:
14 * float - the sum of the three numbers
15 */
16 float add_three(float first, double second, double third)
17 {
18 return first + second + third;
29 }
20
21 int main()
22 {
23 // Declare variables to be used
24 int number; // The integer
25 float fpNumber = 0.0f; // The floating point number
26 double dpNumber = 0.0, total = 0.0; // The double and the total
27
28 // Explain to the user what the program does
29 printf( "This program adds together two floating point numbers\n" );
30 printf( "and an integer.\n" );
31 printf( "Written January 2009 by John Bell for CS 107.\n\n" );
32
33 // Get user input ( and check it if possible )
34 printf( "Please enter the first floating point number > " );
35 scanf( "%f", &fpNumber );
36
37 printf( "\nPlease enter the second floating point number > " );
38 scanf( "%lf", &dpNumber );
39
40 printf( "\nPlease enter the integer > " );
41 scanf( "%d", &number );
42
43 // Perform necessary calculations
44 total = add_three(fpNumber, dpNumber, number);
45
46 // Report results ( in a complete and well-formed format. )
47 printf( "\nThe total of %f plus %f plus %d is %f\n",
48 fpNumber, dpNumber, number, total );
49 // return success
50 return (0);
51
52 }
Explanation of Specific Lines
- Line 16 declares the function. It tells the name of the function and
provides an ordered list of inputs with names and types. The names are what they will
be called within the function.
- Line 18 shows how to return a value. All functions must explicitly return
a single value. If you forget to return, and the function has a return type, then it
return an unknown value.
- Line 44 calls the function.
Splitting Program into Three Files
In C, any program of appreciable size is split into multiple files. Once split,
the smallest number of files is 3. Main is in one file. Functions are in another
file, and the prototypes of the functions are in a third file. For the purposes
of this class, we will have naming conventions for these files. This example
splits the code from the previous example into the three files.
hwx.h - contains comments and prototypes of all functions.
1 #ifndef HWX_H
2 #define HWX_H
3 /* add_three
4 * purpose: adds three numbers
5 * input parameters:
6 * float - first number
7 * double - second number
8 * double - third number
9 * return value:
10 * float - the sum of the three numbers
11 */
12 float add_three(float, double, double);
13 #endif
-
Line 1 contains the first guard. Note the similarity to the file name and the
all capital letters. This says to read what is between this and the #endif only
if HWX_H has not yet been defined. The first time it encounters this line,
HWX_H will not have been defined, so it will be true, and the file will be read.
The purpose is so that when you have large compilations with many files, if the
same .h file is included multiple times, it will only be read by the compiler the
first time. Otherwise, the compiler will think all of the stuff is being defined
multiple times.
-
Line 2 defines HWX_H. This means that next time it encounters the file, the
#ifndef will be false, and the file will be skipped.
-
Lines 3-11 have the function comments
-
Line 12 contains the prototype. It is like the first line of the function
definition except that variable names are not necessary and there is a semicolon
at the end of the line. This is the necessary information for the compiler to
verify that function calls are correct.
-
Line 13 contains the #endif that matches the #ifndef. This signals the end of the
text that will be skipped if #ifndef evaluates to false.
hwx.c - contains function implementations (definitions)
1 /* hwx.c
2 * purpose: Provide functions that will be called from another file.
3 */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include "hwx.h"
7 /* add_three
8 * purpose: adds three numbers
9 * input parameters:
10 * float - first number
11 * double - second number
12 * double - third number
13 * return value:
14 * float - the sum of the three numbers
15 */
16 float add_three(float first, double second, double third)
17 {
18 return first + second + third;
29 }
20
-
Line 6 contains a #include "hwx.h" to read in any declarations that occurred in
the header file. In this particular case, this is not necessary. However, it is
not unusual for data structures to be declared in the .h file, in which case it
would be necessary.
test-hwx.c - this contains main and any testing functions
1 /* test-hwx.c
2 * purpose: Show how to call functions defined in another file.
3 */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include "hwx.h"
7
8 int main()
9 {
10 // Declare variables to be used
11 int number; // The integer
12 float fpNumber = 0.0f; // The floating point number
13 double dpNumber = 0.0, total = 0.0; // The double and the total
14
15 // Explain to the user what the program does
16 printf( "This program adds together two floating point numbers\n" );
17 printf( "and an integer.\n" );
18 printf( "Written January 2009 by John Bell for CS 107.\n\n" );
19
20 // Get user input ( and check it if possible )
21 printf( "Please enter the first floating point number > " );
22 scanf( "%f", &fpNumber );
23
24 printf( "\nPlease enter the second floating point number > " );
25 scanf( "%lf", ∓dpNumber );
26
27 printf( "\nPlease enter the integer > " );
28 scanf( "%d", ∓number );
29
30 // Perform necessary calculations
31 total = add_three(fpNumber, dpNumber, number);
32
33 // Report results ( in a complete and well-formed format. )
34 printf( "\nThe total of %f plus %f plus %d is %f\n", fpNumber,
35 dpNumber, number, total );
36 // return success
37 return (0);
38
39 }
-
Line 6 contains a #include "hwx.h" to read in any declarations that occurred in
the header file. In this particular case, this is not necessary. However, it is
not unusual for data structures to be declared in the .h file, in which case it
would be necessary.
Variables ( Also covered under Data Types )
- A variable is a named storage location, where data may be stored and later changed.
- An identifier is a more general term for a named location, which may contain either data or code.
- Identifiers must begin with a letter or an underscore, preferable letters for user programs.
- The remaining characters must be either alphanumeric or underscores.
- Identifiers may be of any length, but only the first 31 characters are examined in most implementations.
- Identifiers are case sensitive, so "NUMBER", "number", and "Number" are three different identifiers.
- By convention ordinary variables begin with a lower case letter, globals with a Single Capital, and constants in ALL CAPS.
- Multi-word variables may use either underscores or "camel case", such as "new_value" or "newValue".
- Integers are usually assigned variable names beginning with the letters I, J, K, L, M, or N, and floating point variables are usually assigned names beginning with other letters.
- Identifiers may not be the same as reserved words. ( See below for a full list. )
- All variables must be declared before they can be used.
- In K&R C, all variables must be declared before the first executable statement of the program.
- Modern C allows variables to be declared any time before they are used, but it is still normally good practice to declare all variables at the beginning of the program, unless there is a very good reason to do otherwise.
- ( Exceptions: Loop counter variables are often declared as part of the loop structure. Occasionally it is beneficial to declare variables within a reduced scope, to be discussed later. )
- Variables may be given an initial value at the time they are declared. This is called "initialization", or "initializing the variables".
- Initialization in C is done using an equals sign:
- Example: double x1 = 0.0, x2 = 0.0;
- UNINITIALIZED VARIABLES ARE DANGEROUS, AND SHOULD BE CONSIDERED TO HOLD RANDOM VALUES.
- Variables may be declared "const", meaning that their values cannot be changed.
- const variables MUST be initialized at the time they are declared.
- By convention, const variables are named using ALL CAPS.
- Examples:
- const double PI = 3.14159;
- const int MAXROWS = 100;
- Note: K&R C did not have the const keyword, and so the #define pre-processor macro was used to define constant values. The const qualifier is a better approach when it is available, because it allows the compiler to perform type checking among other reasons. For CS 107 we will defer the discussion of #define until we get to the chapter on the pre-processor.
Keywords
The following words are reserved, and may not be used as identifiers:
auto
break
case
char
const
continue
default
do
double
else
|
enum
extern
float
for
goto
if
inline
int
long
register
|
restrict
return
short
signed
sizeof
static
struct
switch
typedef
union
|
unsigned
void
volatile
while
_Bool
_Complex
_Imaginary
|
Naming Conventions
In addition to the variable naming rules imposed by the compiler, there are certain conventions that are commonly followed:
- Ordinary variables normally begin with lower case letters:
int number, nStudents
- Global variables ( to be covered later ) normally begin with a single capital letter:
double Coordinate, Salary;
- Defined constants normally are in all upper case:
const double PI = 3.14159;
const int MAXROWS = 100;
- Variable names consisting of more than one word typically capitalize successive words. This is known as "camel case":
double totalOld, totalNew, sumOfAllDigits;
- Alternatively, where camel case is awkward or undesired, underscores may be used to indicate the start of words:
double totalOfX_coordinates, total_of_Y_coordinates
- Integer numbers typically begin with letters I, J, K, L, M, or N. ( Remeber the first two letters in INteger. )
- Floating point numbers typically begin with other letters:
int nStudents; // Not just students
double average, total, standardDeviation;
- In any case, variable names should be meaningful and easily understood. ( Think complete words, not just letters, and make sure the words are meaningful and not just temp1, temp2, temp3, etc. )
- Single letters may only be used for the counter of a loop (as we will see later).