Thursday, August 21, 2014

Ansi C

The C Programming Language -- ANSI C
Brian W. C. Kernighan & Dennis M. Ritchie
Prentice Hall, 1988
-------------
1988 ANSI C (American National Standards Institute)
-----------
hello.c
#include <stdio.h>
void main() {  printf("\nHello World\n");  }
--------------
Every full C program begins inside a function called "main".

{} curly braces
; semicolon
, comma

variable
type
keyword
declare a variable
statement
operator
Loop
parameter
--------
#include
Prepocessor directive that takes everything in the header and paste it into your program.
The .h files are  header files which contain definitions of variables and functions.

stdio.h: I/O (input/output) library. It contains the function printf
ctype.h: defining character manipulation routines
string.h: defining string manipulation routines
math.h: defining mathematical routines
stdlib.h: defining number conversion, storage allocation  and similar tasks
stdarg.h: defining libraries to handle routines with variable  numbers of arguments
time.h: defining time-manipulation routines
assert.h: defining diagnostic routines
setjmp.h: defining non-local function calls
signal.h: defining signal handlers
limits.h: defining constants of the int type
float.h: defining constants of the float type
--------
Function parameters are always passed by value.
Pass-by-reference is simulated in C by explicitly passing pointer values.
for, if/else, while, switch, and do/while.
A preprocessor performs macro definition, source code file inclusion, and conditional compilation.
-----------
A compiler turns the program that you write into an executable that your computer can actually understand and run.
to compile (GNU C compiler)
gcc hello.c
-------
\n (new line)
\t  (tab)
\g (ring the bell (beep) on the terminal)
\v (vertical tab)
\f (new page)
\b (backspace)
\r (carriage return)
------------
Blocks of statements are put in braces {...}
-----
#include <stdio.h>
int main() {
printf( "I am alive!  Beware.\n" );
getchar(); /*reads in a single character and waits for the user to hit enter before reading the character*/
return 0; /*0 means success.*/
}
--------
/* multiple-line
comment*/

// single-line comment (valid only on C99)
-------
int myVariable;
int x;
int a, b, c, d;
char letter;
float the_float;
int a = 10, b = 100, c = 200;

char:    character variable (single byte)
short:   short integer
int:     integer variable
long:    long integer
float:   single precision real (floating point) variable
double:  double precision real (floating point) variable

In C you must declare all of your variables before you do anything else.
----------
a = 4 * 6;
a = a + 5;
a == 5     /* Does NOT assign five to a. Rather, it checks to see if a equals 5.*/

+ Addition
- Subtraction
* Multiplication
/ Division
% Modulus
----------
signed variables: can be either negative or positive.
unsigned variables: can only be positive.

unsigned int i;
int j; /*signed*/
--------
#include < stdio.h>
#include < math.h>
void main() {
int angle_degree;
double angle_radian, pi, value;

/* Print a header */
printf ("\nCompute a table of the sine function\n\n");

/* obtain pi once for all */
/* or just use pi = M_PI, where  M_PI is defined in math.h */
pi = 4.0 * atan(1.0);
printf ( " Value of PI = %f \n\n", pi );
printf ( " angle     Sine \n" );
angle_degree = 0; /* initial angle value */
/* scan over angle */

while (  angle_degree <= 360 )    {
angle_radian = pi * angle_degree/180.0 ;
value = sin(angle_radian);
printf ( " %3d      %f \n ", angle_degree, value );
angle_degree = angle_degree + 10;  }}
-------------
double atan(double x); arc tangent of x.
double sin(double x); sine of x.
----------
%d     integer  (10)
%.nd    integer (optional n = number of columns; if 0, pad with zeroes)
%ld    long integer
%f     floating-point number in fixed decimal format (10.500000)
%m.nf    float or double (optional m = number of columns,n = number of decimal places)
%.1f     floating-point number with 1 digit after the decimal (10.5)
%e     floating-point number in exponential (scientific notation) (1.050000e+01)
%g     floating-point number in either fixed decimal or exponential format depending on the size of the number (will not display trailing zeros) (10.5)
%ns    string (optional n = number of columns)
%c        character
---------
#include <stdio.h>
int main() {
int this_is_a_number;
printf( "Please enter a number: " );
/ *to read character, string, numeric data from keyboard */
scanf( "%d", &this_is_a_number );
printf( "You entered %d", this_is_a_number );
getchar();
return 0;
}
-----------
if (conditional_1)  {
...statements executed if conditional_1 is true...
} else if (conditional_2) {
...statements executed if conditional_2 is true...
} else {
...statements executed otherwise...
}

<    smaller than
<=    smaller than or equal to
==    equal to
!=    not equal to
>=    greater than or equal to
>    greater than

&&    and
||    or
!    not

1: true
0: false
----------------
#include <stdio.h>
int main() {
int age;
printf( "Please enter your age" );
scanf( "%d", &age );
if ( age < 100 )  printf ("You are pretty young!\n" );
else if ( age == 100 )  printf( "You are old\n" );     
else printf( "You are really old\n" );
return 0;
}
---------
i = initial_i;
while (i <= i_max){
  ...block of statements...
  i = i + i_increment;
}
----------
do {
} while ( condition );
-----------
for (i = initial_i; i <= i_max; i = i + i_increment) {
  ...block of statements...
}
----------
angle_degree = 0;
for ( ; ; ){
  ...block of statements...
  angle_degree = angle_degree + 10;
  if (angle_degree == 360) break;
}
-----------
break: exit the most immediately surrounding loop.
continue: begin to execute again from the top of the loop.
--------
constants
#define ANGLE_MIN 0
#define ANGLE_MAX 360
#define NAME "abcdef"
#define AGE (20 / 2)

It is customary to use capital letters in defining global constants.
---------
switch (expression) {
  case const_expression_1: { ...statements... break; }
  case const_expression_2: { ...statements... break; }
                                 default: { ...statements.. }
}
the case values may only be constant integral expressions.
-----------
int x;
for ( x = 0; x < 10; x++ ) printf( "%d\n", x );
----------
int x = 0;
while ( x < 10 ) {
  printf( "%d\n", x );
  x++; }
-----
int x = 0;
do { printf( "Hello, world!\n" ); } while ( x != 0 );
-------
pointer

defines px to be a pointer to objects of type float, and sets it equal to the address of x
float x;
float* px;
x = 6.5;
px = &x;

The content of the memory location referenced by a pointer is obtained using the * operator (this is called dereferencing the pointer). Thus, *px refers to the value of x.
C allows us to perform arithmetic operations using pointers, but beware that the unit in pointer arithmetic is the size (in bytes) of the object to which the pointer points. For example, if px is a pointer to a variable x of type float, then the expression px + 1 refers not to the next bit or byte in memory but to the location of the next float after x (4 bytes away on most workstations); if x were of type double, then px + 1 would refer to a location 8 bytes (the size of a double)away, and so on. Only if x is of type char will px + 1 actually refer to the next byte in memory.
------------
char* pc;
float* px;
float x;

x = 6.5;
px = &x;
pc = (char*) px;
the (char*) in the last line is a "cast", which converts one data type to another, px and pc both point to the same location in memory (the address of x) but px + 1 and pc + 1 point to different memory locations.
-----------
void main() {
float x, y;
float *fp, *fp2;
x = 6.5;
printf("Value of x is %f, address of x %ld\n", x, &x);
fp = &x;
printf("Value in memory location fp is %f\n", *fp);
*fp = 9.2;
printf("New value of x is %f = %f \n", *fp, x);
*fp = *fp + 1.5;
printf("Final value of x is %f = %f \n", *fp, x);
y = *fp;
fp2 = fp;
printf("Transfered value into y = %f and fp2 = %f \n", y, *fp2);
}
--------------
#include<stdio.h>
int main() {
int *ptr_one;

/*allocates the requested memory and returns a pointer to it.*/
ptr_one = (int *)malloc(sizeof(*ptr_one));

/*if (ptr_one == 0) { Eu acho que não pode usar zero*/
if (ptr_one == NULL) {
printf("ERROR: Out of memory\n");
return 1;
}
*ptr_one = 25;
printf("%d\n", *ptr_one);
free(ptr_one);
return 0;
}
----------
Arrays
type name[dim];
In C, arrays starts at position 0. The elements of the array occupy adjacent locations in memory. C treats the name of the array as if it were a pointer to the first element--this is important in understanding how to do arithmetic with arrays. Thus, if v is an array, *v is the same thing as v[0], *(v+1) is the same thing as v[1], and so on.

int a[4];
a[0] = 1;
a[1] = 2;
a[2] = 3;
a[3] = 4;
----------
#define SIZE 3
void main() {
float x[SIZE], *fp;
int   i;

for (i = 0; i < SIZE; i++) x[i] = 0.5 * (float)i;
for (i = 0; i < SIZE; i++) printf("  %d  %f \n", i, x[i]);
fp = x;
for (i = 0; i < SIZE; i++) printf("  %d  %f \n", i, *(fp + i));
}
---------
Multi-dimensional array

#include<stdio.h>
int main() {
int a[4][4], i , j;
for (i = 0; i < 4; i++) {
for ( j = 0; j < 4; j++) {
a[i][j] = 0;
printf("a[%d][%d] = %d \n", i, j, a[i][j]);
} }
return 0;
}
-----------
String is an array of characters. It is represented internally in C by the ASCII characters in the string, and terminated by the special null character "\0" so programs can find the end of the string.
---------
printf("Hello, world\n");
printf("The value of a is: %f\n", a);
--------
C provides the char type variable, which can contain one character (1 byte) at a time. A character string is stored in an array of character type, one ASCII character per location. Never forget that, since strings are conventionally terminated by the null character "\0", we require one extra storage location in the array!
---------
void main() {
char text_1[100], text_2[100], text_3[100];
char *ta, *tb;
int i;
/* set message to be an arrray  of characters; initialize it to the constant string "..." */
/* let the compiler decide on  its size by using [] */
char message[] = "Hello, I am a string; what are you?";
printf("Original message: %s\n", message);
/* copy the message to text_1   the hard way */
i = 0;
while ( (text_1[i] = message[i]) != '\0' ) i++;
printf("Text_1: %s\n", text_1);
/* use explicit pointer arithmetic */
ta = message;
tb = text_2;
while ( ( *tb++ = *ta++ )  !=  '\0' )  ;
printf("Text_2: %s\n", text_2);
}
--------
Eu acho que esse tipo de expressão deve ser evitada, por ser confusa.
*tb++ = *ta++

*tb = *ta;
tb++;
ta++:
------------
char *strcpy(s,ct)      copy  ct into s, including "\0"; return s
char *strncpy(s,ct,n)   copy ncharcater of ct into s, return s
char *strncat(s,ct)     concatenate ct to end of s; return s
char *strncat(s,ct,n)   concatenate n character of ct to end of s, terminate with "\0"; return s
int strcmp(ptr1,ptr2)       compare ptr1 and ptr2;
<0: the first character that does not match has a lower value in ptr1 than in ptr2
0: the contents of both strings are equal
>0: the first character that does not match has a greater value in ptr1 than in ptr2
char *strchr(cs,c)      return pointer to first occurence of c in cs or NULL if not encountered
size_t strlen(cs)       return length of cs
(s and t are char*, cs and ct are const char*, c is an char converted to type int, and n is an int.)
-----------
#include < string.h>
 void main() {
char line[100], *sub_text;

/* initialize string */
 strcpy(line,"hello, I am a string;");
printf("Line: %s\n", line);

/* add to end of string */
strcat(line," what are you?");
printf("Line: %s\n", line);

/* find length of string */
/* strlen brings back length as type size_t */
printf("Length of line: %d\n", (int)strlen(line));

/* find occurence of substrings */
if ( (sub_text = strchr ( line, 'W' ) )!= NULL )
printf("String starting with \"W\" ->%s\n", sub_text);
if ( ( sub_text = strchr ( line, 'w' ) )!= NULL )
printf("String starting with \"w\" ->%s\n", sub_text);
if ( ( sub_text = strchr ( sub_text, 'u' ) )!= NULL )
printf("String starting with \"w\" ->%s\n", sub_text);
}
-----------
stdin: standard input
stdout: standard output
stderr: standard error
---------
#include < stdio.h>
void main() {
int i, nc;
nc = 0;
i = getchar();
while (i != EOF) {
  nc = nc + 1;
  i = getchar();
}
printf("Number of characters in file = %d\n", nc);
}

This program counts the number of characters in the input stream (e.g. in a file piped into it at execution time).
The code reads characters (whatever they may be) from stdin (the keyboard), uses stdout (the X-terminal you run from) for output, and writes error messages to stderr (usually also your X-terminal).
----------
#include < stdio.h>
void main() {
int c, nc = 0;
while ( (c = getchar()) != EOF ) nc++;
printf("Number of characters in file = %d\n", nc);
}
----------
++nc; (nc is incremented before it is used)
nc++; (nc is used before it is incremented)
------------
#include < stdio.h>
void main() {
int c, nc = 0, nl = 0;
while ( (c = getchar()) != EOF ) {
nc++;
if (c == '\n') nl++;
}
printf("Number of characters = %d, number of lines = %d\n", nc, nl);
}
----------
scanf("format string", variables);
sprintf(string, "format string", variables);
scanf(string, "format string", variables);
----------
#include < stdio.h>
FILE *fp;
fp = fopen(name, mode);
fscanf(fp, "format string", variable list);
fprintf(fp, "format string", variable list);
fclose(fp );
------------
fopen(filename, mode);
mode    Description
"r"     Open a file for reading. The file must exist.
"w"     Create an empty file for writing. If a file with the same name already exists its content is erased and the file is considered as a new empty file.
"a"     Append to a file. Writing operations append data at the end of the file. The file is created if it does not exist.
"r+"     Open a file for update both reading and writing. The file must exist.
"w+"     Create an empty file for both reading and writing.
"a+"     Open a file for reading and appending.
------------
#include < stdio.h>
void main() {
FILE *fp;
int i;
fp = fopen("foo.dat", "w"); /* open foo.dat for writing */
fprintf(fp, "\nSample Code\n\n");  /* write some info */
for (i = 1; i <= 10 ; i++) fprintf(fp, "i = %d\n", i);
fclose(fp);  /* close the file  */
}
-------------
FUNCTIONS

return-type function-name ( argument-list-if-necessary )
{
    ...local-declarations...
    ...statements...
    return return-value;
}

Functions need to be declared before being called
(except main?? main() is usually the first function in the program. But by that logic, main() should be the last function in the program...)
Or they can be prototyped.
I think we should avoid prototyping, it just increases overhead.

function1 (); /* prototype, so the compiler knows beforehand there is a function1 declared somewhere */
main() {}
function1 () {}
function2() {}

local variable is declared inside a function and can only be used inside the function.
global variable is declared outside all functions (including main()) and can be used in all functions.
---------
#include<stdio.h>
int A, B;
int Add() {return A + B; }

main() {
int answer;
A = 5; B = 7;
answer = Add();
printf("%d\n",answer);
}
---------
#include < stdio.h>
#include < string.h>
void main() {
int  n;
char string[50];
strcpy(string, "Hello World");
n = n_char(string);
printf("Length of string = %d\n", n);
}

int n_char(char string[]) {
int n;
n = strlen(string);
if (n > 50)  printf("String is longer than 50 characters\n");
return n;
}
----------
Arguments are always passed by value in C function calls. This means that local copies of the values of the arguments are passed to the routines. Any change made to the arguments internally in the function are made only to the local copies of the arguments. In order to change (or define) an argument in the argument list, this argument must be passed as an address, thereby forcing C to change the real argument in the calling routine.
------------
#include < stdio.h>
void exchange ( int *a, int *b );
void main() {
int a, b;
a = 5;
b = 7;
printf("From main: a = %d, b = %d\n", a, b);
exchange(&a, &b);
printf("Back in main: ");
printf("a = %d, b = %d\n", a, b);
}

void exchange ( int *a, int *b ) {
int temp;
temp = *a;
*a = *b;
*b = temp;
printf(" From function exchange: ");
printf("a = %d, b = %d\n", *a, *b);
}
------------
Command-line arguments

main(int argc, char** argv)
(The syntax char** argv declares argv to be a pointer to a pointer to a character, that is, a pointer to a character array (a character string)--in other words, an array of character strings. You could also write this as char* argv[]. )

For example, if you typed
a.out -i 2 -g -x 3 4
the program would receive
argc = 7
argv[0] = "a.out"
argv[1] = "-i"
argv[2] = "2"
argv[3] = "-g"
argv[4] = "-x"
argv[5] = "3"
argv[6] = "4"
---------
#include < stdio.h>
main(int argc, char** argv) {
int i;
printf("argc = %d\n", argc);
for (i = 0; i < argc; i++) printf("argv[%d] = \"%s\"\n", i, argv[i]);
}
---------
#include < stdio.h>
#include < stdlib.h>
main(int argc, char** argv) {
int a_value = 0;
float b_value = 0.0;
char* c_value = NULL;
int d1_value = 0, d2_value = 0;
int i;
/* Start at i = 1 to skip the command name. */
for (i = 1; i < argc; i++) {
/* Check for a switch (leading "-"). */
if (argv[i][0] == '-') {
/* Use the next character to decide what to do. */
switch (argv[i][1]) {
case 'a':    a_value = atoi(argv[++i]); break;
case 'b':    b_value = atof(argv[++i]); break;
case 'c':    c_value = argv[++i]; break;
case 'd':    d1_value = atoi(argv[++i]); d2_value = atoi(argv[++i]); break;
}}}
printf("a = %d\n", a_value);
printf("b = %f\n", b_value);
if (c_value != NULL) printf("c = \"%s\"\n", c_value);
printf("d1 = %d, d2 = %d\n", d1_value, d2_value);
}

Note that argv[i][j] means the j-th character of the i-th character string.
----------
#include < stdio.h>
#include < stdlib.h>
void get_args(int argc, char** argv, int* a_value, float* b_value) {
int i;
/* Start at i = 1 to skip the command name. */
for (i = 1; i < argc; i++) {
/* Check for a switch (leading "-"). */
if (argv[i][0] == '-') {
/* Use the next character to decide what to do. */
switch (argv[i][1]) {
case 'a':    *a_value = atoi(argv[++i]); break;
case 'b':    *b_value = atof(argv[++i]); break;
default:    fprintf(stderr, "Unknown switch %s\n", argv[i]);
} } } }

main(int argc, char** argv) {
/* Set defaults for all parameters: */
int a = 0;
float b = 0.0;
get_args(argc, argv, &a, &b);
printf("a = %d\n", a);
printf("b = %f\n", b);
}
-------------
printf("Please enter the value of n: ");
scanf("%d", &n);

printf("Please enter the value of x: ");
scanf("%f", &x);
---------
STRUCT

#include<stdio.h>
struct telephone {
char *name;
int number;
};

int main() {
struct telephone index;
index.name = "Jane Doe";
index.number = 12345;
printf("Name: %s\n", index.name);
printf("Telephone number: %d\n", index.number);
return 0;
}
------------
TYPEDEF

#include<stdio.h>
typedef int *int_ptr;
int main() {
int_ptr myvar;
return 0;
}
--------------
#include<stdio.h>
typedef struct telephone {
char *name;
int number;
}TELEPHONE;

int main() {
TELEPHONE index;
index.name = "Jane Doe";
index.number = 12345;
printf("Name: %s\n", index.name);
printf("Telephone number: %d\n", index.number);
return 0;
}
-------------
#include<stdio.h>
typedef struct telephone {
char *name;
int number;
}TELEPHONE;

int main() {
TELEPHONE index;
TELEPHONE *ptr_myindex;
ptr_myindex = &index;
ptr_myindex->name = "Jane Doe";
ptr_myindex->number = 12345;
printf("Name: %s\n", ptr_myindex->name);
printf("Telephone number: %d\n", ptr_myindex->number);
return 0;
}
-----------
A union is like a structure in which all members are stored at the same address. 
A union stores different data types in the same memory location.
Only one member can contain a value at any given time.

#include<stdio.h>
typedef union myunion {
double PI;
int B;
}MYUNION;

int main() {
MYUNION numbers;
numbers.PI = 3.14;
numbers.B = 50;
return 0;
}
----------
#include <stdio.h>
#include <string.h>
union Data { int i; float f; char  str[20]; };

int main( ) {
union Data data;
printf( "Memory size occupied by data : %d\n", sizeof(data));
return 0;
}
----------
#include <stdio.h>
#include <string.h>
union Data { int i; float f; char  str[20]; };

int main( ) {
union Data data;      
data.i = 10;
data.f = 220.5;
strcpy( data.str, "C Programming");
printf( "data.i : %d\n", data.i);
printf( "data.f : %f\n", data.f);
printf( "data.str : %s\n", data.str);
return 0;
}

data.i : 1917853763
data.f : 4122360580327794860452759994368.000000
data.str : C Programming

The data gets corrupted. Only the last value is assigned.
----------------
Preprocessor Directives

The C preprocessor modifies a source file before handing it over to the compiler.

#include <filename>
paste the text of filename into the current file.
If filename cannot be found, compilation will cease with an error.

#define MAX(a, b) ((a) > (b) ? (a) : (b))
To define a multiline macro, each line before the last should end with a \, which will result in a line continuation.

#undef
undefines a constant or preprocessor macro defined previously using #define.

#define E 2.71828
int e_squared = E * E;
#undef E