C was not written as a teaching aid, but as a professional tool. Programmers love C because it is a standard, widely-used language, and a single C program can often be made to run on many different kinds of computer.
Ref: The GNU C Programming Tutorial, Edition 4.1
C Program Structure
The basic building block of a C program is the function. Every C program is a collection of one or more functions. Functions are made of variable declarations and statements, or complex commands, and are surrounded by curly brackets ( `{' and `}' ).
One and only one of the functions in a program must have the name main. This function is always the starting point of a C program, so the simplest C program is a single function definition:
main ()
{
}
The parentheses `()' that follow the name of the function must be included. This is how C distinguishes functions from ordinary variables.
The function main does not need to be at the top of a program, so a C program does not necessarily start at line 1, but wherever the function called main is located. The function main cannot be called, or started, by any other function in the program. Only the operating system can call main; this is how a C program is started.
The C language provides us a standard program structure to start coding at zero level.
//include section
main()
{
//No tasks, no output
}
C language is a procedural oriented programming language, it means it is made of procedures or sub routines or popularly called as functions. The main() is one such function at zero level of the any c source code program. The entry-level function, main() is used as driver function and containing source file is called as main.c for easy identification.
The C programs have only one entry at level 0 and one/many exit points throughout its code. The above basic code do nothing as its code area is empty (contains only comment).
There are two standards in C programs: K&R C and ANSI C. As per ANSI C standard program must return exit or return status to shell or OS kernel or calling program.
//include section
#include <stdio.h>
int main()
{
//No tasks, no output
return(0);
}
Now the basic c program returns 0 or SUCCESS_EXIT as exit/return status. For that one more function return() is used and it is defined in stdio.h header file. So at include section we are adding stdio.h file, which is at compiler reach and hence quoted between <>. If program exit with error, error code can be returned so that called function, here it is shell, can display error message ‘Error Code: execution is aborted for…reason’.
Third, the semicolon is vital; every simple statement in C ends with one. This is a signal to the compiler that the end of a statement has been reached and that anything that follows is part of another statement. This signal helps the compiler diagnose errors.
Passing Arguments/info through command line to a program
So far, all the programs we have written can be run with a single command. For example, if we compile an executable called `main.exe', we can run it from within the same directory with the following command at the GNU/Linux command line:
$ ./main.exe
Hello World!
$
However, what if you want to pass information from the command line to the program you are running? Consider a more complex program like GCC.
Command-line arguments are very useful. After all, C functions wouldn't be very useful if you couldn't ever pass arguments to them | adding the ability to pass arguments to programs makes them that much more useful. In fact, all the arguments you pass on the command line end up as arguments to the main function in your program.
//include section
#include <stdio.h>
int main(int argc, char *argv[])
{
//add code later
return(0);
}
As you can see, main now has arguments. The name of the variable argc stands for
\argument count"; argc contains the number of arguments passed to the program. The name of the variable argv stands for \argument vector". A vector is a one-dimensional array, and argv is a one-dimensional array of strings. Each string is one of the arguments that was passed to the program.
For example, the command line
gcc -o main.exe main.c
would result in the following values internal to GCC:
argc 4
argv[0] `gcc'
argv[1] `-o'
argv[2] ` main.exe '
argv[3] ` main.c
As you can see, the first argument (argv[0]) is the name by which the program was called, in this case `gcc'. Thus, there will always be at least one argument to a program, and argc will always be at least 1.
Environment variables, sometimes called shell variables, are usually set with the export command in the shell. (This section assumes you are using the GNU Bash shell.) Standard environment variables are used for information about your home directory, terminal type, and so on; you can define additional variables for other purposes. The set of all environment variables that have values is collectively known as the environment.
Notice that envp is an array of strings, just as argv is. It consists of a list of the environment variables of your shell, in the following format:
NAME=value
Just as you can manually process command-line options from argv, so can you manually process environment variables from envp. However, the simplest way to access the value of an environment variable is with the getenv function, defined in the system header `stdlib.h'. It takes a single argument, a string containing the name of the variable whose value you wish to discover. It returns that value or a null pointer if the variable is not defined.
Below is the program add.c which accepts user arguments at the time of invoking, so use shell prompt to call it. First compile add.c and get add.exe as output file, next call ./add.exe on command prompt with some arguments.
//add.c
//compiling note: gcc -o add add.c
#include <stdio.h>
#include <stdlib.h>
// Print command-line arguments to stdout.
int main (int argc, char *argv[], char *envp[])
{
int i, total=0;
char *host;
host = getenv("HOSTNAME");
if ( argc < 2) {
printf("Usage: ./add.exe add arguments with space...%s",host);
exit(0);
}
printf("Command : %s \t", argv[0]);
printf("Arguments passed: %d Nos \n", argc-1);
printf("Host Name: %s \n", host);
return(0);
}
The call steps of above add.c program with some outputs is like this:
$ ./add.exe
Usage: ./add.exe add arguments with space...UserLoginName
$ ./add.exe one two three
Command : add.exe Arguments passed: 3 Nos
Host Name: UserLoginName
$
Think like a programmer
C programmed using functions. Take the task break it into manageable, effective modules and cover/encapsulate them inside functions and call them as you wish in main program. This is call as modularising. Then make them generic so that code or functions can be reuse in other programs or elsewhere. By this step program become more robust, feature-n-future ready, well documented, portable and easily allowable for expansion.
Task: A client is having Computer controlled wireless robot, which moves in his 1kbh house or single kitchen-bedroom-hall house. Robot does two things: it moves to three specific locations of the house-Switch Boards of Kitchen, Bed room and hall; and it switches On/Off-Fan or Lights of in-front Switch Board [which are short range devices and controlled too wirelessly].
Now write a prototype program in c language, which sits on client/user computer and allows him to move robot to his desired location with key strokes and carry on the required switching action easily. Since Robot is not available for programmer only print actions are accepted. It teaches how hardware interface programmes are devised and implemented effectively.
Given: Commands list
Command | Does this |
moveR() | Gives current location |
moveR(21) | Robots moves to location 21 |
moveR(23) | Robots moves to location 23 |
moveR(25) | Robots moves to location 25 |
Following is the program called thinklikepgmer.c.
#include <stdio.h>
#include <stdlib.h>
void GetUserData();
void MoveTowards();
void OperateDevice();
int Destination_Location, Current_Location, Device_Operation, Device, Current_Status;
int main()
{
top:
Current_Status = 0;
printf("*********Wel-come to Program***********\n");
printf("Press \t 1-to set Task \t 0-to exit \n");
scanf("%d",&Current_Status);
if (Current_Status == 0 )
exit(0);
if (Current_Status == 1 )
{
GetUserData();
MoveTowards();
OperateDevice() ;
if (Current_Status == 1)
printf("Task: Accomplished!\n");
else
printf("Task: Error in operation, call help!!!\n");
}
printf("\n");
goto top;
}
//User-defined function definitions
void GetUserData()
{
printf("Set Task:\n");
printf("Enter Device: 10-for light 11-for fan\n");
scanf("%d",&Device );
printf("Enter Device Operation: 1-for ON 0-for OFF\n");
scanf("%d",&Device_Operation );
printf("Enter Destination Location: \n \
21-for Kitchen_SwitchBoard\n \
23-for Bedroom_SwitchBoard\n \
25-for Hall_SwitchBoard\n");
scanf("%d",&Destination_Location );
printf("Task: recorded\n");
}
void MoveTowards()
{
//Current_Location = moveR();
/*we manually set it at run time, as robot module is not available in this prototype program*/
printf("Enter Current Location , 21 or 23 or 25 any one: ");
scanf("%d", &Current_Location);
printf(" Current Location = %d, Destination Location = %d\n", Current_Location, Destination_Location);
printf(" Moving Towards Destination Location =%d\n", Destination_Location);
up:
//Current_Location = moveR(Destination_Location);
/*Above robot module code is not available for prototype program, so commenting*/
printf("Enter Present Location, 21 or 23 or 25 any one: ");
scanf("%d", &Current_Location);
if(Current_Location ==Destination_Location )
{
printf("I'm at Destination Location\n");
Current_Status = 1;
}
else
{
printf("Robot moving, wait!!!\n");
Current_Status = 0;
goto up;
}
}
void OperateDevice()
{
if(Current_Status == 1 )
{
printf("I'm doing opertion, Device %d = %d \n",Device,Device_Operation );
Current_Status = 1;
}
else
{
printf("Error doing operation, call help!!!\n");
Current_Status = 0;
}
}
Compile above program and get binary file and run it on terminal. The call steps of with some outputs are like this:
$ ./ thinklikepgmer.exe
*********Wel-come to Program***********
Press 1-to set Task 0-to exit
1
Set Task:
Enter Device: 10-for light 11-for fan
10
Enter Device Operation: 1-for ON 0-for OFF
1
Enter Destination Location:
21-for Kitchen_SwitchBoard
23-for Bedroom_SwitchBoard
25-for Hall_SwitchBoard
21
Task: recorded
Enter Current Location , 21 or 23 or 25 any one: 23
Current Location = 23, Destination Location = 21
Moving Towards Destination Location =21
Enter Present Location, 21 or 23 or 25 any one: 25
Robot moving, wait!!!
Enter Present Location, 21 or 23 or 25 any one: 21
I'm at Destination Location
I'm doing opertion, Device 10 = 1
Task: Accomplished!
*********Wel-come to Program***********
Press 1-to set Task 0-to exit
0
$
C is Procedure-oriented Programming Language, in this approach the problem is viewed as a sequence of things to be done such as reading, calculating and printing. A number of functions are written to accomplish these tasks. The primary focus is on functions. Here functions are action-oriented and do not correspond to the elements of the problem. Most of the functions share global data. Employs top-down approach in program design. So apply these remarks to above example program. Just study it!
Modularising Program
C programmed using functions. It encourages code-reuse by implementing effective function write from basic code implementation while programming any application.
Below is the one session where simple addition processes is extracted from main function and implemented in separate code file for code reuse later in any other programs.
Note that main() is entry-level function hence keep it simple and basic. And take-out specific tasks and form them functions and call them in the body whenever needed. By this code looks tidy and readable, documentable, manageable and debug gable for any error easily.
The session needs only typing and emphasis is on modularising and not on understanding the elements used in while writing code. The main.c program add two given integers and prints the result to screen. Compile the main.c program and get binary file and run it on terminal.
main: (+)maths_operation assign_task print_task |
#include <stdio.h>
main()
{
int i;
i = 3 + 3;
printf("result of 3+3 = %d\n",i);
}
output:
result of 3+3 = 6
Since program contains mathematics operation take it out from main() function. The separate add() function is defined at include section of the main.c program. Then the return value of add() function is given to result variable of main() function, which in turn prints it on screen for user. Compile the main.c program and get binary file and run it on terminal.
#include <stdio.h>
add: (+)maths_operation main: assign_task print_task |
single file code with add function |
int add(int x, int y)
{
return(x+y);
}
main()
{
int i;
i = add(3,3);
printf("result of 3+3 = %d\n",i);
}
output:
result of 3+3 = 6
Now we create one header or include file and move-out add() function to it. By this main() function and main.c file looks more cleaner, and readable. The add.h header file is added to main.c file at include section. The add.h file is in the same directory where main.c file is present, so quoted in between “ “ marks. Compile the main.c program and get binary file and run it on terminal.
Two files code with add.h include file | main: assign_task print_task | |
main.c | add.h |
#include <stdio.h> #include "add.h" main() { int i; i = add(3,3); printf("result of 3+3 = %d\n",i); } | int add(int x, int y) { return(x+y); } |
output:
result of 3+3 = 6
From the above two code files: main.c source file and add.h include file nothing changes at output, it still shows result as single source file was previously showing. User can use his add.h include file in another program wherever he needs it. He can change the implementation details of addition too without affecting main source file.
By following previous step, user can add subtraction function to main.c source file very easily. Just create sub.h file implement the math process and add it to main.c file where it is called.
Note that now main.c source file calls two include files add.h and sub.h. Compile the main.c program and get binary file and run it on terminal.
Three files code with add.h & sub.h include file | main: assign_task print_task assign_task print_task | |
main.c | add.h |
#include <stdio.h> #include "add.h" #include "sub.h" main() { int i; i = add(3,3); printf("result of 3+3 = %d\n",i); i = sub(3,3); printf("result of 3-3 = %d\n",i); } | int add(int x, int y) { return(x+y); } |
sub.h |
int sub(int x, int y) { return(x-y); } |
output:
result of 3+3 = 6
result of 3-3 = 0
It is programmer job tell what his program does to its user. So devising menu [in a separate source file] and calling it in main.c file when they are necessary is quite essential.
Note that include files usually contains only declaration of variables, constants and functions. In our case single line functions were defined in their respective include files. But source file such as menu.c is created when implementation details are to be written in it.
Now include menu.c and other two header files to main.c program file. Compile the main.c program and get binary file and run it on terminal.
Four files code with 2-include files & 1-source file | main: menu_lead assign_task print_task assign_task print_task menu_trail | |
main.c | add.h |
#include <stdio.h> #include "menu.c" #include "add.h" #include "sub.h" main() { int i; menu_lead(); i = add(3,3); printf("result of 3+3 = %d\n",i); i = sub(3,3); printf("result of 3-3 = %d\n",i); menu_trail(); } | int add(int x, int y) { return(x+y); } |
sub.h |
int sub(int x, int y) { return(x-y); } |
menu.c | |
void menu_lead() { printf("==Maths Operation Program==\n"); printf("-----------------------------\n"); } void menu_trail() { printf("-----------------------------\n"); } |
| | |
output:
==Maths Operation Program==
-----------------------------
result of 3+3 = 6
result of 3-3 = 0
-----------------------------