int main () { ...It turns out that main can also accept some parameters. The first parameter is an integer, usually called argc, that tells how many command line arguments there are, including the command itself. The command line arguments describe what the Unix command line looked like when the program was executed. The second argument to main, usually called argv, is an array of strings. A string is just an array of characters, so argv is an array of arrays. There are standard C functions that manipulate strings, so it's not too important to understand the details of argv, as long as you see a few examples of using it.
#include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int i; for (i=0; i<argc; i++) printf ("%s\n", argv[i]); exit (0); }Let's call this program foo, so we would compile it with
cc -o foo foo.cIf the user simply executes it like this:
./foothen the output would be
fooargc would be 1, and argv[0] would be the string "foo". If the user types
./foo 1 2 3 hellothen the output would be
foo 1 2 3 helloargc would be 5.
Suppose we want to write a program that accepts two command line arguments and prints their sums:
#include <stdio.h> #include <stdlib.h> int main (int argc, char *argv[]) { int a, b; if (argc != 3) { fprintf (stderr, "wrong number of arguments!\n"); exit (1); } a = atoi (argv[1]); b = atoi (argv[2]); printf ("%i\n", a + b); exit (0); }The two calls to atoi convert the strings argv[1] and argv[2] to integers. atoi stands for "ASCII to integer."
#include <stdio.h> #include <stdlib.h> #define MAX_STUDENTS 100 int main () { int nstudents, i; float grades[MAX_STUDENTS], sum, avg; nstudents = 0; /* loop, filling the array with values from scanf */ for (;;) { scanf ("%f", &grades[nstudents]); if (feof (stdin)) break; nstudents++; /* too many? complain and exit */ if (nstudents > MAX_STUDENTS) { fprintf (stderr, "too many students!\n"); exit (1); } } /* nothing on stdin? complain and exit. */ if (nstudents == 0) { fprintf (stderr, "not enough students!\n"); exit (1); } /* find average of grades in array */ sum = 0.0; for (i=0; i<nstudents; i++) sum += grades[i]; avg = sum / nstudents; /* go through printing grades that are above average */ for (i=0; i<nstudents; i++) if (grades[i] > avg) printf ("%f\n", grades[i]); exit (0); }
float find_average (float v[], int n) { int i; float sum; for (i=0,sum=0.0; i<n; i++) sum += v[i]; return sum / n; }Because of some weird things going on behind the scenes (trust me, you don't want to know), arrays passed to functions are not passed by value; if an array element is changed in the function, it remains changed in the original array. This makes things more efficient since a new copy of the array doesn't have to be made, but you have to be careful not to change the contents of an array in a function unless you really mean it. Usually this isn't a problem; in fact, it often comes in handy. The following function will initialize the first n elements of an integer array to 0:
void initialize_to_zero (int w[], int n) { int i; for (i=0; i<n; i++) w[i] = 0; }This way, you can initialize lots of different arrays without having to write lots of different for loops.