Operators

C like a 'beautiful' language includes its operators.

These operators may be classified as follows:

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

Expressions

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.

Functions

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.

How to build a static library

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!

How to build a shared library

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.

Examples in C

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;
    }

  n_factors = factor (n, MAX_N_FACTORS, factors);1
  printf ("%s:", human_readable (n, buf, 1, 1));
  for (i = 0; i < n_factors; i++) {
    printf (" %s", human_readable (factors[i], buf, 1, 1));
    perfect += factors[i];
  }
  if (n == perfect)
        printf ("\n%d\n is perfect", n );
  putchar ('\n');
  return 0;
}

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.
 

Exercises

  1. Install the sh-utils source and try to understand the program factor.c
  2. Modify the factor.c program to print factors without to use an array.
  3. Write a program that creates a Segmentation Fault
  4. Write a C expression without the parenthesis on the left: ')', and try to compile.
  5. Write a C expression without the parenthesis that closes the function: '}', and try to compile.
  6. Write a C expression without the semicolon: ';' , and try to compile.
  7. Write an example using the ? : operator.
  8. Develop the following algorithms in C:


Test

  1. What is a pointer ?.
  2. Is possible to have a pointer to an integer variable: 'int * p"?
  3. Is possible to define in C data type called 'address' including company name, address and other similar data ?
  4. What returns the sizeof () ?
  5. The int data type is a long or a short ?
  6. When happens a Segmentation fault (SEGV)?
  7. What is a core file ?
  8. When is created a core file?
  9. When happens a Bus error ?
  10. What is the command to build a library ?
  11. What is the command to list the objects inside an object.
  12. What is a shared library ?
  13. What users can use the shared library ?
  14. What is the command to run after the shared library compilation ?
  15. What file resume the shared libraries present in the system?
  16. What command create this file ?
  17. Describe unsigned int and signed int variables ? What is the difference ?
  18. Describe unsigned char ?
  19. Is possible to alloc an entire structure ?
  20. Is possible copy or duplicate an entire structure ?
  21. Is possible to print a entire structure with a single command ?
  22. How you can print a "30% of 12 is 3.6", using printf ?
  23. Are there some GNU High Precision Mathematical library?
Consult the answers

Check the Interactive Exam Cram Programming: Try the interactive cram ...

Internet Resources for this Chapter.