#include <stdio.h> int main() { printf("hello world\n"); }
Suppose the above program were in a file called myhello.c
cc -o myhello myhello.c
would create a file called myhello.
You could run the program just by invoking its name:
pandora# myhello hello world pandora#
To run this just execute:
lint sourcefilename.c
For example:
lint myhello.c produces output like the following:
pandora% lint myhello.c (5) warning: Function has no return statement : main function falls off bottom without returning value (5) main function returns value which is always ignored printf pandora%Comments about the lint output:
#include <stdio.h> int main() { printf("hello world\n"); return 0; }We can run lint on this:
pandora% lint myhello.c function returns value which is always ignored printf pandora%
It may not seem to useful at this point, but when your programs become more complicated, you will want to use it.
In this course, you must use it!
Only the very simplest aspects of the make utility will be discussed here.
When you execute make, it looks for a file called makefile in the current directory. This makefile is a description file which described the dependency relationships that exist between various program modules.
The dependencies have the following form:
target: components TAB ruleThe first line is called a dependency and the second line is called a rule. Rule lines must start with a tab character. There may be more than one rule line for each dependency.
The rules are invoked if any of the components are newer than the target, or if the target does not exist. Here is a simple makefile for myhello
myhello: myhello.c cc -o myhello myhello.cIf myhello does not exist, then running make will compile myhello.c
pandora% make cc -o myhello myhello.c pandora%If we do it again:
pandora% make `myhello' is up to date. pandora%By default, make will look only at the first target in the makefile. If you give it an argument, it will look at the corresponding target.
Consider the following makefile:
myhello: myhello.c cc -o myhello myhello.c lint: lint myhello.cNow typing make will do the same thing as before, but typing
pandora% rm myhello pandora% make cc -o myhello myhello.c pandora% make lint lint myhello.c function returns value which is always ignored printf pandora% make `myhello' is up to date. pandora%Sometimes you want to remove the executable and start again.
myhello: myhello.c cc -o myhello myhello.c lint: lint myhello.c clean: rm myhelloNow we can run make some more:
pandora% ls -la total 8 drwxr-xr-x 2 srobbins staff 512 Aug 30 15:38 . drwxr-xr-x 4 srobbins staff 512 Aug 30 15:25 .. -rw-r--r-- 1 srobbins staff 89 Aug 30 15:36 makefile -rw-r--r-- 1 srobbins staff 76 Aug 30 15:25 myhello.c pandora% make cc -o myhello myhello.c pandora% make `myhello' is up to date. pandora% ls -la total 22 drwxr-xr-x 2 srobbins staff 512 Aug 30 15:38 . drwxr-xr-x 4 srobbins staff 512 Aug 30 15:25 .. -rw-r--r-- 1 srobbins staff 89 Aug 30 15:36 makefile -rwxr-xr-x 1 srobbins staff 6212 Aug 30 15:38 myhello -rw-r--r-- 1 srobbins staff 76 Aug 30 15:25 myhello.c pandora% make clean rm myhello pandora% ls -la total 8 drwxr-xr-x 2 srobbins staff 512 Aug 30 15:38 . drwxr-xr-x 4 srobbins staff 512 Aug 30 15:25 .. -rw-r--r-- 1 srobbins staff 89 Aug 30 15:36 makefile -rw-r--r-- 1 srobbins staff 76 Aug 30 15:25 myhello.c pandora% make cc -o myhello myhello.c pandora%
In C
The first line creates myhello.o and the second line creates myhello from myhello.o.
If you have several functions, you can put some of them in another file and compile them separately.
void initializeSieve(int primeList[], int primeListSize);
    fill the array primeList of size
printListSize with 1's
void makeSieveOne(int primeList[], int primeListSize, int prime);
    set the multiples of prime to 0.
void makeSieve(int primeList[], int primeListSize);
    set the multiples of all primes to 0.
void printSieve(int primeList[], int primeListSize);
    print out the array (for debugging)
void printPrimes(int primeList[], int primeListSize);
    print out the primes assuming the array has been made
We will put these in a file called sieve.c.
Notice that the first two of these will be called by makeSieve
and do not have to be accessible outside the file.
In Java we declare these private.
In C we do something similar by declaring them to be static.
This means that they are not accessible outside the file and their names
do not appear in the sieve.o file.
We create a separate file called sievemain.c which contains the main program.
#include <stdio.h> #include "sieve.h" #define SIZE 2000 int main() { int myList[SIZE]; int myListSize; printf("This program was written by Steven Robbins\n"); myListSize = SIZE; makeSieve(myList,myListSize); printSieve(myList,myListSize); printPrimes(myList,myListSize); return 0; }
void makeSieve(int primeList[], int primeListSize); void printSieve(int primeList[], int primeListSize); void printPrimes(int primeList[], int primeListSize);Here is a makefile for this program:
all: sieve.o sievemain sieve.o: sieve.c cc -c sieve.c sievemain: sieve.h sieve.o sievemain.c cc -o sievemain sievemain.c sieve.o lint: lint sievemain.c sieve.c run: sievemain clean: rm -f sievemain *.o
#include <stdio.h> static void initializeSieve(int primeList[], int primeListSize) { int i; primeList[0] = 0; primeList[1] = 0; for (i=2;i<primeListSize;i++) primeList[i] = 1; } static void makeSieveOne(int primeList[], int primeListSize, int prime) { int i; for (i=2*prime;i<primeListSize;i=i+prime) primeList[i] = 0; } void makeSieve(int primeList[], int primeListSize) { int i; initializeSieve(primeList,primeListSize); for (i=2;i*i<primeListSize;i++) if (primeList[i] == 1) makeSieveOne(primeList,primeListSize,i); } void printSieve(int primeList[], int primeListSize) { int i; printf("Sieve follows:"); for (i=0;i<primeListSize;i++) { if (i%25 == 0) printf("\n"); printf("%d ",primeList[i]); } printf("\n"); } void printPrimes(int primeList[], int primeListSize) { int i; int count; count = 0; printf("Primes follow:"); for (i=0;i<primeListSize;i++) { if (primeList[i] == 1) { if (count%10 == 0) printf("\n"); printf("%6d ",i); count++; } } printf("\n"); }Running the program gives the following output:
0 0 1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 1 Primes follow: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997 1009 1013 1019 1021 1031 1033 1039 1049 1051 1061 1063 1069 1087 1091 1093 1097 1103 1109 1117 1123 1129 1151 1153 1163 1171 1181 1187 1193 1201 1213 1217 1223 1229 1231 1237 1249 1259 1277 1279 1283 1289 1291 1297 1301 1303 1307 1319 1321 1327 1361 1367 1373 1381 1399 1409 1423 1427 1429 1433 1439 1447 1451 1453 1459 1471 1481 1483 1487 1489 1493 1499 1511 1523 1531 1543 1549 1553 1559 1567 1571 1579 1583 1597 1601 1607 1609 1613 1619 1621 1627 1637 1657 1663 1667 1669 1693 1697 1699 1709 1721 1723 1733 1741 1747 1753 1759 1777 1783 1787 1789 1801 1811 1823 1831 1847 1861 1867 1871 1873 1877 1879 1889 1901 1907 1913 1931 1933 1949 1951 1973 1979 1987 1993 1997 1999We can check some of these:
pandora% factor 1999 1999 1999 pandora% factor 1621 1621 1621 pandora% factor 1623 1623 3 541 pandora% factor 12345678901234 12345678901234 2 7 73 12079920647 pandora%The last one was just for fun.
printf takes one or more arguments. The first argument is a string, usually a constant string in quotes. The additional arguments are values to output.
int a,b,c; double r,s; char w; a = 1; b = 2; c = 3001; r = 2.0/3; s = 5.01; w = 'X'; printf("a is %d, b is %8d, c is %2d, r is %6.2f, s is %6.4f and w is %c\n", a,b,c,r,s,w);Produces the output:
a is 1, b is 2, c is 3001, r is 0.67, s is 5.0100 and w is X
incorrect:
for (int i=0;i<10;i++) printf("i=%d\n",i);correct:
int i; for (i=0;i<10;i++) printf("i=%d\n",i);
In C you would use:
#define MAX 1000
This is handled by the preprocessor which replaces all occurrences of MAX with 1000.
This constant is only available in the file in which it is defined.
printf outputs to the standard output device.
When you start up a program, you can change the standard output device using redirection.
myhello > t.1
Will send all output bound for standard output to the file t.1. The file will be created if it did not previously exist.
In a similar way
myprog <t.2
would take input which normally would come from the keyboard from the file t.2 instead.
int getchar(void);Notice that it returns an int rather than a char. When successful, the value returned can be converted to a char.
Consider the following example:
#include <stdio.h> int main() { int i; int c; for (i=0;i<10;i++) { c = getchar(); printf("c = %d\n",c); } return 0; }Here is what the output would look like if the input were ABCDEFGHIJ:
c = 65 c = 66 c = 67 c = 68 c = 69 c = 70 c = 71 c = 72 c = 73 c = 74But if we changed the printf line to
c = A c = B c = C c = D c = E c = F c = G c = H c = I c = JWhen getchar tries to read past the end of a file, it returns a special value EOF defined in stdio.h. We could modify our program as follows:
#include <stdio.h> int main() { int i; int c; c = getchar(); while (c != EOF) { printf("c = %d\n",c); c = getchar(); } return 0; }If we create a file, t.in containing: ABCDEFGHIJ and called this program copychars, we could run it with:
copychars < t.inthe output generated would be:
c = 65 c = 66 c = 67 c = 68 c = 69 c = 70 c = 71 c = 72 c = 73 c = 10What is the meaning of the last line of output?
Another way of doing character output is with putchar.
Here is another program:
#include <stdio.h> int main() { int i; int c; c = getchar(); while (c != EOF) { putchar(c); c = getchar(); } return 0; }Here is the output generated by copychars1<t.in
This program just copies from standard input to standard output.
Let us assume that we are using the ASCII character set. This has the property that the codes for upper and lower case characters differ by a fixed amount. Consider the following program which is a slight modification of the previous one:
#include <stdio.h> int main() { int i; int c; c = getchar(); while (c != EOF) { if ( (c >= 'A') && (c <= 'Z') ) c = c + 'a' - 'A'; putchar(c); c = getchar(); } return 0; }Suppose this is called tolower and we execute
If we just typed tolower
Whatever we typed would come back with the upper case letters converted to lower case.
How would you convert tolower into toupper?
Unix allows you to easily send the output of one program into the input of another with a pipe. To do this from the command line, just connect the two programs with a | symbol.
Example:
ls -l | toupper
would show your directory converting upper case letters to lower case.
#include <stdio.h> #define OUT 0 #define IN 1 static int delimiter(int c) { if (c == ' ') return 1; return 0; } int main() { int c, wordCount, state; state = OUT; wordCount = 0; while ( (c=getchar()) != EOF) { if (state == OUT) { if (!delimiter(c)) { wordCount++; state = IN; } } else /* state == IN */ if (delimiter(c)) state = OUT; } printf("The number of words was %d\n",wordCount); return 0; }What would happen if there were no braces around the first if?
How would we allow other characters to be delimiters? Change the delimiter function.
static int delimiter(int c) { if ( (c == ' ') || (c == '\n') || (c == '\t') ) return 1; return 0; }
When you declare an array in C, you specify the size of the array, and the size must be known at compile time. This means that the size must be a constant.
In Java:
int letterCount[]; letterCount = new int[26];In C:
int letterCount[26];Here is a simple program that gives a letter count for its input:
#include <stdio.h> int main() { int count[26]; int i; int c; for (i=0;i<26;i++) count[i] = 0; while ((c = getchar()) != EOF) { if ( (c >= 'A') && (c <= 'Z')) count[c-'A']++; else if ( (c >= 'a') && (c <= 'z')) count[c-'a']++; } printf("Letter Counts Follow:\n"); for (i=0;i<26;i++) printf("%c: %4d\n",(char)(i+'A'),count[i]); return 0; }
Recall that the arguments are passed by value.
This means the the called function gets a copy of the value of the parameters
and so any changes it makes to these values is not seen by the calling
program.
The function can affect the calling program only through its return value.
Unlike in Java, C does provide a mechanism for changing primitive types that are passed as parameters. This will not be discussed for a while.
In C, a string is just an array of type char.
The length of the string is marked by a special character, sometimes referred
to as the null character.
Here, we will call it the string terminator.
It is the character with ASCII code 0. There are two ways to set a
character to have this value:
    char c;
    c = 0;
    c = '\0';
The last two lines do exactly the same thing.
The length of the string is the number of characters in the string up to but not including the string terminator.
Here is an example of a function that will read in a line from
standard input.
h | e | l | l | o | \0 |
"hello\n" is represented as
h | e | l | l | o | \n | \0 |
You cannot do:
char hello[6]; hello = "hello";but you can do:
char hello[6]; hell0[0] = 'h'; hell0[1] = 'e'; hell0[2] = 'l'; hell0[3] = 'l'; hell0[4] = 'o'; hell0[5] = '\0';And nothing will prevent you from doing:
char hello[5]; hell0[0] = 'h'; hell0[1] = 'e'; hell0[2] = 'l'; hell0[3] = 'l'; hell0[4] = 'o'; hell0[5] = '\0';But the consequences would be unpredictable.
Example:
#include <stdio.h> int main() { int d; int A[4]; int c; c = -1; d = -2; A[0] = 1; A[1] = 2; A[2] = 3; A[3] = 4; A[4] = 5; printf("c=%d, d=%d, A=%d %d %d %d %d\n",c,d,A[0],A[1],A[2],A[3],A[4]); return 0; }This compiles without error and when run gives:
lint will catch this:
(15) warning: array subscript cannot be > 3: 4 (16) warning: array subscript cannot be > 3: 4 function returns value which is always ignored printfHowever, lint will not complain about:
int A[4]; int i; for (i=0;i<5;i++) A[i] = a+1;
The array can be longer than the string:
char hello[10]; hell0[0] = 'h'; hell0[1] = 'e'; hell0[2] = 'l'; hell0[3] = 'l'; hell0[4] = 'o'; hell0[5] = '\0';This works fine as long as you don't access anyhting past hello[5].
The storage looks like:
h | e | l | l | o | \0 | ? | ? | ? | ? |
What is stored in the spaces with a ??
/* getline: read a line into s and return its length*/ int getline(char s[], int lim) { int c, i; c = getchar(); for (i=0; c != '\n'; i++) { if (c == EOF) { s[i] = '\0'; return i; } if (i == lim-1) { s[i] = '\0'; return i; } s[i] = c; c = getchar(); } s[i] = '\n'; if (i != lim-1) /* handle case of no room for string terminator */ i++; s[i] = '\0'; return i; }Notes:
#include <stdio.h> #define MAXLINE 10 int getline(char line[], int maxline); int main() { int len; int i; char line[MAXLINE]; len = getline(line,MAXLINE); printf("The line has length %d and the array is\n",len); for (i=0; i<MAXLINE; i++) { printf("%3d: %c = %d\n",i,line[i],(int)line[i]); if (line[i] == '\0') break; } return 0; }Some sample output:
pandora% getlinetest1 abc The line has length 4 and the array is 0: a = 97 1: b = 98 2: c = 99 3: = 10 4: = 0 pandora%
pandora% getlinetest1 abcdefghijklmnop The line has length 9 and the array is 0: a = 97 1: b = 98 2: c = 99 3: d = 100 4: e = 101 5: f = 102 6: g = 103 7: h = 104 8: i = 105 9: = 0 pandora%
pandora% getlinetest1 abc^D^DThe line has length 3 and the array is 0: a = 97 1: b = 98 2: c = 99 3: = 0 pandora%Note: The two ^D^D indicate pushing the D-key while holding down Control.
Creating test files:
pandora% wc test* wc test* 0 0 0 test00 0 1 1 test01 0 1 8 test08 0 1 9 test09 0 1 10 test10 1 0 1 testline00 1 1 2 testline01 1 1 9 testline08 1 1 10 testline09 1 1 11 testline10 1 1 2 testlines02 1 2 8 testlines08 1 2 9 testlines09 1 2 10 testlines10 9 15 90 total pandora%The wc utility lists number of newlines, words and bytes in a file.
Here is a batch file (shell script) to for testing getlinetest1.c
#!/bin/sh getlinetest1 < test00 getlinetest1 < test01 getlinetest1 < test08 getlinetest1 < test09 getlinetest1 < test10 getlinetest1 < testline00 getlinetest1 < testline01 getlinetest1 < testline08 getlinetest1 < testline09 getlinetest1 < testline10 getlinetest1 < testlines02 getlinetest1 < testlines08 getlinetest1 < testlines09 getlinetest1 < testlines10and we can run this with:
Here is the version of getline from the book (page 29):
int getline(char s[], int lim) { int c, i; for (i=0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i) s[i] = c; if (c == '\n') { s[i] = c; ++i; } s[i] = '\0'; return i; }Notes:
/* copy: copy 'from' into 'to'; assume big enough */ void copy(char to[], char from[]) { int i; i = 0; while( (to[i] = from[i]) != '\0') ++i; }Notes:
In a Java class you can declare variables outside of any method and these variables are available to any method in the class.
If they are declared public, they are available to any object which can access the object in which they appear.
In a similar way, you can declare a variable in a C source file outside of any function, and this variable is available to all functions in that file.
It is also available to functions outside of that file unless it is declared to be static.
We make a distinction between the definition and the declaration of a variable.
Declaration refers to the place where the nature of the variable is stated, but no storage is allocated.
We have already seen an example of this with functions.
The name of a function is a variable of a certain type.
(The nature of this type will be described later.)
The definition of a function occurs where the body of the function appears. A prototype of the function is its declaration.
A function or variable in C must be defined or declared before it is used.
If it is not possible or convenient to define it before it is used, a
declaration is necessary.
If a variable that is defined in another file is to be used, it must be declared in the file in which it is used before it is used. This is done by putting the key word extern in front of what would be its definition.
Example:
The following is a definition:
     int count
The following is a declaration:
     extern int count
Normally, there would be one file that contains the definition and any
number of other files that contain the declaration.
If two files contain the definition of count they would be referencing different variables.
If a prototype describes a function which is defined in another file
then extern should be used.
If the function is defined later in the same file, do not use
extern
Definitions are usually placed in separate files, traditionally called
header files, and included in the source file when needed.
An example of this is stdio.h which contains declarations of
functions such as printf and getchar.
Header files may also contain constants defined by #define such
as EOF.
Note: There is a difference between the declarations:
    int myfun(void);
and
    int myfun();
The first one indicates that the function has no parameters.
The second one indicates that the parameters are not specified and
agreement with the parameters should not be checked by the compiler.