![]() | ![]() | ![]() | 6 Notes |
??=
is replaced by #
#define
and #undef
#include
#if
, #ifdef
, #ifndef
, #elif
, #else
, and #endif
#error
#
end with \n
\\n
at end of line
#define
identifier token-sequence#include
"filename" -- user files#include
<
filename>
-- system files
/usr/include#if constant-expression #ifdef identifier #ifndef identifier #elif constant-expression #else #endif functiondefined
operator!
__LINE__
__FILE__
__DATE__
__TIME__
{
& }
while(
expression )
statementif(
expression )
statement
if(
expression )
statement else
statement
main
function
* | Multiply | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/ | Divide | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+ | Addition (and unary) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- | Subtraction (and unary, Negation) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
% | Remainder/mod | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"If the quotient a/b is representable, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
the expression (a/b)*b + a%b shall equal a." | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ANSI "C" Standard 9899 p82. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
= | Assignment | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
++ | Pre/post increment | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- | Pre/post decrement | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
== | Equality | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
> | Greater than | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
>= | Greater than or equal | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
< | Less than | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<= | Less than or equal | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
==
comparison operator
for floating point values. It may fail even when the numbers
"should" be identical. The precision used for registers and
computation may exceed the precision used for storage in memory.
What this means is that a comparison might fail or pass simply
due to register utilization by the compiler.
for
statementfor
statement:
for( expr_1; expr_2; expr_3 ) statementis equivalent to
expr_1; while( expr_2 ) { statement expr_3; }From Kernighan page 60.
do while
statement
"The statement is executed, then the expression is evaluated. If it is true, statement is [executed] again, and so on." Kernighan p 62.do
statementwhile(
expression);
Decimal | 12345 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Unsigned Decimal | 12345U | or u | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Long Integer | 123456789L | or l | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Unsigned Long Integer | 123456789UL | or ul | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Octal | 012345 | Leading 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Hexadecimal | OxA4BC | I like lower case x | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Single Character | 'a' | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
String, null terminated | "String" | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Floating Point | 1234f | or F | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Floating Point | 1234.234 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Long Floating Point | .0012L | or l | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Exponential notation | 1234.234e-12 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Exponential notation | 1e-12 | No . required. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
\b | Backspace | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
\f | Form feed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
\n | Newline | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
\r | Carriage return | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
\t | Horizontal tab | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
\v | Vertical tab | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
\\ | Backslash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
\? | Question mark | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
\' | Single quote | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
\" | Double quote | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
\ooo | Octal number | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
\xhh | Hexadecimal number | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
and"Hello, "
"world"
"Hello, world"
are equivalent. This is useful for long, multi-line constants.
printf()
-- 1 stdio.h
fprintf()
%
signed decimal | d | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
signed decimal | i | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
octal | o | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Uppercase Hex | X | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Lowercase Hex | x | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
unsigned decimal | u | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
single character | c | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
string | s | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
floating point | f | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
exponential notation | e | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mixed (f&e) notation | g | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
% | % | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Left justify | - | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Always print sign | + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Leave a space for the sign | space | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Pad with leading zeros | 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Alternate output | # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Minimum width | number | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Period | width. precision | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Short Integer | h | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Long integer and real | l | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Long Double | L | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*
,
in which case the value comes from the next arguments. Kernighan p 244.
& | Bitwise AND | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | Bitwise OR | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
^ | Bitwise XOR | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<< | Left shift | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
>> | Right Shift | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
~ | one's complement (unary) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#include <stdio.h>
un
functions can only return a single
character. You can NOT push back multiple characters
with multiple calls.
getc(FILE *fp) | Read a char from *fp | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
getchar() | #define getchar() getc(stdin) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ungetc(FILE *fp) | Returns one char to *fp | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ungetchar() | Returns one char to stdin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
putc(int c, FILE *fp) | "Prints" one char to *fp | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
putchar(int c) | #define putchar(c) putc(c,stdin) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int i, j, k, l, m, n;
int i = 1, j =2; const double pi = 3.1415926535897932384626433;
extern | Symbol is passed to the linker | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
static | Symbol is NOT passed to the linker | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
exists for the duration of the program. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
auto | Limits storage duration, not useful | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
register | Instructs compiler to use registers. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pointers are NOT allowed. |
void | It doesn't exist | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
char | a single character | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
short | often 16 bits | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
int | the default size on the machine | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
long | often 32 bits | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
float | floating point | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
double | 64 bit floating point | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
signed | the default anyway | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
unsigned | no negative values, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
but twice the range. |
const | You can't change it. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
volatile | "Something" else might change it. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[ ]
square braces.
,
operator.
[ ]
square braces.
int i[4] = { 4, 3, 2, 1 }; float x[2][3] = { { 8.8, 7.7, 6.6 } { 5.5, 4.4, 3.3 } };
/* Louis Taber * * Feb 10, 2001 * * Program to demonstrate the effect * of the cache memory system * and array addressing order. */ #include <stdio.h> #include <time.h> #define LINE 512 #define MAX_ARRAY_SIZE 64*1024*1024 /* 64 Mbytes */ #define MAX_ROW ( MAX_ARRAY_SIZE / LINE ) char array[MAX_ROW][LINE]; /* Test array */ int i,j; /* Index values */ int size, row; /* Array indexes */ int sum, sum1, sum2; clock_t start, filled_time, first_fetch, second_fetch; float f_t, t_1, t_2, ratio; int main() { printf("Execution Times LINE= %d \n\n", LINE); printf(" Array Fill Row Column C/R\n"); printf(" Size Time Fetch Fetch Ratio\n"); size=MAX_ARRAY_SIZE; while( size >= 32 * 1024 ) { row=size/LINE; sum=sum1=sum2=0; start= clock(); /* Fill array */ for( i=0; i<row; i++ ) for( j=0; j<LINE; j++) sum += (int)(array[i][j] = (char)((i+j)%127) ); filled_time = clock(); /* Access all of array right index fastest */ for( i=0; i<row; i++ ) for( j=0; j<LINE; j++) sum1 += (int)array[i][j]; first_fetch = clock(); /* Access all of array left index fastest */ for( j=0; j<LINE; j++) for( i=0; i<row; i++ ) sum2 += (int)array[i][j]; second_fetch = clock(); f_t = (float)(filled_time-start)/CLOCKS_PER_SEC; t_1 = (float)(first_fetch-filled_time)/CLOCKS_PER_SEC; t_2 = (float)(second_fetch-first_fetch)/CLOCKS_PER_SEC; ratio= t_2/t_1; printf("%10d %6.2f %6.2f %6.2f %6.2f\n", size, f_t,t_1,t_2, ratio); /* check to see of the sums are all the same */ if( sum != sum1 || sum != sum2 ) { printf(" Sums do not match\n"); printf(" %d %d %d \n", sum, sum1, sum2); } size >>=1; /* Cut size of array in half. */ } return 0; }
Intel Pentium, Dual 100MHz, 128 MBytes Execution Times LINE= 512 Array Fill Row Column C/R Size Time Fetch Fetch Ratio 67108864 55.32(1) 14.03(1) 30.68 2.19(3) 33554432 27.09 7.02 15.33 2.18 16777216 13.67 3.51 7.67 2.19 8388608 6.94 1.76 3.82 2.17 4194304 3.59 0.88 1.92 2.18 2097152 1.91 0.44 0.95 2.16 1048576 1.06 0.22 0.48 2.18 524288 0.64 0.11 0.21 1.91 262144 0.45 0.06 0.09 1.50 131072 0.34 0.02 0.04 2.00 65536 0.20 0.01 0.12 12.00(4) 32768 0.10 0.01 0.09 9.00 Intel Pentium II, 233 MHz, 386 Mbytes (old gort) Execution Times LINE= 512 Array Fill Row Column C/R Size Time Fetch Fetch Ratio 67108864 13.31 3.27 11.50 3.52 33554432 6.34 1.64 5.73 3.49 16777216 3.17 0.82 2.84 3.46 8388608 1.59 0.41 1.41 3.44 4194304 0.80 0.20 0.71 3.55 2097152 0.40 0.10 0.36 3.60 1048576 0.20 0.05 0.17 3.40 524288 0.10 0.02 0.07 3.50 262144 0.05 0.01 0.02 2.00 131072 0.03 0.00 0.01 inf 65536 0.01 0.00 0.01 inf 32768 0.01 0.00 0.00 nan AMD K6-2, 500MHz, 128MBytes (old lt) Execution Times LINE= 512 Array Fill Row Column C/R Size Time Fetch Fetch Ratio 67108864 7.56 1.97 19.54 9.92(3) 33554432 3.34 0.98 9.77 9.97 16777216 1.67 0.50 4.87 9.74 8388608 0.84 0.24 2.44 10.17 4194304 0.42 0.12 1.22 10.17 2097152 0.21 0.06 0.60 10.00 1048576 0.11 0.03 0.28 9.33 524288 0.05 0.01 0.12 12.00 262144 0.02 0.01 0.05 5.00 131072 0.01 0.01 0.02 2.00 65536 0.01 0.00 0.01 inf 32768 0.00 0.00 0.00 nan AMD K6-2, 233MHz, 64MBytes (amd) Execution Times LINE= 512 Array Fill Row Column C/R Size Time Fetch Fetch Ratio 67108864 17.46 3.29 355.67 108.11(5) 33554432 7.57 2.50 16.49 6.60 16777216 3.94 1.30 8.24 6.34 8388608 2.00 0.65 4.11 6.32 4194304 0.98 0.33 2.04 6.18 2097152 0.49 0.16 1.01 6.31 1048576 0.24 0.08 0.48 6.00 524288 0.13 0.04 0.17 4.25 262144 0.06 0.02 0.08 4.00 131072 0.03 0.01 0.03 3.00 65536 0.01 0.00 0.02 inf 32768 0.01 0.00 0.00 nan AMD Athelon, 850MHz, 512MBytes (thunder) Execution Times LINE= 512 Array Fill Row Column C/R Size Time Fetch Fetch Ratio 67108864 4.91 1.05 7.52 7.16 33554432 2.39 0.52 3.76 7.23 16777216 1.19 0.26 1.88 7.23 8388608 0.60 0.13 0.94 7.23 4194304 0.29 0.07 0.46 6.57 2097152 0.15 0.04 0.22 5.50 1048576 0.08 0.02 0.10 5.00 524288 0.03 0.01 0.05 5.00 262144 0.02 0.01 0.00 0.00 131072 0.01 0.00 0.01 inf 65536 0.00 0.00 0.00 nan 32768 0.01 0.00 0.00 nan HP Compaq dc5100MT 3.0Ghz, 2GBytes (red 2008) Execution Times LINE= 512 Array Fill Row Column C/R Size Time Fetch Fetch Ratio 67108864 0.77 0.28 2.40 8.57 33554432 0.36 0.14 1.18 8.43 16777216 0.18 0.07 0.58 8.29 8388608 0.09 0.03 0.29 9.67 4194304 0.05 0.01 0.15 15.00 2097152 0.03 0.00 0.08 inf 1048576 0.01 0.00 0.03 inf 524288 0.01 0.00 0.00 nan 262144 0.01 0.00 0.00 nan 131072 0.00 0.00 0.00 nan 65536 0.00 0.00 0.00 nan 32768 0.00 0.00 0.00 nan HP 2133 Mininote 1.6Ghz Atom, 2GBytes Execution Times LINE= 512 Array Fill Row Column C/R Size Time Fetch Fetch Ratio 67108864 3.10 1.18 8.46 7.17 33554432 1.46 0.57 4.22 7.40 16777216 0.73 0.28 2.10 7.50 8388608 0.35 0.14 1.06 7.57 4194304 0.18 0.08 0.52 6.50 2097152 0.10 0.04 0.24 6.00 1048576 0.06 0.02 0.12 6.00 524288 0.02 0.01 0.07 7.00 262144 0.01 0.00 0.03 inf 131072 0.01 0.00 0.01 inf 65536 0.00 0.00 0.00 nan 32768 0.00 0.00 0.00 nanThis "benchmark" was using the FSF
gcc
compiler running Linux.
Notes on cache.c
program output:
break
statement
Kernighan p224 (very bottom of page)
A break
statement may appear only in an iteration statement
or a switch
statement, and terminates execution of the
smallest enclosing such statement; control passes to the statement
following the terminating statement.
switch (
expression )
statement
case
labels.
default
statement is allowed.
case
.
switch( i ) { case 1: a++; /* falls into case 2 */ case 2: b++; break; default: c++; /* i was not 1 or 2 */ }
continue
statement
Kernighan p224
A continue
statement may appear only within
an iteration statement. It causes control to pass to the
loop-continuation portion of the
smallest enclosing such statement.
+= | Addition | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-= | Subtraction | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
*= | Multiply | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/= | Divide | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
%= | Remainder/mod | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
&= | Bitwise AND | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
^= | Bitwise XOR | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|= | Bitwise OR | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<<= | Left shift | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
>>= | Right Shift | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Logical expression evaluation will stop as soon as the final outcome is known (ANSI "C" Standard 9899 6.5). The order of the expression evaluation is indeterminate -- most of the time.
Except as specified later (For the function call ( )
,
&&
, ||
, ?:
and the comma operators), the order
of evaluation of subexpressions and the order in which side effects
take place are both unspecified.
The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.
True is indicated by non-zero. False by zero. ANSI "C" Standard 9899 p6.5.3.3 re: ! operator will return a one(1) for a true condition.
&& | Logical AND | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|| | Logical OR | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
! | Logical NOT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for
statement.
extern
or implicitly by context.
extern
is used to declared a variable not to define it.
extern
declaration is required.
return-type function-name(
argument declarations)
{ declarations and statements }
#include
the necessary header (.h
) files.
rain
and cain
and
functions main
and spain
.
/* Program to demonstrate different function * prototypes and declarations * * Louis Taber Feb 11, 2001 PCC */ /* library prototypes and macros */ #include <stdio.h> double rain(double x, int y); void cain(int r, int s); int /* You may want the function name in Col #1 */ main(int argc, char * argv[ ], char * env[ ]) { return 0; } /* You can put them on seperate lines */ /* old style */ int spain(argc, argv, env) int argc; char * argv[ ]; char * env[ ]; { return 0; }I not quite sure why you would want it but it is available by HTTP at:
main
function revisited.
The following program prints out the
passed arguments and the environment
variables. According to
ANSI "C" Standard 9899 5.1.2.2.1 p 12 the only arguments
passed to main are int argc
and char *argv[ ]
.
Passing the environment is a UNIX extension.
/* Program to print arguments to a program */ /* and the passed environment */ /* L Taber March 28, 1993 PCC */ #include <stdio.h> main(int argc, char * argv[ ], char * env[ ]) { int i; /* Print number of arguments and the first argument */ printf("argc = %d File name = %s\n", argc, argv[0]); /* Print all remaining arguments - if any */ for ( i=1; i<argc; i++) printf(" arg[%d] = %s \n" ,i,argv[i]); printf("\n"); /* Print the environment - if any */ for ( i=0; env[i] != NULL; i++) printf(" env[%d] = %s\n" ,i,env[i]); printf("\n"); return 0; }
return
expressionopt;
}
will also return
control from a function.
&
Address operator Kernighan p 94
Hanly & Koffman pages 51, 285.
This operator returns the address of the object.
*
Indirection Operator (dereference) Kernighan p 94.
An example program that:
/* Program to look at pointers */ /* L Taber Feb 17, 2001 PCC */ #include <stdio.h> #include <stdlib.h> /* returns three results */ int sumANDswap(int *a, int *b); int printab(int x, int y, char *string); int a = 1; /* external variable */ /* initilized only once */ int *ptr; int main() { int b; /* auto variable */ int sum; /* for return value */ ptr = malloc( sizeof a ); *ptr = 42; b=5+a; printab(a, b, "a & b "); sum = sumANDswap(&a, &b); printab(a, b, "a & b "); printf("sum= %d\n\n", sum); printab(b, *ptr, "b & *ptr "); sum = sumANDswap(&b, ptr); printab(b, *ptr, "b & *ptr "); printf("sum= %d\n", sum); } /* returns three results */ int sumANDswap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; return( *a + *b ); } /* strings are really character pointers ! */ int printab(int x, int y, char *string) { return printf(" %s %d %d\n", string, x, y); }
This program is available by HTTP at:
http://lt.tucson.az.us/ltaber/hl2.2009-spring/c/prt1.c.
The anotated output on my system looked like this:
a & b 1 6 a & b 6 1 sum= 7 b & *ptr 1 42 b & *ptr 42 1 sum= 43
I am using gcc version 2.95.2 20000220 (Debian GNU/Linux).
main()
does not change.
a
does not change.
b
is placed on the stack
at a lower address.
int
on the malloc
-ed.
The heap is grows toward the stack.
You may want to look at Linux Torvalds coding standards for the kernel. I have converted them to HTML.
if( a>b ){ a++; }
if( a>b ) { a++; }
if( a>b ) { a++; }
stdlib
I/O functions#include <stdio.h>
fopen()
fclose()
stream
and flush all data. Harbison p346.
fgets()
stream
. Harbison p356.
fputs()
stream
. Harbison p366.
fseek()
Sets file position. Kernighan p248. Harbison p352.
ftell()
Returns file position. Kernighan p248. Harbison p352.
rewind()
fgetpos()
fsetpos()
fflush()
remove()
rename()
stdlib
error functions#include <stdio.h>
#include <errno.h>
#include <string.h>
extern int errno;
This integer is set when a routine
reports an error. It is NEVER cleared by a routine.
It should only be checked after an error occurs.
strerror()
"Convert" the error number to a string.
perror()
Print the string associated with an error to stderr.
ferror()
File error. Harbison p404.
feof()
End-of-file.
clearerr()
Clear file error.
(Avoid these functions for portability)
open
close
creat
read
write
lseek
File access examples. http://lt.tucson.az.us/ltaber/hl2.2009-spring/c/file-or-stdin.c
/* Louis Taber, 3/18/2001 * * -- Use stdin or file name on command line. * * copy stdin to stdout if no file name is specified * * else opern file and send to stdout */ #include <stdio.h> void filecopy(FILE *, FILE *); int main(int argc, char *argv[]) { FILE *fp; if( argc == 1 ) /* No arguments -- use std input */ { filecopy(stdin, stdout); } else { if((fp = fopen( argv[1], "r")) == NULL) { printf("%s(line %d): can't open: %s\n", __FILE__, __LINE__, argv[1]); return 1; } else { filecopy(fp, stdout); fclose(fp); } } return 0; } /* filecopy: copy file ifp to file ofp */ void filecopy(FILE *ifp, FILE *ofp) { int c; while(( c= getc(ifp)) != EOF) putc(c, ofp); }
Program to read the roads for the route lab. http://lt.tucson.az.us/ltaber/hl2.2009-spring/c/read-roads.c
/* Louis Taber 3/18/2001 * * -- Read roads * * Example program for fscanf() * * */ #include <stdio.h> int main(void) { FILE *fp; int zip1, zip2, miles; char comment[200]; if((fp = fopen( "route.dat", "r")) == NULL) { printf("%s(line %d): can't open: route.dat\n", __FILE__, __LINE__); return 1; } else { do { if( fscanf( fp, "%d %d %d %s\n", &zip1, &zip2, &miles, comment) <0 ) break; printf("From zip %05d to zip %05d is %5d miles (%s) \n", zip1, zip2, miles, comment); } while( zip1 != 0 ); fclose(fp); } return 0; }
scanf | Reads from standard input | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
sscanf | Reads from string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fscanf | Reads from file | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
stdio.h
signed decimal | d | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
signed integer (octal & hex too) | i | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
octal | o | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
hexadecimal | x | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
unsigned decimal | u | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
single character | c | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
string | s | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
floating point | f e g | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
% (literal) | % | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fprintf()
output to file
sprintf()
output to string
#include <ctype.h>
isalnum()
True if alphanumeric
isalpha()
True if A-Z or a-z
iscntrl()
Control character
isdigit()
True if 0-9
isgraph()
Printing character except space
islower()
True if a-z
isprint()
Printing character including space
ispunct()
Printing character except space, letter or digit
isspace()
True if space, FF, HT, VT, CR
isupper()
True if A-Z
isxdigit()
True if a Hexadecimal Digit
#include <ctype.h>
#include <stdlib.h>
atof()
ASCII to floating point
atoi()
ASCII to integer
atol()
ASCII to long
itoa()
Integer to ASCII
tolower
Upper case to lower case
toupper
Lower case to upper case
Some problems, (not many,) lend themselves to a recursive solution. Expression evaluation is a good example of a good application of recursion.
You may want to look at Hanly & Koffman Chapter 10 Recursion on page 501..
The following program is recursive implementation of the Fibonacci
series, (1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...
). In the series
(except
for the first two numbers) each number is the sum of the previous two.
The program source is available at:
http://lt.tucson.az.us/ltaber/hl2.2009-spring/c/recursion.c
/* Louis Taber PCC April 8, 2001 * * Recursion example */ int fib(int d) /* Fibonacci series */ { /* First two numbers are 1 */ if( d <= 2 ) return 1; /* The rest are the sum of */ /* the previous two in series */ else return fib(d-1) + fib(d-2); } main() /* Call Fibonacci series */ { /* function fib with values */ int i; /* from 1 to 12 */ for( i=1; i<13; i++) printf("fib(%2i)=%3d %c", i, fib(i), i%3 ? ' ' : '\n' ); return 0; }
And the output:
fib( 1)= 1 fib( 2)= 1 fib( 3)= 2 fib( 4)= 3 fib( 5)= 5 fib( 6)= 8 fib( 7)= 13 fib( 8)= 21 fib( 9)= 34 fib(10)= 55 fib(11)= 89 fib(12)=144
It is some times desirable to be able to pass the address of a function to another part of a program. This can be useful in sorts. It can also be required for certain calls to the operating system for error handling and signals.
The example is about as simple as it can get. There are two different
functions, one twice
, doubles a number, and half
, divides a
number by two. They are called alternately. The address of the function
called is also printed.
The program:
/* Program to look at function pointers */ /* L Taber April 8, 2001 PCC */ #include <stdio.h> int twice(int x) { return x*2; } /* double number */ int half(int x) { return x/2; } /* divide number by 2 */ int main() { int i; int (*function)(int); for( i=0; i<10; i++) { /* If i is odd, function = twice */ if( i&1 ) function = &twice; else function = ½ /* call function and print results */ /* Print address of function in [ ] */ printf(" f[%p](%i) = %d %c", function, i, function(i), i&1 ? '\n' : ' ' ); } }
The source is available at:
http://lt.tucson.az.us/ltaber/hl2.2009-spring/c/function-ptr.c
And the output:
f[0x80483f4](0) = 0 f[0x80483e0](1) = 2 f[0x80483f4](2) = 1 f[0x80483e0](3) = 6 f[0x80483f4](4) = 2 f[0x80483e0](5) = 10 f[0x80483f4](6) = 3 f[0x80483e0](7) = 14 f[0x80483f4](8) = 4 f[0x80483e0](9) = 18
C standard library string function assume that the string is null
terminated.
#include <string.h>
strcpy | Copy a string to another location | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strncpy | Copy a limited string to another location | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strcat | Concatenate strings | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strncat | Concatenate a limited string to another | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strcmp | compares two strings | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strncmp | compares two strings up to a limit | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strchr | Find the first specific character in a string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strrchr | Find the last specific character in a string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strlen | Find length of string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Other string functions: strspn
, strcspn
, strpbrk
,
strstr
, and strtok
.
There is also a set of functions for wide characters.
Structures are a way of keeping related data together.
General form of a structure:
struct structure-name { field-type field-name field-type field-name field-type field-name ... } variable-name;
This program uses structures
The program:
The source is available at:
http://lt.tucson.az.us/ltaber/hl2.2009-spring/c/struct.c
/* Louis Taber April 9, 2001 * * Sample program for structures */ #include <stdio.h> #include <math.h> /* structure has a integer and a float */ struct twoitems { int a; float b; }; /* Subroutine swaps values */ /* doing type conversions */ void swap(struct twoitems *subptr) { int temp; temp = subptr->a; subptr->a = (int)subptr->b; subptr->b = (float)temp; return; } main() { /* define x & y using twoitems */ /* declaration */ struct twoitems x, y; struct twoitems *ptr; /* initilize using dot syntax */ x.a = 42; x.b = 8.4; /* Place values in y using x */ y.a = (int)x.b + 1; y.b = (int)sqrt((double)y.a); /* Print out structure y */ printf("y: %3d %f\n", y.a, y.b); /* Allocate space for new structure */ ptr = (struct twoitems *)malloc( sizeof(struct twoitems) ); /* Copy all of x into allocated space */ *ptr = x; /* print copy pointed to by ptr */ printf("copy: %3d %f\n", ptr->a, ptr->b); /* Call subroutine to swap elements */ swap(ptr); /* print results of swap */ printf("swapped: %3d %f\n", ptr->a, ptr->b); return 0; }
And the output:
y: 9 3.000000 copy: 42 8.400000 swapped: 8 42.000000
This program inputs "tokens" from
the standard input and places them on
a linked list keeping track of usage
The source is available at:
http://lt.tucson.az.us/ltaber/hl2.2009-spring/c/link.c
/* Louis Taber April 15, 2001 */ /* */ /* Linked list program #1 */ #include <stdio.h> #define TRUE 1 struct token { struct token *next; /* link to next item */ char *value; /* link to storage for string */ int usecount; /* number of times encountered */ }; struct token * insert(char * string); int link_count = 0; /* count of links used */ int item_count = 0; /* count of items */ main() { int i; /* loop counter */ char string[200]; /* max string size */ struct token *current; struct token *start; struct token *working; start = NULL; while( TRUE ) /* Until EOF */ { /* get a string */ if( fscanf( stdin, "%s", string ) == EOF ) break; if( start == NULL ) { start = insert( string ); continue; } current = start; while( TRUE ) { if( strcmp( string, current->value ) == 0 ) { /* found existing item */ current->usecount++; break; } if( current->next == NULL ) /* if end of list */ { current->next = insert( string ); break; } else { /* get next item on list */ current = current->next; link_count++; } } } current = start; /* print out items */ while( TRUE ) { if( current == NULL ) break; item_count ++; if( current->usecount > 3 ) printf("use:%4d -- %s\n", current->usecount, current->value); current = current->next; } printf("\nItem count: %4d Link count: %4d\n", item_count, link_count); } /* routine to insert string at end of linked list. */ struct token * insert(char * string) { int str_length; struct token * token_ptr; /* allocate space for structure */ token_ptr = (struct token*) malloc( sizeof( struct token )); if( token_ptr == NULL ) { printf("malloc 1 failed\n"); exit(); } /* get string length and allocate space */ str_length = strlen( string ) + 1; /* set initial use count */ token_ptr->usecount = 1; /* clear next pointer */ token_ptr->next = NULL; /* copy string to heap */ token_ptr->value = (char *) malloc( str_length ); if( token_ptr->value == NULL ) { printf("malloc 2 failed\n"); exit(); } strcpy( token_ptr->value, string ); /* return pointer to new structure */ return token_ptr; }
And the edited output:
use: 13 -- things use: 674 -- will use:1825 -- a use:2588 -- to use: 7 -- Visual use: 7 -- Cybervision Item count: 12191 Link count: 156262111
This program is a modification of the prior
program that uses multiple linked lists and
a hashing algorithm to reduce search time.
The source is available at:
http://lt.tucson.az.us/ltaber/hl2.2009-spring/c/link-hash.c
/* Louis Taber April 16, 2001 */ /* */ /* Linked list program #2 */ #include <stdio.h> #define TRUE 1 /* Number of linked lists */ #define MASKBITS 8 #define HASHMAX ( 1 << MASKBITS ) #define MAXMASK ( HASHMAX - 1 ) /* When run on a text file with 565839 bytes */ /* ( ../linux/Documentation/Configure.help) */ /* with different values of MASKBITS */ /* This was done with an AMD K6-2 500Mhz with */ /* 128 Mbytes running Linux */ /* MASKBITS HASHMAX U Time Link Count */ /* 0 1 23.42 156262111 */ /* 1 2 14.78 78120792 */ /* 4 16 2.26 9750485 */ /* 5 32 1.35 4865690 */ /* 8 256 .42 602588 */ /* 12 4096 .33 32669 */ struct token { struct token *next; /* link to next item */ char *value; /* link to storage for string */ int usecount; /* number of times encountered */ }; struct token * insert(char * string); int link_count = 0; /* count of links used */ int item_count = 0; /* count of items */ /* Routine to determine which linked list */ /* This should be fast and "random". */ int hash(char *st) { int rtn=0; char c; while( (c = *st++) != '\0' ) { rtn = ( ( rtn ^ 0x5A5A ) << 2 ) ^ c; rtn = (rtn & 0xFFFF) ^ (rtn >> 12); } return rtn & MAXMASK; } main() { int i; /* loop counter */ int hash_count[HASHMAX]; int start_point; /* index in to linked list array */ char string[200]; /* max string size */ struct token *current; struct token *start[HASHMAX]; struct token *working; /* Print hash algorithm constants */ printf("MASKBITS %d\nHASHMAX %d\nMAXMASK %08x\n", MASKBITS, HASHMAX, MAXMASK); for( i=0; i<HASHMAX; i++) start[i] = NULL; while( TRUE ) /* Until EOF */ { /* get a string */ if( fscanf( stdin, "%s", string ) == EOF ) break; /* figure out which list */ start_point = hash( string ); if( start[start_point] == NULL ) { /* place initial string */ start[start_point] = insert( string ); continue; } current = start[start_point]; while( TRUE ) { /* look for existing item */ if( strcmp( string, current->value ) == 0 ) { /* found existing item */ current->usecount++; break; } if( current->next == NULL ) /* if end of list */ { /* place item at end of list */ current->next = insert( string ); break; } else { /* get next item on list */ current = current->next; link_count++; } } } for( i=0; i<HASHMAX; i++ ) { hash_count[i] = 0; current = start[i]; /* print out items */ while( start[i] != NULL ) { if( current == NULL ) break; item_count++; hash_count[i]++; if( current->usecount > 5 ) printf("use:%4d -- %s\n", current->usecount, current->value); current = current->next; } } for( i=0; i<HASHMAX; i++ ) printf("%8d",hash_count[i]); printf("\nItem count: %4d Link count: %4d\n", item_count, link_count); } /* routine to insert string at */ /* end of linked list. */ struct token * insert(char * string) { int str_length; struct token * token_ptr; /* allocate space for structure */ token_ptr = (struct token*) malloc( sizeof( struct token )); if( token_ptr == NULL ) { printf("malloc 1 failed\n"); exit(); } /* get string length and allocate space */ /* strlen does not include '\0' */ str_length = strlen( string ) + 1; /* set initial use count */ token_ptr->usecount = 1; /* clear next pointer */ token_ptr->next = NULL; /* copy string to heap */ token_ptr->value = (char *) malloc( str_length ); if( token_ptr->value == NULL ) { printf("malloc 2 failed\n"); exit(); } strcpy( token_ptr->value, string ); /* return pointer to new structure */ return token_ptr; }
And the edited output:
MASKBITS 8 HASHMAX 256 MAXMASK 000000ff use: 13 -- things use: 674 -- will use:1825 -- a use:2588 -- to use: 7 -- Visual use: 7 -- Cybervision 61 46 55 47 51 55 ... Item count: 12191 Link count: 602588
![]() | ![]() | ![]() | 6 Notes |