| Goals for this chapter: |
|
The C language offers different types of data: int for integers, double and float for real numbers and char for characters.
For example, the following declaration
int i,j;
char str[24];
float degc, degf;
are valid C data declaration.
For integers C offers differents containers of data
long pencil;
short pen;
The difference between these types
The previous definitions are variable. To set constants there are two modes:
#define PI 3.141515
#define A 90.0
#define __isascii(c) (((c) & ~0x7f) ==
0)
#define __tobody(c, f, a, args) \
(__extension__
\
({ int __res;
\
if (sizeof (c) > 1)
\
{
\
if (__builtin_constant_p
(c))
\
{
\
int __c = (c);
\
__res = __c < -128 || __c > 255 ? __c : a[__c];
\
}
\
else
\
__res = f args;
\
}
\
else
\
__res = a[(int) (c)];
\
__res; }))
const char mychar = "C Programming";
While define are const are equivalent for non-strings definitions,
only the using const is possible to define constants.
We note in the previous example that define may works like functions. We also note the Operator "? :"
This operator is equivalent to a if-then-else statement.
Suppose that you write
(A> B) ? C : D
This is equivalent to the following code:
if (A > B) {
C
} else {
D
}
For example is usefull also in return.
For example return (a>0) ? a ? b;
Now, we will resume all this data in a simgle program, printing regular data, maximum and minimum values for each variable. The limits of the C are listed in the include file, <limits.h> .
In C is also possible to use the enum, for example
enum colors {Green, Red, Yellow }
enum days { MON = 1, TUE, WED, THU, FRI, SAT, SUN }
Of course, TUE will be 2, WED will be 3, etc.
Other more complex enum definitions are:
enum { XmSTRING_DIRECTION_L_TO_R,
XmSTRING_DIRECTION_R_TO_L,
XmSTRING_DIRECTION_UNSET
= 3,
XmSTRING_DIRECTION_DEFAULT
= XmDEFAULT_DIRECTION
};
Of course, is possible to built its own types using structures and unions, See the section: Structures in this chapter.
Some examples are:
typedef enum{ XmFONT_IS_FONT, XmFONT_IS_FONTSET
} XmFontType;
typedef unsigned char XmStringDirection;
typedef union __XmStringRec *XmString;
/* opaque to outside */
typedef XmString * XmStringTable;
/* opaque to outside */
typedef char *
XmStringCharSet; /* Null term
string */
typedef char *
XmStringTag;
/* Null term string */
typedef unsigned char XmStringComponentType;
/* component tags */
C offers the possibility to print data in formated mode.
| Printf Argument | Description |
| %d %i | Print a decimal number |
| %6d | Print a decimal number with up to 6 digits |
| %f | Print a float |
| %.4f | Print a float with 4 decimals |
| %6.4f | Prints a float 6 digit float and 4 decimals |
| %u | Prints int without sign |
| %o | Prints octal numbers |
| %x, %X | Prints hexadecimal |
| %c | Prints a character |
| %s | Prints a string |
| %20s | Prints a string 20 characters long |
| %-20s | Prints a string 20 characters long alignment to left. |
In C are also used the following C escape sequence:
ASCII Name
Description
C Escape Sequence
nul
null byte
\0
bel
bell character
\a
bs
backspace
\b
ht
horizontal tab
\t
np
formfeed
\f
nl
newline
\n
cr
carriage return
\r
In the section C Operators we will offer a complete introduction to these operators, however now we will introduce the cycle for, to print sin and cos, from 0 until 64 degree.
My first serious project when I enter in UCV (Caracas - Venezuela), in 1980, was to use the faculty computer a Burroghs system which covers a big surface (about 4 normal rooms), to print a similar table.
Starting from this table and using the sin (64) and the formulae for six(x/2), I offers a proof that is possible to built the same table with a simple desk calculator, with four five operations: '+', '-', 'x', '/' and 'sqrt'. In Chapter 1, I introduce an algorithm to get the cubic root from the squared root.
#include <math.h>
main ()
{
int i;
for (i=0; i <=
64; i++) {
printf ("%d %.4f %.4f\n", i, sin(i), cos(i));
}
}
Because we use a function sin(x) that belong to the mathematical library we need to add it to the compilation line.
[root@ftosx1 Chap2]# cc sin64.c -o sin64 -lm
Then, we will have the table
[root@ftosx1 Chap2]# ./sin64
0 0.0000 1.0000
1 0.8415 0.5403
2 0.9093 -0.4161
3 0.1411 -0.9900
4 -0.7568 -0.6536
...
In C is also possible to align strings to right or left.
[root@ftosx1 Chap2]# more align.c
main()
{
char ruler [] = "012345678901234567890123456789";
char str1 [] = "Brian
Kernimgham";
char str2 [] = "C
is cool language";
printf ("%s\n", ruler);
printf ("%20s\n",
str1);
printf ("%-20s\n",
str2);
}
[root@ftosx1 Chap2]#
There are also other importants data objects like array of characters and pointers.
char * string;
char string[];
The first declaration is a pointer to char, while the second is a vector of char.
We can define for example:
char mystr[] = "Hello!"
We don't need to alloc memory for this because this happens automatically.
A simple C source explains this:
[root@ftosx1 Chap2]# more array.c
main()
{
char mystr[] = "Hello!";
puts (mystr);
printf ("%c %c\n",
mystr[0], mystr[3]);
}
[root@ftosx1 Chap2]# make array
[root@ftosx1 Chap2]# ./array
Hello!
H l
[root@ftosx1 Chap2]#
The Pointer is a variable that contains the address of another variable. Now, we will write two simple examples that generate correct situation that can create bad situations and also clear bad situations.
We can use also the pointer concept like we did in the previous example.
[root@ftosx1 Chap2]# more array2.c
main()
{
char * mystr = "Hello!";
puts (mystr);
printf ("%c %c\n", mystr[0], mystr[3]);
}
[root@ftosx1 Chap2]#
If we don't change the pointer, everything works!
[root@ftosx1 Chap2]# make array2
cc array2.c -o array2
[root@ftosx1 Chap2]# ./array2
Hello!
H l
[root@ftosx1 Chap2]#
But, if we change the pointer "everything" (for an indefinite situation) may happens.
[root@ftosx1 Chap2]# more array3.c
main()
{
char * mystr = "Hello!";
puts (mystr);
printf ("%c %c\n", mystr[0], mystr[3]);
strcpy (mystr, "We change now!");
printf ("%c %c\n", mystr[0], mystr[3]);
}
[root@ftosx1 Chap2]# make array3
cc array3.c -o array3
[root@ftosx1 Chap2]# ./array3
Hello!
H l
Segmentation fault
[root@ftosx1 Chap2]#
The previous segmentation fault happens because we try to use an unallocated memory position.
Now, we will illustrate better this problems generating a segmentation fault!
[root@ftosx1 Chap2]# more array4.c
main()
{
// Allocated variable;
char mystr[14];
strcpy (mystr, "We
change now!");
puts (mystr);
printf ("%c %c\n",
mystr[0], mystr[3]);
strcpy (mystr, "We
change now with a very very long string!");
puts (mystr);
}
[root@ftosx1 Chap2]#
[root@ftosx1 Chap2]# make array4
cc array4.c -o array4
[root@ftosx1 Chap2]# ./array4
We change now!
W c
We change now with a very very long string!
Segmentation fault
[root@ftosx1 Chap2]#
Therefore is clear that when we use pointers, pointers must point to allocated variable with the sufficient ammount of memory.
Now, we will cover an example using point to integers, and using pointers to print the information where the pointer points.
[root@ftosx1 Chap2]# more array5.c
main()
{
// Allocated variable;
int a[10];
a[0] = 0;
a[1] = 1;
a[2] = 2;
a[3] = 3;
a[4] = 4;
a[5] = 5;
a[6] = 6;
a[7] = 7;
a[8] = 8;
a[9] = 9;
printf ("%d, %d, %d\n",
a[0], a[1], a[9]);
}
[root@ftosx1 Chap2]#
Therefore, a is a simple vector where each position includes an integer that represent its position.
Now, we use a point and print the information that this pointer points!
[root@ftosx1 Chap2]# more array6.c
main()
{
// Allocated variable;
int a[10];
int *pa;
a[0] = 0;
a[1] = 1;
a[2] = 2;
a[3] = 3;
a[4] = 4;
a[5] = 5;
a[6] = 6;
a[7] = 7;
a[8] = 8;
a[9] = 9;
// Now 'pa' points
to the element 0 of the array a.
pa = &a[0];
// ... and we print
its contents
printf ("%d\n", *pa);
// Now 'pa' points
to the element 0 of the array a.
pa = &a[4];
// ... and we print
its contents
printf ("%d\n", *pa);
}
[root@ftosx1 Chap2]# make array6
cc array6.c -o array6
[root@ftosx1 Chap2]# ./array6
0
4
[root@ftosx1 Chap2]#
The line
pa = &a[0];
is equivalent to:
pa = a;
because a is equivalent to &a[0].
We can also prints the next position where points the pointer and also the n-position, where n must be a valid position.
We clean the previous example and transform it a more classical code.
[root@ftosx1 Chap2]# more array7.c
main()
{
// Allocated variable;
int a[10], i;
int *pa;
for (i=0; i<=9;
i++)
a[i] = i;
// Now 'pa' points
to the element 0 of the array a.
pa = a;
// ... and we print
its contents
printf ("%d\n", *pa+6);
}
[root@ftosx1 Chap2]#
[root@ftosx1 Chap2]# make array7
cc array7.c -o array7
[root@ftosx1 Chap2]# ./array7
6
The next step on Pointers is a vector of pointers:
We can also create a vector of Pointers, for example the declaration:
static char * myweek [] = { "Linux", "StarOffice", "KDE", "Java", "PHP", "Netscape", "Number Theory", "Relativity" };
create an array of six pointers.
These pointers automically allocated from the previous declaration.
[root@ftosx1 Chap2]# more vector_pointer.c
main(int argc, char ** argv[])
{
int i;
static char * myweek
[] = {"Linux", "StarOffice", "KDE", "Java", "PHP", "Number Theory", "Relativity"
};
for (i = 0; i <=
6; i++) {
printf ("%s\n", myweek[i]);
}
return 0;
}
[root@ftosx1 Chap2]#
[root@ftosx1 Chap2]# make vector_pointer
cc vector_pointer.c -o vector_pointer
[root@ftosx1 Chap2]# ./vector_pointer
Linux
StarOffice
KDE
Java
PHP
Number Theory
Relativity
[root@ftosx1 Chap2]#
Pointers may be passed as functions parameters, pointers may be entire structures and are used anywhere. This argument is covered in C Functions
In C programing for X11, or Motif (See X Windows Course), or Networking programming covered in this course we can find real structures declaration as follows:
struct arphdr
{
unsigned short int ar_hrd;
/* Format of hardware address. */
unsigned short int ar_pro;
/* Format of protocol address. */
unsigned char ar_hln;
/* Length of hardware address. */
unsigned char ar_pln;
/* Length of protocol address. */
unsigned short int ar_op;
/* ARP opcode (command). */
#if 0
/* Ethernet looks like this : This bit is
variable sized
however... */
unsigned char __ar_sha[ETH_ALEN];
/* Sender hardware address. */
unsigned char __ar_sip[4];
/* Sender IP address. */
unsigned char __ar_tha[ETH_ALEN];
/* Target hardware address. */
unsigned char __ar_tip[4];
/* Target IP address. */
#endif
};
In X11.h we can find:
typedef union _XEvent {
int type;
/* must not be changed; first element */
XAnyEvent xany;
XKeyEvent xkey;
XButtonEvent xbutton;
XMotionEvent xmotion;
XCrossingEvent xcrossing;
XFocusChangeEvent
xfocus;
XExposeEvent xexpose;
XGraphicsExposeEvent
xgraphicsexpose;
XNoExposeEvent xnoexpose;
XVisibilityEvent
xvisibility;
XCreateWindowEvent
xcreatewindow;
XDestroyWindowEvent
xdestroywindow;
XUnmapEvent xunmap;
XMapEvent xmap;
XMapRequestEvent
xmaprequest;
XReparentEvent xreparent;
XConfigureEvent xconfigure;
XGravityEvent xgravity;
XResizeRequestEvent
xresizerequest;
XConfigureRequestEvent
xconfigurerequest;
XCirculateEvent xcirculate;
XCirculateRequestEvent
xcirculaterequest;
XPropertyEvent xproperty;
XSelectionClearEvent
xselectionclear;
XSelectionRequestEvent
xselectionrequest;
XSelectionEvent xselection;
XColormapEvent xcolormap;
XClientMessageEvent
xclient;
XMappingEvent xmapping;
XErrorEvent xerror;
XKeymapEvent xkeymap;
long pad[24];
} XEvent;
In Xm.h we can find:
typedef struct
{
int reason;
XEvent *event;
} XmAnyCallbackStruct;
Note how structures may includes others that may be installed or not. Generally very few systems install Motif today (RedHat continues to use LessTif a Motif clone). FTOSX install OpenMotif, the original.
Now, we present an example about how we can setup our own typedefs.
Suppose that you want write a program to list your friends at college:
C offers structures and union for this kind of data, however C offers also the typedef to create our own types.
[root@ftosx1 Chap2]# more structures.c
typedef struct _student {
char name[20];
char address [50];
int id;
int age;
char sex;
} student;
main ()
{
student john;
strcpy(john.name,
"John Smith");
strcpy(john.address,
"1620 26th Street - Santa Monica");
john.id = 42571;
john.age = 18;
john.sex = 'M';
printf ("The data request is the following:\n\t%s\n\t%s\n\t%d\n\t%d\n\t%c\n", john.name, john.address, john.id, john.age, john.sex);
}
[root@ftosx1 Chap2]#
[root@ftosx1 Chap2]# make structures
cc structures.c -o structures
[root@ftosx1 Chap2]# ./structures
The data request is the following:
John Smith
1620 26th Street
- Santa Monica
42571
18
M
[root@ftosx1 Chap2]#
A union is similar to a structure but only one of its member is in use.
For example, we can define:
union {
/* prime number */
short is_prime;
/* composite */
short is_not_prime;
} is_prime
or for example:
union {
char single_name[40];
char marital_lastname[40];
char complete_divorcedname[60];
} marital_info;
Yo access members we use the classic mode: marital_info.single_name
Any data type is a set of bits. Therefore a number may be a string and a string may be a number.
These conversions are possible. For example we can covert a string (like
"3098" to its relative integer 3098, a number).
main ()
{
char string [] =
"3098";
int myint;
printf ("%d\n", myint = atoi(string));
printf ("like a test
%d\n", myint + 1);
}
[root@ftosx1 Chap2]# make atoi
cc atoi.c -o atoi
[root@ftosx1 Chap2]# ./atoi
3098
like a test 3099
The same is valid for double or float
[root@ftosx1 Chap2]# more strtod.c
#include <stdlib.h>
main ()
{
char string [] =
"-3.141516098";
double mydouble;
printf ("%f\n", mydouble = strtod(string, NULL));
printf ("like a test
%f\n", mydouble + 1);
}ec
[root@ftosx1 Chap2]#
[root@ftosx1 Chap2]# make strtod
cc strtod.c -o strtod
[root@ftosx1 Chap2]# ./strtod
-3.141516
like a test -2.141516
[root@ftosx1 Chap2]#
Is possible make also reverse operations, for example a number that become a string, but this is inmmediate.
[root@ftosx1 Chap2]# more number2string.c
#include <stdio.h>
main()
{
double mydouble =
3.141516;
char mystr[14];
sprintf (mystr, "%f\n", mydouble);
printf ("%s and its fifth character is: %c\n", mystr, mystr[4]);
}
[root@ftosx1 Chap2]#
[root@ftosx1 Chap2]# make number2string
cc number2string.c -o number2string
[root@ftosx1 Chap2]# ./number2string
3.141516
and its fifth character is: 1
[root@ftosx1 Chap2]#
Of course an analog conversion may be made from any type to any string.
Generally the reciprocal fprintf functions are the scanf function, used to join in a single string, different types.
This is normally the mode things works.
C like a 'beautiful' language includes its operators.
These operators may be classified as follows:
Any language offers the possibility to
Formally we have: +, - * / %
For example we can create assignments like:
a = (b - 1)/(c + d);
or
if ( n % 2 == 0) {
puts ("n is even")
} else {
puts ("n is odd");
}
To write complex programs is necessary to move the program flow to determinate positions in the source to fill variables or make math for special purpose.
Formally we have: > >= < <=
and :== and !=, for equal and different.
The incremental operators are ++ and --.
Examples are:
n[i++] = b[--j];
The variable is incremented with ++, evaluating the previous or the
subsequent position depending of the operator position.
Formally we have: &, |, ^, <<. >> and ~
These operators represent the standard and have the common meaning,
as follows:
| Bit Operator | Description |
| & | AND |
| | | OR |
| ^ | OR esclusiv |
| << | shift to left |
| >> | shift to right |
| ~ | complement to one |
These operators are used as to resume assigments.
For example we have:
If we write normally, a = a + b;
we can write, the same instruction using an assigment operator as: a += b;
The same is valid for any operation:
c /= f;
d %= h;
i -= j;
g *= j;
| Operators | Precedence |
| () [ ] -> . | left to right |
| ! - ++ -- + - * & (type) sizeof | right to left |
| * / % | 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 |
This short section what to present regular statements and C common expression.
For conditionals we have:
if ( ( fd = open (dirname, O_RDONLY), 0)) == -1 )
|| fstat (fd, &
stbuf ) == -1
|| (stbuf.st_mode
& S_IFMT ) != S_IFDIR
|| (dp = (DIR *)
malloc (sizeof(DIR))) == NULL)
return NULL;
The classical if-then-else, may be something like:
if (a != b)
a = b
else
a = a + 1;
The previous statement may be written as:
a = (a !=b) ? b : a+1;
C offers also a long-if, called switch
switch (c) {
case 'a':
n += f[90];
break;
case 'c':
n += f[90];
break;
default:
n = 0;
break;
}
For cycles we can have:
for (i=0; i<= j; i++) {
printf ("%i\n", h[i]);
}
or
do {
a += c + b[490];
}
or
while (scanf ("%lf", &v) == 1)
printf ("%.5f\n", sum += v);
We can also represent infinite loops with while and for in the following mode.
while (1) and
for (;;)
C offers a break and continue statement to exit from cycles or continue it
while (1) {
printf ("I must study C Language)
if (I_know_C == 1)
break;
else
continue; // the
previous else is not necessary. We includes to present the continue statement.
}
In the past C supports also the famous (and innecessary) goto. However this instruction now had been removed from gcc.
The function "main" is called in this mode because is the place where starts the program and any other new function written will be secondary. For example
[root@ftosx1 Chap2]# more factorial.c
main ()
{
fact(9);
}
int fact (int last)
{
int i, result;
result = last;
for (i=last-1;i>=2;
i--)
result *= i;
printf ("%ld\n", result);
}
[root@ftosx1 Chap2]#
Is possible to declare also static functions that haves a special area in the memory.
In the rest of the chapter we will explain how to create libraries and offers some examples.
From the beginning of UNIX system, and the C language is possible to compat C objects in libraries and use it when necessary. For example, any Linux program uses the libc.a in shared or static mode.
In this section we will show how to create and use a library. The next Chapter 3: The functions of the "libc" library presents all the normal functions present in that library, and this is the role of a programmer.
Study a library, write programs using that or other library. The libX11.a is a library, the Motif library is libXm.a and the same is valid for Troll's Qt or Gtk.
To write programs that take advantage of Networking services: ftp, nfs or other is necessary to know the structures and libs about networking, and so on.
We will start this section splitting two sources to create a library.
Therefore we now will split the latest source, factorial.c in two sources factorial1.c factorial2.c
Thus, we have:
[root@ftosx1 Chap2]# more factorial?.c
::::::::::::::
factorial1.c
::::::::::::::
//2 "main2.c"
main ()
{
fact(9);
}
::::::::::::::
factorial2.c
::::::::::::::
int fact (int last)
{
int i, result;
result = last;
for (i=last-1;i>=2;
i--)
result *= i;
printf ("%ld\n", result);
}
[root@ftosx1 Chap2]#
q
Now, will compile (without to create the binary) each source.
[root@ftosx1 Chap2]# cc -c factorial1.c
The previous command create the object. the '.o' file.
[root@ftosx1 Chap2]# ls -al factorial1.o
-rw-r--r-- 1 root
root 828 Sep 24 15:21
factorial1.o
Now, we repeat the procedure for the second source.
[root@ftosx1 Chap2]# cc -c factorial2.c
[root@ftosx1 Chap2]# ls -al factorial?.o
-rw-r--r-- 1 root
root 828 Sep 24 15:21
factorial1.o
-rw-r--r-- 1 root
root 956 Sep 24 15:21
factorial2.o
[root@ftosx1 Chap2]#
Now, we have two objects.
To create the binary we need to run the following command:
[root@ftosx1 Chap2]# cc factorial1.o factorial2.o -o factorial
[root@ftosx1 Chap2]# ./factorial
362880
[root@ftosx1 Chap2]#
Therefore working with two sources we can get the same results.
The second program factorial2.c, includes the function that does all the job: factorial.
We can create a library with this function and use when necessary.
To create a library we need to run the following command:
[root@ftosx1 Chap2]# ar -r libfactorial.a factorial2.o
Don't forget to run the ranlin program
[root@ftosx1 Chap2]# ranlib libfactorial.a
Our small and new library:
[root@ftosx1 Chap2]# ls -al libfactorial.a
-rw-r--r-- 1 root
root 1098 Sep 24 15:29
factorial.a
[root@ftosx1 Chap2]#
Haves the same properties that the classical an important libc.a
[root@ftosx1 Chap2]# file /usr/lib/libc.a
/usr/lib/libc.a: current ar archive
[root@ftosx1 Chap2]#
[root@ftosx1 Chap2]# file factorial.a /usr/lib/libc.a
factorial.a: current ar archive
/usr/lib/libc.a: current ar archive
[root@ftosx1 Chap2]#
Of course, we can list the objects included in the library:
[root@ftosx1 Chap2]# ar -t libfactorial.a
factorial2.o
[root@ftosx1 Chap2]#
... and of course also in the libc.a
[root@ftosx1 Chap2]# ar -t /usr/lib/libc.a | more
init-first.o
libc-start.o
set-init.o
sysdep.o
version.o
check_fds.o
errno-loc.o
iconv_open.o
iconv.o
iconv_close.o
gconv_open.o
gconv.o
gconv_close.o
gconv_db.o
...
Now, we will compile the factorial program (binary) using this new library.
[root@ftosx1 Chap2]# cc factorial1.o -o factorial -L./ -lfactorial
[root@ftosx1 Chap2]# ./factorial
362880
[root@ftosx1 Chap2]#
We will update our source factorial1.c, to get a more big factorial
[root@ftosx1 Chap2]# more factorial1.c
//2 "main2.c"
main ()
{
fact(11);
}
[root@ftosx1 Chap2]# cc factorial1.c -o factorial -L./ -lfactorial
[root@ftosx1 Chap2]# ./factorial
39916800
[root@ftosx1 Chap2]#
Note that we includes the .c file in the command line, that allows to create the object file, and the binary running the compiler and loading the library.
The parameter, -L, inform the compiler where to look to search the library.
The library, libfactorial.a, uses the synonymous -lfactorial (without the words lib and without the extension .a) to compile.
In the same way, compiling with -lX11, will call the library libX11.a and compiling with -lqt means that we are looking for the libqt.a
This may be solved using the LD_LIBRARY_PATH function.
Know the language, using the libraries and think how to apply is the work of a programmer.
In nowadays, is more fascinating than in the past because people have free access to all the source.
Welcome to the Programming World!
In Linux is common to use shared libraries. A shared library is a set of shared objects. A shared object is a special object created by the compiler capable to loaded by the kernel in memory. Any subsequent will take advantage of the library present in memory.
The gcc manual page explains this
-shared
Produce a shared object which can then be linked with other objects to
form an executable.
Only a few systems support this option.
The GNU Team to create shared library, develop the libtool. Using this command or tool is possible to develop and create shared libraries easy.
Of course we need to create the shared object. We will use libtool from now, however here libtool is not necessary.
[root@ftosx1 Chap2]# libtool cc -shared factorial2.c -o libfactorial.so
Our new and small shared library, haves the same file type that famous shared libraries like Qt.
[root@ftosx1 Chap2]# file libfactorial.so /usr/lib/qt-2.3.1/lib/libqt.so.2.3.1
libfactorial.so:
ELF 32-bit LSB shared object, Intel 80386, version 1, not stripped
/usr/lib/qt-2.3.1/lib/libqt.so.2.3.1: ELF 32-bit LSB shared
object, Intel 80386, version 1, not stripped
[root@ftosx1 Chap2]#
Now, using libtool again. Here is where libtool plays its role.
[root@ftosx1 Chap2]# libtool gcc -O -o factorial factorial1.o ./libfactorial.so
Therefore, we have
[root@ftosx1 Chap2]# ./factorial
3628800
[root@ftosx1 Chap2]# libtool gcc -o libfactorial.la
rm -fr .libs/libfactorial.la .libs/libfactorial.* .libs/libfactorial.*
ar cru .libs/libfactorial.al
ranlib .libs/libfactorial.al
creating libfactorial.la
(cd .libs && rm -f libfactorial.la && ln -s
../libfactorial.la libfactorial.la)
[root@ftosx1 Chap2]#
[root@ftosx1 Chap2]# ls -al libfactorial.*
-rw-r--r-- 1 root
root 1098 Sep 24 18:29
libfactorial.a
-rwxr-xr-x 1 root
root 5665 Sep 24 18:55
libfactorial.so
[root@ftosx1 Chap2]#
Now, we will update the factorial to calculate a new number.
[root@ftosx1 Chap2]# more factorial1.c
//2 "main2.c"
main ()
{
fact(15);
}
[root@ftosx1 Chap2]#
[root@ftosx1 Chap2]# libtool gcc -O -o factorial factorial1.c
./libfactorial.so
gcc -O -o factorial factorial1.c ./libfactorial.so
[root@ftosx1 Chap2]# ./factorial
2004310016
[root@ftosx1 Chap2]
libtool may also be used to create static (lib*.a) libraries:
[root@ftosx1 Chap2]# libtool gcc -g -O -o libfactorial.a factorial2.o
ar cru libfactorial.a factorial2.o
ranlib libfactorial.a
[root@ftosx1 Chap2]#
In this case libtool rans also the ranlib command for the static library!
We can compile and create a new binary for test purpose, linking to the static instead of the shared.
[root@ftosx1 Chap2]# cc factorial1.o -o factorial_static -L./
-lfactorial
[root@ftosx1 Chap2]# time ./factorial_static
2004310016
real 0m0.006s
user 0m0.000s
sys 0m0.000s
[root@ftosx1 Chap2]# time ./factorial
./factorial: error while loading shared libraries: ./libfactorial.so:
cannot open shared object file: No such file or directory
real 0m0.003s
user 0m0.000s
sys 0m0.000s
[root@ftosx1 Chap2]#
Is clear that the shared version also in this simple example, needs less CPU time. In this case just the 50% less.
For example, the Troll Qt, is created in a similar mode:
[root@ftosx1 root]# file /usr/lib/qt-2.3.1/lib/libqt.so.2.3.1
/usr/lib/qt-2.3.1/lib/libqt.so.2.3.1: ELF 32-bit LSB shared
object, Intel 80386, version 1, not stripped
[root@ftosx1 root]#
g++ --whole-archive -shared -Wl,-soname,libqt.so.3 -Wl,-rpath,/root/qt/lib/
-o libqt.so.3.0.0 .obj/release/qapplication_x11.o .obj/release/qclipboard_x11.o
.obj/release/qcolor_x11.o .obj/release/qcursor_x11.o .obj/release/qdnd_x11.o
.obj/release/qdesktopwidget_x11.o .obj/release/qfont_x11.o .obj/release/qinputcontext_x11.o
.obj/release/qmotifdnd_x11.o .obj/release/qpixmap_x11.o .obj/release/qpaintdevice_x11.o
.obj/release/qpainter_x11.o .obj/release/qregion_x11.o .obj/release/qsound_x11.o
.obj/release/qwidget_x11.o .obj/release/qnpsupport.o .obj/release/qwidgetcreate_x11.o
.obj/release/qprinter_unix.o .obj/release/qpsprinter.o .obj/release/qprocess_unix.o
.obj/release/qthread_unix.o .obj/release/qabstractlayout.o .obj/release/qucomextra.o
.obj/release/qaccel.o .obj/release/qapplication.o .obj/release/qasyncimageio.o
.obj/release/qasyncio.o .obj/release/qbitmap.o .obj/release/qclipboard.o
.obj/release/qcolor.o .obj/release/qcolor_p.o .obj/release/qcomplextext.o
.obj/release/qconnection.o .obj/release/qcursor.o .obj/release/qdragobject.o
.obj/release/qdrawutil.o .obj/release/qdropsite.o .obj/release/qevent.o
.obj/release/qfocusdata.o .obj/release/qfont.o .obj/release/qfontdatabase.o
.obj/release/qguardedptr.o .obj/release/qiconset.o .obj/release/qimage.o
.obj/release/qkeysequence.o .obj/release/qlayout.o .obj/release/qlayoutengine.o
.obj/release/qtranslator.o .obj/release/qmetaobject.o .obj/release/qmime.o
.obj/release/qmovie.o .obj/release/qnetworkprotocol.o .obj/release/qobject.o
.obj/release/qobjectcleanuphandler.o .obj/release/qpainter.o .obj/release/qpalette.o
.obj/release/qpaintdevicemetrics.o .obj/release/qpicture.o .obj/release/qpixmap.o
.obj/release/qpixmapcache.o .obj/release/qpointarray.o .obj/release/qpoint.o
.obj/release/qpolygonscanner.o .obj/release/qprinter.o .obj/release/qprocess.o
.obj/release/qrect.o .obj/release/qregion.o .obj/release/qsignal.o .obj/release/qsignalmapper.o
.obj/release/qsize.o .obj/release/qsizegrip.o .obj/release/qstyle.o .obj/release/qsocketnotifier.o
.obj/release/qsound.o .obj/release/qstylesheet.o .obj/release/qtimer.o
.obj/release/qurl.o .obj/release/qlocalfs.o .obj/release/qurloperator.o
.obj/release/qurlinfo.o .obj/release/qwidget.o .obj/release/qwmatrix.o
.obj/release/qvariant.o .obj/release/qrichtext.o .obj/release/qinternal.o
.obj/release/qrichtext_p.o .obj/release/qsimplerichtext.o .obj/release/qbuttongroup.o
.obj/release/qbutton.o .obj/release/qcheckbox.o .obj/release/qcombobox.o
.obj/release/qwidgetresizehandler.o .obj/release/qdial.o .obj/release/qdockarea.o
.obj/release/qdockwindow.o .obj/release/qframe.o .obj/release/qgrid.o .obj/release/qgridview.o
.obj/release/qgroupbox.o .obj/release/qhbuttongroup.o .obj/release/qheader.o
.obj/release/qhgroupbox.o .obj/release/qhbox.o .obj/release/qlabel.o .obj/release/qlcdnumber.o
.obj/release/qlineedit.o .obj/release/qlistbox.o .obj/release/qlistview.o
.obj/release/qmainwindow.o .obj/release/qmenubar.o .obj/release/qmenudata.o
.obj/release/qmultilineedit.o .obj/release/qpopupmenu.o .obj/release/qprogressbar.o
.obj/release/qpushbutton.o .obj/release/qradiobutton.o .obj/release/qrangecontrol.o
.obj/release/qscrollbar.o .obj/release/qscrollview.o .obj/release/qslider.o
.obj/release/qspinbox.o .obj/release/qspinwidget.o .obj/release/qsplitter.o
.obj/release/qstatusbar.o .obj/release/qtabbar.o .obj/release/qtabwidget.o
.obj/release/qtitlebar.o .obj/release/qtoolbar.o .obj/release/qtoolbutton.o
.obj/release/qtooltip.o .obj/release/qvalidator.o .obj/release/qvbox.o
.obj/release/qvbuttongroup.o .obj/release/qvgroupbox.o .obj/release/qwhatsthis.o
.obj/release/qwidgetstack.o .obj/release/qaction.o .obj/release/qdatetimeedit.o
.obj/release/qeffects.o .obj/release/qtextview.o .obj/release/qtextbrowser.o
.obj/release/qtextedit.o .obj/release/qprintdialog.o .obj/release/qcolordialog.o
.obj/release/qdialog.o .obj/release/qerrormessage.o .obj/release/qfiledialog.o
.obj/release/qfontdialog.o .obj/release/qmessagebox.o .obj/release/qprogressdialog.o
.obj/release/qtabdialog.o .obj/release/qwizard.o .obj/release/qinputdialog.o
.obj/release/qiconview.o .obj/release/qworkspace.o .obj/release/qdns.o
.obj/release/qftp.o .obj/release/qhttp.o .obj/release/qhostaddress.o .obj/release/qnetwork.o
.obj/release/qserversocket.o .obj/release/qsocket.o .obj/release/qsocketdevice.o
.obj/release/qsocketdevice_unix.o .obj/release/qcanvas.o .obj/release/qtable.o
.obj/release/qxml.o .obj/release/qdom.o .obj/release/qsvgdevice.o .obj/release/qgl.o
.obj/release/qglcolormap.o .obj/release/qgl_x11.o .obj/release/qsqlquery.o
.obj/release/qsqldatabase.o .obj/release/qsqlfield.o .obj/release/qsqlrecord.o
.obj/release/qsqlform.o .obj/release/qsqlcursor.o .obj/release/qeditorfactory.o
.obj/release/qsqleditorfactory.o .obj/release/qsqldriver.o .obj/release/qsqlerror.o
.obj/release/qsqlresult.o .obj/release/qsqlindex.o .obj/release/qsqlpropertymap.o
.obj/release/qsqlmanager_p.o .obj/release/qdatatable.o .obj/release/qdataview.o
.obj/release/qdatabrowser.o .obj/release/qmngio.o .obj/release/qjpegio.o
.obj/release/qpngio.o .obj/release/png.o .obj/release/pngerror.o .obj/release/pngget.o
.obj/release/pngmem.o .obj/release/pngpread.o .obj/release/pngread.o .obj/release/pngrio.o
.obj/release/pngrtran.o .obj/release/pngrutil.o .obj/release/pngset.o .obj/release/pngtrans.o
.obj/release/pngwio.o .obj/release/pngwrite.o .obj/release/pngwtran.o .obj/release/pngwutil.o
.obj/release/adler32.o .obj/release/compress.o .obj/release/crc32.o .obj/release/deflate.o
.obj/release/gzio.o .obj/release/infblock.o .obj/release/infcodes.o .obj/release/inffast.o
.obj/release/inflate.o .obj/release/inftrees.o .obj/release/infutil.o .obj/release/trees.o
.obj/release/uncompr.o .obj/release/zutil.o .obj/release/qdir_unix.o .obj/release/qfile_unix.o
.obj/release/qfileinfo_unix.o .obj/release/qmutex_unix.o .obj/release/qsemaphore_unix.o
.obj/release/qsettings_unix.o .obj/release/qwaitcondition_unix.o .obj/release/qlibrary_unix.o
.obj/release/qbitarray.o .obj/release/qbuffer.o .obj/release/qcomponentfactory.o
.obj/release/qcstring.o .obj/release/qdatastream.o .obj/release/qdatetime.o
.obj/release/qdir.o .obj/release/qfile.o .obj/release/qfileinfo.o .obj/release/qgarray.o
.obj/release/qgcache.o .obj/release/qgdict.o .obj/release/qglist.o .obj/release/qglobal.o
.obj/release/qgpluginmanager.o .obj/release/qgvector.o .obj/release/qiodevice.o
.obj/release/qlibrary.o .obj/release/qmap.o .obj/release/qptrcollection.o
.obj/release/qregexp.o .obj/release/qstring.o .obj/release/qsettings.o
.obj/release/qstringlist.o .obj/release/qtextstream.o .obj/release/qucom.o
.obj/release/quuid.o .obj/release/qbig5codec.o .obj/release/qeucjpcodec.o
.obj/release/qeuckrcodec.o .obj/release/qgbkcodec.o .obj/release/qjiscodec.o
.obj/release/qjpunicode.o .obj/release/qrtlcodec.o .obj/release/qsjiscodec.o
.obj/release/qtextcodec.o .obj/release/qtsciicodec.o .obj/release/qutfcodec.o
.obj/release/qtextcodecfactory.o .obj/release/qfontarcodec.o .obj/release/qfontcncodec.o
.obj/release/qfontjpcodec.o .obj/release/qfontkrcodec.o .obj/release/qfonttwcodec.o
.obj/release/qstylefactory.o .obj/release/qcommonstyle.o .obj/release/qcdestyle.o
.obj/release/qmotifplusstyle.o .obj/release/qplatinumstyle.o .obj/release/qsgistyle.o
.obj/release/qwindowsstyle.o .obj/release/qmotifstyle.o .obj/release/moc_qaccel.o
.obj/release/moc_qapplication.o .obj/release/moc_qasyncio.o .obj/release/moc_qclipboard.o
.obj/release/moc_qdesktopwidget.o .obj/release/moc_qdragobject.o .obj/release/moc_qguardedptr.o
.obj/release/moc_qlayout.o .obj/release/moc_qtranslator.o .obj/release/moc_qnetworkprotocol.o
.obj/release/moc_qobject.o .obj/release/moc_qobjectcleanuphandler.o .obj/release/moc_qprocess.o
.obj/release/moc_qsessionmanager.o .obj/release/moc_qsignal.o .obj/release/moc_qsignalmapper.o
.obj/release/moc_qsizegrip.o .obj/release/moc_qsocketnotifier.o .obj/release/moc_qsound.o
.obj/release/moc_qstyle.o .obj/release/moc_qstylesheet.o .obj/release/moc_qtimer.o
.obj/release/moc_qlocalfs.o .obj/release/moc_qurloperator.o .obj/release/moc_qwidget.o
.obj/release/moc_qrichtext_p.o .obj/release/moc_qbuttongroup.o .obj/release/moc_qbutton.o
.obj/release/moc_qcheckbox.o .obj/release/moc_qcombobox.o .obj/release/moc_qwidgetresizehandler_p.o
.obj/release/moc_qdial.o .obj/release/moc_qdockarea.o .obj/release/moc_qdockwindow.o
.obj/release/moc_qframe.o .obj/release/moc_qgrid.o .obj/release/moc_qgridview.o
.obj/release/moc_qgroupbox.o .obj/release/moc_qhbuttongroup.o .obj/release/moc_qheader.o
.obj/release/moc_qhgroupbox.o .obj/release/moc_qhbox.o .obj/release/moc_qlabel.o
.obj/release/moc_qlcdnumber.o .obj/release/moc_qlineedit.o .obj/release/moc_qlistbox.o
.obj/release/moc_qlistview.o .obj/release/moc_qmainwindow.o .obj/release/moc_qmenubar.o
.obj/release/moc_qmultilineedit.o .obj/release/moc_qpopupmenu.o .obj/release/moc_qprogressbar.o
.obj/release/moc_qpushbutton.o .obj/release/moc_qradiobutton.o .obj/release/moc_qrangecontrol.o
.obj/release/moc_qscrollbar.o .obj/release/moc_qscrollview.o .obj/release/moc_qslider.o
.obj/release/moc_qspinbox.o .obj/release/moc_qsplitter.o .obj/release/moc_qstatusbar.o
.obj/release/moc_qtabbar.o .obj/release/moc_qtabwidget.o .obj/release/moc_qtitlebar_p.o
.obj/release/moc_qtoolbar.o .obj/release/moc_qtoolbutton.o .obj/release/moc_qtooltip.o
.obj/release/moc_qvalidator.o .obj/release/moc_qvbox.o .obj/release/moc_qvbuttongroup.o
.obj/release/moc_qvgroupbox.o .obj/release/moc_qwidgetstack.o .obj/release/moc_qaction.o
.obj/release/moc_qdatetimeedit.o .obj/release/moc_qtextview.o .obj/release/moc_qtextbrowser.o
.obj/release/moc_qtextedit.o .obj/release/moc_qcolordialog.o .obj/release/moc_qdialog.o
.obj/release/moc_qerrormessage.o .obj/release/moc_qfiledialog.o .obj/release/moc_qfontdialog.o
.obj/release/moc_qmessagebox.o .obj/release/moc_qprogressdialog.o .obj/release/moc_qsemimodal.o
.obj/release/moc_qtabdialog.o .obj/release/moc_qwizard.o .obj/release/moc_qinputdialog.o
.obj/release/moc_qprintdialog.o .obj/release/moc_qiconview.o .obj/release/moc_qworkspace.o
.obj/release/moc_qdns.o .obj/release/moc_qftp.o .obj/release/moc_qhttp.o
.obj/release/moc_qserversocket.o .obj/release/moc_qsocket.o .obj/release/moc_qcanvas.o
.obj/release/moc_qtable.o .obj/release/moc_qgl.o .obj/release/moc_qsqlquery.o
.obj/release/moc_qsqldatabase.o .obj/release/moc_qsqlform.o .obj/release/moc_qsqldriver.o
.obj/release/moc_qdatatable.o .obj/release/moc_qdataview.o .obj/release/moc_qdatabrowser.o
.obj/release/moc_qgpluginmanager.o .obj/release/moc_qlibrary_p.o .obj/release/moc_qcommonstyle.o
.obj/release/moc_qcdestyle.o .obj/release/moc_qmotifplusstyle.o .obj/release/moc_qplatinumstyle.o
.obj/release/moc_qsgistyle.o .obj/release/moc_qwindowsstyle.o .obj/release/moc_qmotifstyle.o
-L/usr/X11R6/lib -L/usr/X11R6/lib -ljpeg -lGL -lXmu -lICE -lSM -ldl -lXext
-lX11 -lm -lXinerama -lXrender -lXft -lfreetype
ln -s libqt.so.3.0.0 libqt.so
ln -s libqt.so.3.0.0 libqt.so.3
ln -s libqt.so.3.0.0 libqt.so.3.0
To complete this section we will speak about ldconfig.
ldconfig is a program that creates a file called "/etc/ld.so.cache" where all the shared libraries will be present.
Check this example:
We check the date of the file
[root@ftosx1 root]# ls -al /etc/ld.so.cache
-rw-r--r-- 1 root
root 110041 Sep 21 20:03 /etc/ld.so.cache
[root@ftosx1 root]# date
Mon Sep 24 16:02:00 CEST 2001
and then run ldconfig to update it
[root@ftosx1 root]# ldconfig
[root@ftosx1 root]# ls -al /etc/ld.so.cache
-rw-r--r-- 1 root
root 110041 Sep 24 16:02 /etc/ld.so.cache
[root@ftosx1 root]#
and we get a new file including the actual shared libs.
Is clear that this file does not belong to any rpm package
[root@ftosx1 Chap2]# rpm -qf /etc/ld.so.cache
file /etc/ld.so.cache is not owned by any package
[root@ftosx1 Chap2]#
Is clear that this file is created in the post-installation after the package transfer.
In this section we will present very simple examples about the elementary C. Most of this represent example of Number Theory that may be written using the C operator '%' .
The factor.c program, which binary is "factor", includes the following C code:
static int
factor (uintmax_t n0, int max_n_factors, uintmax_t *factors)
{
register uintmax_t n = n0, d, q;
int n_factors = 0;
if (n < 1)
return n_factors;
while (n % 2 == 0)
{
assert (n_factors < max_n_factors);
factors[n_factors++] = 2;
n /= 2;
}
/* The exit condition in the following loop is correct
because
any time it is tested one of these
3 conditions holds:
(1) d divides n
(2) n is prime
(3) n is composite but has no
factors less than d.
If (1) or (2) obviously the right thing
happens.
If (3), then since n is composite it
is >= d^2. */
d = 3;
do
{
q = n /
d;
while (n
== q * d)
{
assert (n_factors < max_n_factors);
factors[n_factors++] = d;
n = q;
q = n / d;
}
d += 2;
}
while (d <= q);
if (n != 1 || n0 == 1)
{
assert (n_factors < max_n_factors);
factors[n_factors++] = n;
}
return n_factors;
}
The core of the previous function is do-while cycle in blue color. This cycle decompose the number, n, in its factor and apply the same cycle to the new number without the saved factor.
This is the classical approach. Differents optimization are available, like for example to stop the cycle up to the sqrt(number) (Gauss) or moves the divisors in a array that contains the first primes up to 37 in a cylic mode. The last algorithm is present in Hewlett-Packard - HP-67/HP-97 - Math Pac I, 1976.
Here, we will use this algorithm to introduce perfect numbers.
A perfect number, in Number Theory is a number which is equal to the sum of its proper divisors.
For example,
6 = 1 * 2 * 3 and 6 = 1 + 2 + 3, its the sum of its proper divisors.
A divisor is proper if is different of the number. So, we don't count 6.
Other examples are: 28 = 1 * 2 * 4 * 7 * 14 = 1 + 2 + 4 + 7 + 14.
Is well-know that all even perfect numbers may be represented by the Euclids formula:
N = (2n-1) (2n - 1),
where (2n - 1) is a prime. The primes are called Mersenne primes.
We will modify the factor.c to print if the input number is perfect or not.
Actually, our factor prints its factors as follows:
[root@ftosx1 src]# ./factor 6
6: 2 3
The original program is called factor.c.original, while the modified version is called factor.c.
Looking inside the code we see that the factors are printed by the function:
static int
print_factors (const char *s)
{
uintmax_t factors[MAX_N_FACTORS];
uintmax_t n;
int n_factors;
int i;
int perfect = 1;
char buf[LONGEST_HUMAN_READABLE + 1];
if (xstrtoumax (s, NULL, 10, &n, "") != LONGINT_OK)
{
error (0, 0, _("`%s' is not a
valid positive integer"), s);
return 1;
}
If we had the lines in color we will get inmmediately the solution.
[root@fosx1 src]# ./factor 6
6: 2 3
6
is perfect
[root@ftosx1 src]#
However these files are not sufficient. Because for the perfect number 28, we have a bad result.
[root@ftosx1 src]# ./factor 28
28: 2 2 7
Therefore we need to modify the algorithm to print divisor instead of factors.
2 is a factor of 28, but its divisor are: 2, 4, 7, 14.
However, the algorithm is simple to work on old code. We write here a simple version, that works fine!
[root@ftosx1 src]# more myfactor.c
#include <math.h>
main()
{
int n=8128, i, perfect, sumd=1;
for (i=2; i < n; i++) {
if (n % i == 0) {
sumd += i;
printf ("%d\n", i);
}
}
if (sumd == n)
printf ("%d is perfect\n", n );
}
[root@ftosx1 src]#
The numbers in the previous example must be written inside the source!
The latest Mersenne Prime and the last Perfect number are available for example on the URL: http://www.utm.edu/research/primes/lists/top20/Largest.html or http://www.mersenne.org/status.htm. Mathematical proofs may be found at http://www.utm.edu/research/primes/notes/proofs/
Check also: http://www.eff.org/awards/award-news.html
Factoring numbers are important in E-commerce Security
Another interesing theme is Gematria. The Gematria is the antique Hebrew Numerology that assign a number to names.
Exactly,

You can check the previous source at http://www.inner.org/gematria/gematria.htm
Because this example is for fun we will base here on an updated document
available on the Web: EXAMPLE
GEMATRIA ENGLISH ALPHABETS
A=6 B=12 C=18 D=24 E=30 F=36 G=42 H=48 I=54
J=60 K=66 L=72 M=78 N=84 O=90 P=96 Q=102 R=108
S=114 T=120 U=126 V=132 W =138 X=144 Y=150 Z=156
For example, my name: Giovanni Alberto Orlando will be the number: Giovanni will be (42+54+90+132+6+84+84+54=546), Alberto (6+72+12+30+108+120+90=438), Orlando (90+108+72+6+84+24+90=474).
Total is: 1458
Giovanni A. Orlando is: 546+6+474=1026
Bill Gates number will be: Bill (12+54+72+72), Gates (42+6+120+30+114) = 522
Formal Bill Gates name is: William Henry Gates III
Osama bin Laden: Osama (90+114+6+78+6=294), bin (12+54+84=150), Laden (72+6+24+30+84=216)
Total is: 660
Is also possible to found Ladin, instead of Laden, and we will get a new number.
Now, we will write a program in C about this.
We start to fix the source flow and test it the variables present in the program. Generally this is the mode to work: Design, Write the program in different stages with testing and final release.
This is a first stage.
Here we create a function "gematria" where will make the calculus to the string received and in the main we send each string to the function.
main(int argc, char ** argv[])
{
int myuntil;
puts ("Enter the name(s) to get the equivalent gematria numbers:\n" );
myuntil = 1;
do {
gematria(argv[myuntil++]);
} while (myuntil
<= argc--);
}
int gematria (char * s)
{
int a[27], i;
// English codes Gematria
codes ... just for fun!
// A=6 B=12
C=18 D=24 E=30 F=36 G=42 H=48 I=54
// J=60 K=66 L=72
M=78 N=84 O=90 P=96 Q=102 R=108
// S=114 T=120 U=126
V=132 W =138 X=144 Y=150 Z=156
a[0] = 6; //A
a[1] = 12; //B
a[2] = 18; //C
a[3] = 24; //D
a[4] = 30; //E
a[5] = 36; //F
a[6] = 42; //G
a[7] = 48; //H
a[8] = 54; //I
a[9] = 60; //J
a[10] = 66; //K
a[11] = 72; //K
a[12] = 78; //K
a[13] = 84; //K
a[14] = 90; //K
a[15] = 96; //K
a[16] = 102; //K
a[17] = 108; //R
a[18] = 114; //S
a[19] = 120; //T
a[20] = 126; //U
a[21] = 132; //V
a[22] = 138; //W
a[23] = 144; //X
a[24] = 150; //Z
a[25] = 156; //Z
for (i = 0; i <=
strlen (s); i++) {
printf ("%c\n", s[i]);
}
}
Now, we compile and test it.
[root@ftosx1 Chap2]# make gematria
cc gematria.c -o gematria
[root@ftosx1 Chap2]# ./gematria Giovanni
Enter the name(s) to get the equivalent gematria numbers:
G
i
o
v
a
n
n
i
[root@ftosx1 Chap2]#
Now, we will update the function gematria adding another array including each letter.
The idea is to find the right index in the array a, that includes the gematria numbers, scanning each letter received.
If for example
s[i] = b[j]
Then, j will represent the right index in the array a, that will get the right gematria number for the letter.
Cycling on each word, we will get the gematria number for the word, and then for each word!
These ideas are the ideas that you need to have to be a programmer, in this case a C programmer.
Now, we will test a stage2
int gematria (char * s)
{
int a[27], i;
static
char b [] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', \
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', \
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
// English codes Gematria
codes ... just for fun!
// A=6 B=12
C=18 D=24 E=30 F=36 G=42 H=48 I=54
// J=60 K=66 L=72
M=78 N=84 O=90 P=96 Q=102 R=108
// S=114 T=120 U=126
V=132 W =138 X=144 Y=150 Z=156
a[0] = 6; //A
a[1] = 12; //B
a[2] = 18; //C
a[3] = 24; //D
a[4] = 30; //E
a[5] = 36; //F
a[6] = 42; //G
a[7] = 48; //H
a[8] = 54; //I
a[9] = 60; //J
a[10] = 66; //K
a[11] = 72; //K
a[12] = 78; //K
a[13] = 84; //K
a[14] = 90; //K
a[15] = 96; //K
a[16] = 102; //K
a[17] = 108; //R
a[18] = 114; //S
a[19] = 120; //T
a[20] = 126; //U
a[21] = 132; //V
a[22] = 138; //W
a[23] = 144; //X
a[24] = 150; //Z
a[25] = 156; //Z
for (i = 0; i <=
strlen (s); i++) {
//for (j = 0; j <= 25; j++) {
// Now we will recognize the letter inside the string testing each letter
in array b.
//if ( s[i] ==
printf ("%c %c\n", s[i],
b[i]);
//}
}
}
We show the changes in green.
[root@ftosx1 Chap2]# ./gematria Giovanni
Enter the name(s) to get the equivalent gematria numbers:
G A
i B
o C
v D
a E
n F
n G
i H
I
[root@ftosx1 Chap2]#
Now, we need to add only the condition to match the right letter.
Now, we add the explained condition. We transform the input letter to UPPERCASE. This is necessary get results to test.
int a[27], i, j, mygematria = 0;
for
(i = 0; i <= strlen (s); i++) {
for
(j = 0; j <= 25; j++) {
// Now we will recognize the letter inside the string testing each letter
in array b.
// We need to transform the input char sequence to upper case, for a sucessfull
test
if ( toupper(s[i]) == b[j] ) {
mygematria += a[j];
printf ("%c\n", s[i]);
}
}
}
printf ("gematria
%d\n", mygematria);
[root@ftosx1 Chap2]# ./gematria Giovanni
Enter the name(s) to get the equivalent gematria numbers:
G
i
o
v
a
n
n
i
gematria 546
[root@ftosx1 Chap2]# ./gematria Giovanni Alberto Orlando
Enter the name(s) to get the equivalent gematria numbers:
G
i
o
v
a
n
n
i
gematria 546
A
l
b
e
r
t
o
gematria 438
O
r
l
a
n
d
o
gematria 474
[root@ftosx1 Chap2]#
Now, we are ready for a final release!
main(int argc, char ** argv[])
{
int myuntil, totalgematria=0;
puts ("Enter the name(s) to get the equivalent gematria numbers:\n" );
myuntil = 1;
do {
totalgematria += gematria(argv[myuntil++]);
} while (myuntil
<= argc--);
printf ("The number of the name is: %d\n", totalgematria);
}
int gematria (char * s)
{
int a[27], i, j, mygematria = 0;
static char b [] =
{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', \
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', \
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
// English codes Gematria
codes ... just for fun!
// A=6 B=12 C=18 D=24 E=30 F=36 G=42
H=48 I=54
// J=60 K=66 L=72 M=78 N=84 O=90 P=96 Q=102
R=108
// S=114 T=120 U=126 V=132 W =138 X=144 Y=150
Z=156
a[0] = 6; //A
a[1] = 12; //B
a[2] = 18; //C
a[3] = 24; //D
a[4] = 30; //E
a[5] = 36; //F
a[6] = 42; //G
a[7] = 48; //H
a[8] = 54; //I
a[9] = 60; //J
a[10] = 66; //K
a[11] = 72; //K
a[12] = 78; //K
a[13] = 84; //K
a[14] = 90; //K
a[15] = 96; //K
a[16] = 102; //K
a[17] = 108; //R
a[18] = 114; //S
a[19] = 120; //T
a[20] = 126; //U
a[21] = 132; //V
a[22] = 138; //W
a[23] = 144; //X
a[24] = 150; //Z
a[25] = 156; //Z
for (i = 0; i <=
strlen (s); i++) {
for (j = 0; j <= 25; j++) {
// Now we will recognize the letter inside the string testing each letter
in array b.
// We need to transform the input char sequence to upper case, for a sucessfull
test
if ( toupper(s[i]) == b[j] ) {
mygematria += a[j];
}
}
}
return mygematria;
}
[root@ftosx1 Chap2]#
... and a real test!
[root@ftosx1 Chap2]# ./gematria Giovanni Alberto Orlando
Enter the name(s) to get the equivalent gematria numbers:
The number of the name is: 1458
[root@ftosx1 Chap2]# ./gematria Giovanni Alberto Orlando
Enter the name(s) to get the equivalent gematria numbers:
The number of the name is: 1458
[root@ftosx1 Chap2]# ./gematria Dr Giovanni A Orlando
Enter the name(s) to get the equivalent gematria numbers:
The number of the name is: 684
[root@ftosx1 Chap2]# ./gematria Osama Abin Laden
Enter the name(s) to get the equivalent gematria numbers:
The number of the name is: 666
[root@ftosx1 Chap2]# ./gematria William Henry Gates III
Enter the name(s) to get the equivalent gematria numbers:
The number of the name is: 1206
[root@ftosx1 Chap2]#
Some other people uses the ASCII code creating very comic results.
Generally everyone knows the quadratic solution for: a x^2 + b x + c
=0. The cubic equation may be solved solving some quadratic and the quartic
may be reduced to two quadratic equations. The quintic is impossible to
be solved using radical . Niels H. Abel give a proof about this fact in
1826.
Therefore any equation of higher than the fouth degree are in general
not capable to be solved using algebraic solutions.
Check the Interactive Exam Cram Programming:
Internet Resources for this Chapter.