C Info
(Quick Reference)
Introduction
C was originally developed by Dennis Ritchie of the Bell Laboratories in 1972. It is also called "Common C" or "Classic C".
The language was named "C" because it was the successor to a language named "B".
C is a structured, procedural programming language that has been widely used both for operating systems and applications and that has had a wide following in the academic community.
Many versions of UNIX-based operating systems are written in C. C has been standardized as part of the Portable Operating System Interface (Portable Operating System Interface).
Nowadays, with the increasing popularity of object-oriented programming, C is being rapidly replaced as "the programming language" by C++, a superset of the C language that uses an entirely different set of programming concepts, and by Java, a language similar to but simpler than C++, that was designed for use in distributed networks.
The American National Standards Institute defined a standard for C, called ANSI C, eliminating much uncertainty about the exact syntax of the language. ANSI C incorporate a few improvements over the old common C and the main difference is in the grammar of the language. The form of function declarations has been changed making them rather more like Pascal procedures.
Nowadays, most of the C programming texts are available in ANSI editions.
C Standard Library
<assert.h>
: Diagnostics <ctype.h>
: Character Class Tests <errno.h>
: Error Codes Reported by (Some) Library Functions <float.h>
: Implementation-defined Floating-Point Limits <limits.h>
: Implementation-defined Limits <locale.h>
: Locale-specific Information <math.h>
: Mathematical Functions <setjmp.h>
: Non-local Jumps <signal.h>
: Signals <stdarg.h>
: Variable Argument Lists <stddef.h>
: Definitions of General Use <stdio.h>
: Input and Output <stdlib.h>
: Utility functions <string.h>
: String functions <time.h>
: Time and Date functions References:
The Program Development Cycle
The Program Development Cycle for an application program written in C is summarized below :
1. Creating a program - Use a text editor to create or modify the source program. To identify your program as a C program, UNIX expects you to store your program in a file whose name ends in .c
(Remark: You can use any available editor. For example: Emacs, Xemacs, pico or vi.).
2. Compiling the Program - As follows find four ways to achieve this, though the three first eventually rely on the compiler (called cc on our system), and the last one rely on another compiler. Just choose one of them.
a) Using C Compiler < cc > - This is the simplest method. Just type:
> cc [-options] filename.c (To check all options type man cc)
This will try to compile filename.c, and, if successful, will produce a runnable file called a.out. If you want to give the runnable file a better name you can type:
> cc filename.c -o filename
This will compile filename.c, creating runnable file filename. (It is better keep the same name for the source and the runnable programs.)
b) Using a Program Builder < make > - UNIX also includes a very useful program called make. Make allows very complicated programs to be compiled quickly, by reference to a configuration file (usually called Makefile). If your C program is a single file, you can usually use make by simply typing:
> make [-options] filename (To check all options type man make).
This will compile filename.c and put the executable code in filename.
c) Using Improved Type Checking < lint > - The checker called lint will not generate any runnable code. You can use it, typing:
> lint [-options] filename.c (To check all options type man lint).
Lint is very good at detecting errors which cause programs to crash at run time. A disadvantage of lint is the fact that lint generally produces a long list of messages about minor problems with the program. Experience will teach you how to distinguish the important messages from those which can be ignored.
Comments:
The order of the options may be changed. You could type: cc -o filename filename.c.
Care about the options
Use the extension .out to name your runnable (or executable) files. It will help you to distinguish your files
d) Using the GNU Compiler < gcc > - GCC is a free compiler collection for C, C++, Fortran, Objective C and other languages. It is also available in our server. GCC works very similar than CC.
> gcc [-options] filename.c (To check all options type man gcc).
3. Running the progam - To run a program under UNIX you simply type a.out or , in case you gave a better name, just type the filename.
>a.out (If you did not give a better name.)
OR
> filename.out (Use the same extension you choose during the compilation step. In our case .out.
If you did not choose any extension, just type filename)You will see your prompt again after the program is done. If logical or run-time errors are encountered when the program is executed, it will be necessary to return to step 1, correct the errors and repeat steps 2 and 3.
Example: A simple program.
1. Creating a program.
>pico hello.c and type the following code:
#include <stdio.h> main() |
2. Compiling the Program, using C
Compiler cc.
>cc hello.c -o hello.out
3. Running the progam. - To run a
program under UNIX you simply type in the filename.
>hello.out
The program will print the message and you
will see your prompt again after the program is done.
Hello World !! This is a C program !!
|
C - Quick Reference
Structure of a C Program
/* This is a comment. */ #include <stdio.h> main() { ....; } |
Separating Statement
auto | break | case | char | const | continue | default | do |
double | else | enum | extern | float | for | goto | if |
int | long | register | return | short | signed | sizeof | static |
struct | switch | typedef | union | unsigned | void | volatile | while |
abc
total counter
factorial power sum x1 x2 in_file out_file |
c-max 4thValue while last word |
Characters other than letters and digits are not
allowed. The first character must be a letter. while is a reserved word. (See Appendix A). Blank spaces are not allowed (a blank space is a character). |
Data Types
C code | Meaning |
\b \f \n \r \t \\ \' \" \0 |
Backspace Form Feed Newline (linefeed + carriage return) Carriage Return Tab Backslash Single quote Double Quote NULL |
|
#define <name> <replacement text/value> |
#define city "Macau" #define tax 1.5 #define step 20 |
Variables
int a, x, counter; char letter; float average; |
int counter=1; |
int counter; counter = 1; |
int total;
/* Total of salaries
*/ int marks[10] /* Series of input marks */ char letter; /* Letter grade */ float average; /* Average of sales */ |
#include <stdio.h> int a = 123; /* global variable */ main() { printf ("%d\n%d\n",a,b); } int b = 456; /* global variable */ |
#include <stdio.h> int a = 123; /* global variable */ main() { extern int a,b; printf ("%d\n%d\n",a,b); } int b = 456; /* global variable */ |
>cc test.c >"test.c", line 7: undefined symbol: b cc: acomp failed for test.c > > |
> cc test.c >a.out 123 456 > |
- Global and external variables can be of any legal type.
They can be initialized, but the initialization takes place when the program
starts up, before entry to the main function.
- It is also recommended to avoid using external variables.
{ static int a; static sum=0; float pi=3.14; } |
int numbers[20];
/* this is a single-dimension array */ int numbers_2d[20][5]; /* this is a two-dimension array */ int numbers_3d[20][5][3]; /* this is a three-dimension array */ |
int add_array(int array[], int size) { int i; int total = 0; for(i = 0;
i < size; i++)
return(total); |
Strings
+ - * / % |
Addiction Subtraction Multiplication Division Modulo Reduction (Remainder from Integer Division) |
- The operators *, / and % will be performed before + or - in
any expression.
- Parentheses or brackets change the order of evaluation,
because a sub-expression within parentheses gets evaluated before the rest of
the expression. In nested expression, calculations are done from the inside out.
- Where division is performed between two integers, the result
will be an integer, with remainder discarded.
- Modulo reduction works with integers.
- Division by zero, will cause an error, usually causing the
program to crash.
- Examples of arithmetic expressions used within assignment
statements:
sum=sum + number; counter=counter + 1; area = pi * radius * radius; |
- C has some operators which allow abbreviation of certain types of arithmetic assignment statements.
Operator | Shorthand | Equivalent to |
Increment Decrement |
++i; or i++; --i; or i--; |
i = i + 1; i = i - 1; |
- These operations are usually very efficient and they can be
combined with another expression.
- Care about where the operator occurs. These can cause
confusion if you try to do too many things on one command line. Restrict the use
of the increment and the decrement operators to ensure that your programs stay
readable. As follows some examples:
Expression | Equivalent to |
a = b * c++; | a = b * c; c = c + 1; |
a = b * ++c ; | c = c + 1; a = b * c; |
Another shorthand notation is listed below:
Expression | Equivalent to |
a += 10 a -= 10 a*= 10 a /= 10 |
a = a + 10 a = a - 10 a = a * 10 a = a / 10 |
Relational Operators | Meaning |
> >= < <= == != |
greater than greater than or equal less than less than or equal equal not equal |
Logical Operators | Meaning |
&& || ! |
AND OR NOT |
Bitwise Operators | Meaning |
& | ^ << >> ~ |
bitwise AND bitwise inclusive OR bitwise exclusive OR left shift right shift one's complement (unary) |
Operators |
Associativity |
( ) [ ] ->
. ! ~ ++ -- + - * (type) sizeof * / % + - << >> < <= > >= == != & ^ | && || ?: = += -= /= %= ^= |= <<= >>= . |
left to right right to left left to right left to right left to right left to right left to right left to right left to right left to right left to right left to right right to left right to left left to right |
Conditional Expressions
expr1 ? expr2 : expr3 |
largest = (a > b) ? a : b;
|
z = max(a,b);
|
if (a>b) z=a; else z=b; |
printf ("You have %d items%s.\n", n, n==1 ? "" : "s"); |
Assignment Statement
Variable identifier = the value represented by an expression |
age = 18 ; firstletter = A ; sum=0; area = radius*radius*pi ; a=b+1; |
Type conversion
- You can mix the types of values in your arithmetic
expressions. char types will be treated as int. Otherwise where types of
different size are involved, the result will usually be of the larger size, so a
float and a double would produce a double result. Where integer and real types
meet, the result will be a double.
- There is usually no trouble in assigning a value to a variable
of different type. The value will be preserved as expected except where;
- Values passed as function arguments must be of the correct type. The function has no way of determining the type passed to it, so automatic conversion cannot take place. This can lead to corrupt results. The solution is to use a method called casting which temporarily disguises a value as a different type.
Example: The function sqrt finds the square root of a
double.
int i = 256; |
Explanation: The cast is made by putting the bracketed name of the required type just before the value. (double) in this example. The result of sqrt( (double) i); is also a double, but this is automatically converted to an int on assignment to root. |
Control Structures
if (expression) statement_1; /* if expression is true perform statement_1 */ else statement_2; /* if expression is false perform statement_2 */ |
if (a > b) max = a; else max = b; |
if (counter <=10) { sum += counter; counter ++; } |
if (a > b) { max = a; min = b; } else { max = b; min = a; } |
if (result >= 90) printf("Grade A\n"); else if (result >= 70) printf("Grade B\n"); else if (result >= 50) printf("Grade C\n"); else printf("Failed\n"); |
switch (expression) { case constant_expression : statements case constant_expression : statements ... default: statements /* default is an optional */ } |
switch(number) { case 0: printf("Zero\n"); break; /* the break statements causes an immediate exit from the switch */ case 1: /* case serves just as labels, without the break, the execution will */ printf("One\n"); /* falls through to the next unless you take explicit action to escape*/ break; case 2: printf("Two\n"); break; case 3: case 4: /* No break statement, the execution continue on allowing the */ case 5: /* same action for case 5. */ printf("Several\n"); break; default : printf("Many\n"); break; } |
while (expression) statement; |
while (i < 10) printf("%d\n",i++); printf("We are out of the loop".\n"); |
while (i < 10) { printf("%d\n",i++); printf("We are in the loop".\n"); } |
do statement while (expression); |
do printf("%d\n",i++); while (i < 10); printf("We are out of the loop".\n"); |
do { printf("%d\n",i++); printf("We are in the loop".\n"); } while (i < 10); |
for (expression1;expression2;expression3)
statement |
for (i=1; i <10; i++) printf("%d\n",i++); printf("We are out of the loop".\n"); |
for (i=1; i <10; i++) { printf("%d\n",i++); printf("We are in the loop".\n"); } |
int i=0; while (++i <=9) { if (i==5) break; printf("%d\n",i); } |
The output will be: 1 2 3 4 > |
- Like a break, continue should be protected by an if statement. It is not recommended to use it. For example:
int i=0; while (++i <=5) { if (i==3) continue; printf("%d\n",i); } |
The output will be: 1 2 4 5 > |
#include <stdio.h> /* Standard Input and Output Library Functions */ |
#include <stdio.h> main() { int ch; ch=getchar(); while (ch != EOF) { putchar(ch); ch = getchar(); } } |
#include <stdio.h> main() { int ch; while (( ch=getchar() ) != EOF ) putchar(ch); }
|
Comments: - EOF can be generated by typing Ctrl - d - Use Ctrl - c to stop the execution of the program. |
Comments: - EOF can be generated by typing Ctrl - d - Use Ctrl - c to stop the execution of the program. |
#include <ctype.h>
/* For definition of toupper - a function to convert lower case to upper
case*/ #include <stdio.h> /* For definition of getchar, putchar, EOF */ main() { int ch; while ((ch=getchar()) != EOF) putchar(toupper(ch)); } |
Comments: - EOF can be generated by typing Ctrl - d - Use Ctrl - c to stop the execution of the program. |
Format specifiers | Meaning |
%d %ld %c %s %u %f %e %g %o %x %% |
read an int argument in decimal read a long int argument in decimal read a character read a string read an unsigned decimal integer read a float or double argument same as %f, but use exponential notation use %e or %f, whichever is better read an int argument in octal (base 8) read an int argument in hexadecimal (base 16) read a literal %, no assignment is made. |
int n; scanf("%d", &n); |
int day, year; char month[12] scanf("%d %s %d", &day, month, &year); |
int day, month, year; scanf("%d/%d/%d", &day, &month, &year); |
Comment:
scanf("%d", n); instead of scanf("%d", &n); |
Format specifiers | Meaning |
%d, %i %ld %c %s %u %f %e %g %o %x, %X %% |
print an int argument in decimal print a long int argument in decimal print a character print a string print an unsigned int decimal number print a float or double argument same as %f, but use exponential notation use %e or %f, whichever is better print an int argument in octal (base 8) print an int argument in hexadecimal (base 16) no argument is converted, print a single % |
printf("%s\n",s); printf("%10s\n", s); printf("%.10s\n",s); printf("%-10s\n",s); printf("%.15s\n",s); printf("%-15s\n",s); /* - means right justified */ printf("%15.10s\n",s); printf("%-15.10s\n",s); |
:hello, world: :hello, world: :hello, wor: :hello, world: :hello, world: :hello, world: : hello, wor: :hello, wor: |
printf("%f\n",f); /* by default, 6 decimal places */ printf("%d\n",n); printf("%8.2f\n",f); /*8 spaces wide with 2 decimal places */ printf("%8.2f\n",n); printf("%6.4f\n",f); /*6 spaces wide with 4 decimal places */ printf("%6d\n",n); printf("%12.6f\n",f); printf("%d\n",f); |
:1234.123413: :12345678: :1234.12: : 0.00: :1234.1234: :12345678: : 1234.123413: :1083394174: |
Comments:
|
#include <stdio.h> main() { char line[256]; /* Define string sufficiently large to store a line of input */
while(gets(line) != NULL) /* Read line
*/ |
return-type <function-name> (argument declarations) |
#include <stdio.h> int example(int a, int b); /*function prototype declaration*/ main( ) { ... } example(int x, int y) { ... return value; } |
#include <stdio.h> int example(int , int); /*function prototype declaration*/ main( ) { ... } example(int x, int y) { ... return value; } |
double power(double val, unsigned pow) { double ret_val = 1.0; unsigned i; for(i = 0;
i < pow; i++)
return(ret_val); |
result = power(val, pow); /*This calls the function
power assigning the return value to variable result. */ or printf("%f", power(val,pow)); /* This prints the function power. */ |
void <function-name> (<argument declarations>) |
Scope of Function Variables
int powers(int base , int exp) { if (exp == 0) /*powers(base, 0) =1*/ return(1); else return(powers(base, exp - 1) * base); } |
|
#include
|
#include "filename"
or #include <filename> |
|
#define | #define name replacement-text | It calls for a macro substitution of the simplest kind. The name will be replaced by the replacement-text. |
#ifdef #ifndef |
#ifdef name #ifndef name |
They test whether a name is defined. |
#include <stdio.h> | <stdio.h> is a header and headers are implementation-dependent accessed. |
#include "myfile.h" | "myfile.h" is a file. |
#define Maxlength 1000 | Constant declaration |
#define max(a,b) ((a) > (b) ? (a) : (b)) | It is a macro called max. So max(a,b) will be substituted by the expression ((a) > (b) ? (a) : (b)). Parameters will be replaced by arguments. |
Pointers in C
int a = 10, b = 20, c[100]; int *p; /* p is a pointer to int */ p = &a
/* p now points to a - or p is referencing a - or the address of a is
assigned to the variable p. */ *p = *p + 1; /* increments *p by 1 */ b = *p + 1 /* whatever p points at, adds 1, and assigns the result to b */ *p+=1 /* increments what p points to */ ++*p /* same as before */ (*p)++ /* remember that ++ and * associate right to left, then the parentheses are necessary */ int a[10]; int x,y ; int *pa; pa=&a[0];
/* pa points to a[0] - or pa contains the address of a[0] */ |
swap(a,b); /* this is just the call */
void swap(int x, int y) /* this is the
function definition */ temp = x; |
swap(&a&,b); /*this is just the call */
void swap(int *px, int *py) /* this is the function
definition */ temp = *px; |
The arguments here will not be affected by the function swap. | The arguments here will be affected by the function swap. |
struct student { char name[30]; char faculty[50] char major [100]; int age; int year; }; |
typedef struct { char name[30]; char faculty[50] char major [100]; int age; int year; } student; |
student abc;
abc.age = 18; /* It will assign value 18 to member age in the variable abc */ If we have a pointer to a structure: struct point { Then *p is the structure and the members are (*p).x and (*p).y, or just p->x and p->y. Remember that *p.x is the same as *(p.x) !!! |
FILE *output_file; |
if ((output_file = fopen("output_file", "w")) ==
NULL) fprintf(stderr, "Cannot open %s\n", "output_file"); |
r open file for reading w create file for writing a open file for appending |
stdin The standard Input. The keyboard or a
redirected input file. stdout The standard Output. The screen or a redirected output file. stderr The standard Error. This is the screen, even when the output is redirect. This is the conventional place to put any error message. |
fclose(output_file); |
int fprintf(FILE *stream, char *format, args..)
int fscanf(FILE *stream, char *format, args..) |
char *string[80] FILE *stream, *fopen(); if ( (stream = fopen(...)) != NULL) |